Compare commits

...

22 Commits

Author SHA1 Message Date
heck 16e9bda15f sphinx doc - config and module doc pEp._gen / pEp._pEp 4 years ago
heck 348fa8f2f9 make clean 4 years ago
heck 8e1898446e gitignore 4 years ago
heck da1d3a8347 codegen - add enigne functions from message.h 4 years ago
heck 103208ea95 add pybind11 to setup-requires 4 years ago
heck 7a84853814 build - get pybind includes from pybind module 4 years ago
heck d87fd19652 gitignore generated debug files 4 years ago
heck 784653df6f Half the adapter generated, strike \o/! 4 years ago
heck 6a1d302821 _gen fix Makefiles 5 years ago
heck dc0b769136 _gen Add PEP_SESSION 5 years ago
heck 119effbfdb gen log_event 5 years ago
heck 7b4ba8b4c4 Makefile 5 years ago
heck b153ce3c7a Makefile - fix static vs dynamic linking options 5 years ago
heck 2e138e1190 introduce pEpACIDgen - Abstract C Interface Definition Generator 5 years ago
heck 0792869686 suitable name for the generated extension module 5 years ago
heck c56b3b40f3 Makefile based build for C++ parts only 5 years ago
heck 19b2ebb18d Move common includes, namespace aliases etc... to adapter_main.hh/.cc, 5 years ago
heck 0e896bf36c namespace cleanup - replace all "using namespace" with namspace aliases (except std in impl files.) 5 years ago
heck 0e893624c9 formatting fornatting - breakfast and lunch - dinner and brunch :) 5 years ago
heck 63e830040c Mark all symbols from the pEpEngine with explicit global namespace. (e.g: ::pEp_stuff). 5 years ago
heck 688fff5667 Add Makefile based build for _pEp native module 5 years ago
heck 8aa36d9f95 pyBind11 evaluation - parallel mode with boost.python 5 years ago
  1. 11
      .gitignore
  2. 26
      Makefile
  3. 1
      Makefile.conf
  4. 8
      docs/source/api/pEp._gen.rst
  5. 7
      docs/source/api/pEp._pEp.rst
  6. 9
      docs/source/api/pEp.rst
  7. 2
      docs/source/conf.py
  8. 3
      docs/source/index.rst
  9. 3
      pyproject.toml
  10. 2
      requirements.txt
  11. 2
      setup.cfg
  12. 20
      setup.py
  13. 16
      src/pEp/Makefile.conf
  14. 2
      src/pEp/__init__.py
  15. 46
      src/pEp/_gen/Makefile
  16. 12
      src/pEp/_gen/Makefile.conf
  17. 40
      src/pEp/_gen/adapter_main.hh
  18. 35
      src/pEp/_gen/gen/Makefile
  19. 98
      src/pEp/_gen/gen/config.json
  20. 22
      src/pEp/_gen/pEpModule.cc
  21. 32
      src/pEp/_pEp/Makefile
  22. 163
      src/pEp/_pEp/adapter_main.cc
  23. 84
      src/pEp/_pEp/adapter_main.hh
  24. 177
      src/pEp/_pEp/basic_api.cc
  25. 29
      src/pEp/_pEp/basic_api.hh
  26. 231
      src/pEp/_pEp/identity.cc
  27. 60
      src/pEp/_pEp/identity.hh
  28. 320
      src/pEp/_pEp/message.cc
  29. 101
      src/pEp/_pEp/message.hh
  30. 165
      src/pEp/_pEp/message_api.cc
  31. 22
      src/pEp/_pEp/message_api.hh
  32. 360
      src/pEp/_pEp/pEpmodule.cc
  33. 24
      src/pEp/_pEp/pEpmodule.hh
  34. 138
      src/pEp/_pEp/str_attr.cc
  35. 40
      src/pEp/_pEp/str_attr.hh
  36. 100
      src/pEp/_pEp/user_interface.cc
  37. 42
      src/pEp/_pEp/user_interface.hh

11
.gitignore

@ -47,4 +47,13 @@ __pycache__/
.DS_store
# pEpACIDgen generated files
/src/pEp/_gen/gen/adapter_main.hh.acid.json
/src/pEp/_gen/gen/adapter_main.hh.acid.yml
/src/pEp/_gen/gen/adapter_main.hh.ast.json
/src/pEp/_gen/gen/py_module.pybind11
/src/pEp/_gen/gen/py_module.yml2
/src/pEp/_gen.cpython-38-darwin.so
/src/pEp/_pEp.cpython-38-darwin.so
/src/pEp/_gen/pEpModule.o
/src/pEp/_gen/_gen.so

26
Makefile

@ -3,12 +3,20 @@ include Makefile.conf
.PHONY: all compile compile-inplace dist dist-egg dist-whl install install-user venv envtest install-test test develop docs clean clean-all clean-docs
all: dist
# Install pEpACIDgen from local repo clone, not from pypi
install-pepacidgen:
pip3 install -r requirements.txt --find-links ../pEpACIDgen/dist
# Build
# =====
compile:
gen: install-pepacidgen
$(MAKE) -C src/pEp/_gen gen
compile: gen
python3 setup.py build_ext $(DEBUG_OPT) $(PREFIX_OPT)
compile-inplace:
compile-inplace: gen
python3 setup.py build_ext $(DEBUG_OPT) $(PREFIX_OPT) --inplace
# Packaging
@ -57,8 +65,6 @@ envtest:
install-test: compile
pip3 install .[test]
# TODO: maybe use setup.py test?
# --forked, because every test needs a separate process, see PYADPT-100
test:
pytest
@ -80,6 +86,7 @@ clean-all: clean
rm -rf $(VENV_DIR)
clean: clean-docs
$(MAKE) -C src/pEp/_gen clean-all
rm -rf $(BUILD_DIR)
rm -rf $(DIST_DIR)
rm -rf $(PYTHON_ARTIFACTS)
@ -88,3 +95,14 @@ clean: clean-docs
clean-docs:
make clean -C docs/
# Makefile based build of C++ parts only
# ======================================
makefile-build:
$(MAKE) -C src/pEp/_pEp
$(MAKE) -C src/pEp/_gen
makefile-clean:
$(MAKE) -C src/pEp/_pEp clean
$(MAKE) -C src/pEp/_gen clean

1
Makefile.conf

@ -5,6 +5,7 @@ BUILD_DIR = ./build
DIST_DIR = ./dist
VERSION_FILE = ./src/pEp/__version__.py
BUILD_INPLACE = ./src/pEp/_pEp.cpython-38-darwin.so
BUILD_INPLACE += ./src/pEp/_gen.cpython-38-darwin.so
PYTHON_ARTIFACTS += ./.eggs
PYTHON_ARTIFACTS += ./src/pEp.egg-info
PYTHON_ARTIFACTS += ./.pytest_cache

8
docs/source/api/pEp._gen.rst

@ -0,0 +1,8 @@
Module pEp._gen
---------------
.. automodule:: pEp._gen
:members:
:imported-members:
:undoc-members:
:show-inheritance:

7
docs/source/api/pEp._pEp.rst

@ -0,0 +1,7 @@
Module pEp._pEp
---------------
.. automodule:: pEp._pEp
:members:
:imported-members:
:undoc-members:
:show-inheritance:

9
docs/source/api/pEp.rst

@ -1,12 +1,7 @@
pEp package
===========
Module contents
---------------
Module pEp
----------
.. automodule:: pEp
:members:
:imported-members:
:undoc-members:
:show-inheritance:

2
docs/source/conf.py

@ -92,7 +92,7 @@ html_theme = "nature"
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]
#html_static_path = ["_static"]
# Custom sidebar templates, must be a dictionary that maps document names
# to template names.

3
docs/source/index.rst

@ -13,6 +13,9 @@ Welcome to pEpPythonAdapter's documentation!
install
software_using
api/pEp
api/pEp._pEp
api/pEp._gen
Indices and tables
==================

3
pyproject.toml

@ -5,7 +5,8 @@
requires =[
"setuptools >=39.2.0",
"setuptools_scm >= 4.1.2",
"wheel >= 0.35.1" ]
"wheel >= 0.35.1",
"pybind11 >= 2.6.2" ]
build-backend = "setuptools.build_meta"

2
requirements.txt

@ -0,0 +1,2 @@
pEpACIDgen
pyBind11

2
setup.cfg

@ -35,6 +35,8 @@ setup_requires =
setuptools >=39.2.0
setuptools_scm >= 4.1.2
wheel >= 0.35.1
pybind11 >= 2.6.2
[options.extras_require]
# To install these dependencies, run pip install .[test]
test =

20
setup.py

@ -7,7 +7,6 @@
from __future__ import print_function
import sys
import os
from os import environ
from os.path import join
@ -174,6 +173,14 @@ class BuildExtCommand(build_ext):
module_pEp.libraries = libs
module_pEp.extra_compile_args = compile_flags
global module_gen
module_gen.include_dirs = includes
import pybind11
module_gen.include_dirs += [pybind11.commands.get_include()]
module_gen.library_dirs = libdirs
# module_gen.libraries = libs
module_gen.extra_compile_args = compile_flags
pEpLog("Include Dirs:", module_pEp.include_dirs)
pEpLog("Libs Dirs:", module_pEp.library_dirs)
pEpLog("Libraries:", module_pEp.libraries)
@ -195,6 +202,7 @@ if sys.version_info[0] < 3:
module_pEp = Extension(
'pEp._pEp',
sources=[
'src/pEp/_pEp/adapter_main.cc',
'src/pEp/_pEp/pEpmodule.cc',
'src/pEp/_pEp/basic_api.cc',
'src/pEp/_pEp/identity.cc',
@ -205,11 +213,19 @@ module_pEp = Extension(
],
)
module_gen = Extension(
'pEp._gen',
sources=[
'src/pEp/_gen/pEpmodule.cc',
],
)
# "MAIN" Function
setup(
package_dir={'': 'src'},
packages=['pEp'],
ext_modules=[module_pEp],
ext_modules=[module_pEp, module_gen],
cmdclass={
'build_ext': BuildExtCommand,
},

16
src/pEp/Makefile.conf

@ -0,0 +1,16 @@
HERE:=$(dir $(lastword $(MAKEFILE_LIST)))
-include $(HERE)../../local.conf
TARGET_PEP=_pEp.so
TARGET_GEN=_gen.so
# General Build settings
CXX=g++
CXXFLAGS+=-std=c++11 -g
INCLUDES+=-I$(PREFIX)/include
INCLUDES+=-I/opt/local/Library/Frameworks/Python.framework/Versions/3.8/include/python3.8
LIB_DIRS=-L$(PREFIX)/lib
LIB_DIRS+=-L/opt/local/lib
LIBS=-lpEpEngine -lpEpAdapter
LDFLAGS+=-undefined dynamic_lookup

2
src/pEp/__init__.py

@ -25,10 +25,12 @@ except ImportError:
# Imports all symbols EXCEPT the ones beginning with underscore
from ._pEp import *
from ._gen import *
# import the native module into the current namespace because we also need to access the names beginning
# with an underscore (of _pEp), but we dont want to import them into this module
import pEp._pEp
import pEp._gen
# Executed on module import
def init():

46
src/pEp/_gen/Makefile

@ -0,0 +1,46 @@
include Makefile.conf
TARGET=_gen.so
# Swap here, for static vs dyn linking
TARGET_MODULE_DYN=$(TARGET)
TARGET_MODULE_STATIC=
CXX=clang
CXXFLAGS+=-std=c++11 -g
SRCS+=$(wildcard *.cc)
OBJS+=$(SRCS:.cc=.o)
CXXFLAGS+=$(INCLUDES)
LDFLAGS_DYN+=-undefined dynamic_lookup $(LIBS_PATH) $(LIBS)
LDFLAGS_STATIC+=-undefined dynamic_lookup
$(info -----BUILD INFO----)
$(info SRCS $(SRCS))
$(info OBJS $(OBJS))
.PHONY: all gen gen-pybind module_dyn module_static clean
all: gen compile
gen:
$(MAKE) -C gen
gen-pybind:
$(MAKE) -C gen pybind
compile: $(TARGET)
$(TARGET_MODULE_DYN) : $(OBJS)
$(CXX) $(LDFLAGS_DYN) -o $@ $^
$(TARGET_MODULE_STATIC) : $(OBJS) $(LIBS_STATIC)
$(CXX) $(LDFLAGS_STATIC) -o $@ $^
clean:
rm -f $(TARGET)
rm -f $(OBJS)
clean-all: clean
$(MAKE) -C gen clean

12
src/pEp/_gen/Makefile.conf

@ -0,0 +1,12 @@
# pyBind11 and python headers
INCLUDES+=$(shell pybind11-config --includes)
# example lib
INCLUDES+=-I/Users/heck/local-default/include/
# static lib (.a)
#LIBS_STATIC+=/Users/heck/local-default/include/
# dynamic lib (.so)
LIBS+=-lpEpEngine
LIBS_PATH+=-L/Users/heck/local-default/lib

40
src/pEp/_gen/adapter_main.hh

@ -0,0 +1,40 @@
// This file is under GNU Affero General Public License 3.0
// see LICENSE.txt
#ifndef ADAPTER_MAIN_HH
#define ADAPTER_MAIN_HH
// Use only if cant be avoided
//#include <pEp/stringlist.h>
/// =======
#include <pEp/pEpEngine.h>
//// Engine
////pEp-API
#include <pEp/keymanagement.h>
#include <pEp/message_api.h>
#include <pEp/sync_api.h>
#include <pEp/distribution_codec.h>
#include <pEp/sync_codec.h>
/// =======
// #include <pEp/identity_list.h>
// #include <pEp/key_reset.h>
// #include <pEp/mime.h>
// #include <pEp/message.h>
// #include <pEp/sync_codec.h>
// #include <pEp/distribution_codec.h>
// #include <pEp/timestamp.h>
// #include <pEp/stringpair.h>
// libpEpAdapter
/// =======
//#include <pEp/Adapter.hh>
//#include <pEp/callback_dispatcher.hh>
/// =======
// #include <pEp/status_to_string.hh>
// #include <pEp/pEpLog.hh>
#endif // ADAPTER_MAIN_HH

35
src/pEp/_gen/gen/Makefile

@ -0,0 +1,35 @@
include ../Makefile.conf
YML2_FILE=py_module.yml2
YSL2_FILE=$(shell pEp_acid_gen-config)
PYBIND11_FILE=py_module.pybind11
DEBUG_AST_FILE=adapter_main.hh.ast.json
DEBUG_ACID_FILE=adapter_main.hh.acid.json
DEBUG_YML_FILE=adapter_main.hh.acid.yml
$(info -----_gen GEN----)
$(info YML2_FILE $(YML2_FILE))
$(info YSL2_FILE $(YSL2_FILE))
$(info CC_FILE $(PYBIND11_FILE))
.PHONY = all yml pybind
all: pybind
yml: $(YML2_FILE)
pybind: $(YML2_FILE) $(PYBIND11_FILE)
$(YML2_FILE): config.json
pEp_acid_gen $^
$(PYBIND11_FILE) : $(YML2_FILE)
yml2proc --encoding=utf8 -y $(YSL2_FILE) $(YML2_FILE)
clean:
rm -f $(YML2_FILE)
rm -f $(PYBIND11_FILE)
rm -f $(DEBUG_AST_FILE)
rm -f $(DEBUG_ACID_FILE)
rm -f $(DEBUG_YML_FILE)

98
src/pEp/_gen/gen/config.json

@ -0,0 +1,98 @@
{
"module_name": "_gen",
"header_filename": "../adapter_main.hh",
"libclang_path": "/opt/local/libexec/llvm-9.0/lib/libclang.dylib",
"variables": [
],
"functions": [
"KEYMANAGEMENT",
"update_identity",
"myself",
"//register_examine_function",
"//do_keymanagement",
"key_mistrusted",
"trust_personal_key",
"trust_own_key",
"key_reset_trust",
"//own_key_is_listed",
"_own_identities_retrieve",
"own_identities_retrieve",
"_own_keys_retrieve",
"own_keys_retrieve",
"set_own_key",
"//clean_own_key_defaults",
"//PEPENGINE",
"update_identity",
"myself",
"//register_examine_function",
"//do_keymanagement",
"key_mistrusted",
"trust_personal_key",
"trust_own_key",
"key_reset_trust",
"//own_key_is_listed",
"own_identities_retrieve",
"//own_keys_retrieve",
"set_own_key",
"//clean_own_key_defaults",
"new_identity",
"//MESSAGE_API",
"encrypt_message",
"encrypt_message_and_add_priv_key",
"encrypt_message_for_self",
"color_from_rating",
"decrypt_message",
"own_message_private_key_details",
"outgoing_message_rating",
"outgoing_message_rating_preview",
"identity_rating",
"get_binary_path",
"get_trustwords",
"get_message_trustwords",
"get_trustwords_for_fprs",
"re_evaluate_message_rating",
"get_key_rating_for_user",
"rating_from_comm_type",
"probe_encrypt",
"//MESSAGE",
"new_message",
"free_message",
"message_dup",
"message_transfer",
"new_message_ref_list",
"free_message_ref_list",
"message_ref_list_dup",
"message_ref_list_add",
"//SYNC_API",
"deliverHandshakeResult",
"//register_sync_callbacks",
"//unregister_sync_callbacks",
"//do_sync_protocol",
"//do_sync_protocol_step",
"//is_sync_thread",
"//new_sync_timeout_event",
"enter_device_group",
"//leave_device_group",
"enable_identity_for_sync",
"disable_identity_for_sync",
"//SYNC_CODEC",
"//decode_Sync_message",
"//encode_Sync_message",
"//PER_to_XER_Sync_msg",
"//XER_to_PER_Sync_msg",
"//DISTRIBUTION_CODEC",
"//decode_Distribution_message",
"//encode_Distribution_message",
"//PER_to_XER_Distribution_msg",
"//XER_to_PER_Distribution_msg"
],
"debug_ast" : 0,
"debug_acid" : 0,
"debug_yml" : 0
}

22
src/pEp/_gen/pEpModule.cc

@ -0,0 +1,22 @@
#include <string>
#include <iostream>
#include <pybind11/pybind11.h>
#include <pybind11/detail/common.h>
#include "adapter_main.hh"
#include <pEp/Adapter.hh>
#include <pEp/callback_dispatcher.hh>
using namespace std;
namespace alib = pEp::Adapter;
PEP_SESSION pep_session() {
return alib::session();
}
PYBIND11_MODULE(_gen, m) {
// PEP_SESSION
// m.def("pep_session",(PEP_SESSION(*)()) &pep_session);
#include "gen/py_module.pybind11"
}

32
src/pEp/_pEp/Makefile

@ -0,0 +1,32 @@
include ../Makefile.conf
TARGET=$(TARGET_PEP)
# Specific Build settings
CXXFLAGS+=-Wno-unused-result -Wsign-compare -Wunreachable-code -fno-common -dynamic -g -fwrapv -O3 -Wall -pipe -Os -isysroot/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk
INCLUDES+=
LIB_DIRS+=
LIBS+=-lboost_python38-mt -lboost_locale-mt
LDFLAGS+=
# Combine Settings
CXXFLAGS+=$(INCLUDES)
LDFLAGS+=$(LIB_DIRS)
LDFLAGS+=$(LIBS)
SRCS:=$(wildcard *.cc)
OBJS:=$(SRCS:.cc=.o)
.PHONY: clean
all: $(TARGET)
# Using implicit compile target
# And explicit link taget
$(TARGET): $(OBJS)
$(CXX) $(LDFLAGS) -o $@ $^
clean:
rm -rf $(TARGET)
rm -rf $(OBJS)

163
src/pEp/_pEp/adapter_main.cc

@ -0,0 +1,163 @@
// This file is under GNU Affero General Public License 3.0
// see LICENSE.txt
#include "adapter_main.hh"
#include "message.hh"
#include "message_api.hh"
namespace pEp {
namespace PythonAdapter {
static const char *version_string = "p≡p Python adapter version 0.3";
void init_before_main_module() {
pEpLog("called");
}
// hidden init function, wrapped by hello_world.init()
void _init_after_main_module() {
pEpLog("called");
callback_dispatcher.add(_messageToSend, notifyHandshake, nullptr, nullptr);
Adapter::_messageToSend = CallbackDispatcher::messageToSend;
}
void config_passive_mode(bool enable) {
::config_passive_mode(Adapter::session(), enable);
}
void config_unencrypted_subject(bool enable) {
::config_unencrypted_subject(Adapter::session(), enable);
}
void key_reset_user(const string &user_id, const string &fpr) {
if (user_id == "") {
throw invalid_argument("user_id required");
}
::PEP_STATUS status = ::key_reset_user(Adapter::session(), user_id.c_str(), fpr != "" ? fpr.c_str() : nullptr);
_throw_status(status);
}
void key_reset_user2(const string &user_id) {
key_reset_user(user_id, "");
}
void key_reset_all_own_keys() {
::PEP_STATUS status = ::key_reset_all_own_keys(Adapter::session());
_throw_status(status);
}
string about() {
string version = string(version_string) + "\np≡p version " + PEP_VERSION + "\n";
return version;
}
void _throw_status(::PEP_STATUS status) {
if (status == ::PEP_STATUS_OK) {
return;
}
if (status >= 0x400 && status <= 0x4ff) {
return;
}
if (status == ::PEP_OUT_OF_MEMORY) {
throw bad_alloc();
}
if (status == ::PEP_ILLEGAL_VALUE) {
throw invalid_argument("illegal value");
}
if (status_to_string(status) == "unknown status code") {
stringstream build;
build << setfill('0') << "p≡p 0x" << setw(4) << hex << status;
throw runtime_error(build.str());
} else {
throw runtime_error(status_to_string(status));
}
}
::PEP_STATUS _messageToSend(::message *msg) {
pEpLog("called");
try {
PyGILState_STATE gil = PyGILState_Ensure();
pEpLog("GIL Aquired");
bp::object modref = bp::import("pEp");
bp::object funcref = modref.attr("message_to_send");
bp::call<void>(funcref.ptr(), Message());
PyGILState_Release(gil);
pEpLog("GIL released");
} catch (exception &e) {
}
return ::PEP_STATUS_OK;
}
::PEP_STATUS notifyHandshake(::pEp_identity *me, ::pEp_identity *partner, ::sync_handshake_signal signal) {
pEpLog("called");
try {
PyGILState_STATE gil = PyGILState_Ensure();
pEpLog("GIL Aquired");
bp::object modref = bp::import("pEp");
bp::object funcref = modref.attr("notify_handshake");
bp::call<void>(funcref.ptr(), me, partner, signal);
PyGILState_Release(gil);
pEpLog("GIL released");
} catch (exception &e) {
}
return ::PEP_STATUS_OK;
}
void start_sync() {
CallbackDispatcher::start_sync();
}
void shutdown_sync() {
CallbackDispatcher::stop_sync();
}
void debug_color(int ansi_color) {
::set_debug_color(Adapter::session(), ansi_color);
}
void leave_device_group() {
::leave_device_group(Adapter::session());
}
bool is_sync_active() {
return Adapter::is_sync_running();
}
void testfunc() {
_messageToSend(nullptr);
}
void deliverHandshakeResult(int result, bp::object identities) {
identity_list *shared_identities = nullptr;
if (identities != bp::api::object() && boost::python::len(identities)) {
shared_identities = ::new_identity_list(nullptr);
if (!shared_identities) {
throw bad_alloc();
}
try {
::identity_list *si = shared_identities;
for (int i = 0; i < bp::len(identities); ++i) {
Identity ident = bp::extract<Identity>(identities[i]);
si = ::identity_list_add(si, ident);
if (!si) {
throw bad_alloc();
}
}
} catch (exception &ex) {
::free_identity_list(shared_identities);
throw ex;
}
}
::PEP_STATUS status = ::deliverHandshakeResult(Adapter::session(), (::sync_handshake_result)result, shared_identities);
free_identity_list(shared_identities);
_throw_status(status);
}
} // namespace PythonAdapter
} // namespace pEp

84
src/pEp/_pEp/adapter_main.hh

@ -0,0 +1,84 @@
// This file is under GNU Affero General Public License 3.0
// see LICENSE.txt
#ifndef ADAPTER_MAIN_HH
#define ADAPTER_MAIN_HH
// System
#include <string>
#include <iomanip>
// Boost
#include <boost/python.hpp>
#include <boost/locale.hpp>
// Engine
#include <pEp/pEpEngine.h>
#include <pEp/keymanagement.h>
#include <pEp/identity_list.h>
#include <pEp/key_reset.h>
#include <pEp/sync_api.h>
#include <pEp/mime.h>
#include <pEp/message.h>
#include <pEp/message_api.h>
#include <pEp/sync_codec.h>
#include <pEp/distribution_codec.h>
#include <pEp/timestamp.h>
#include <pEp/stringpair.h>
// libpEpAdapter
#include <pEp/Adapter.hh>
#include <pEp/callback_dispatcher.hh>
#include <pEp/status_to_string.hh>
#include <pEp/pEpLog.hh>
namespace pEp {
namespace PythonAdapter {
using namespace std;
namespace bp = boost::python;
namespace bl = boost::locale;
void init_before_main_module();
void _init_after_main_module();
void testfunc();
//extern string device_name;
string about();
void config_passive_mode(bool enable);
void start_sync();
void shutdown_sync();
void debug_color(int ansi_color);
bool is_sync_active();
void config_unencrypted_subject(bool enable);
void key_reset_user(const string &user_id, const string &fpr);
void key_reset_user2(const string &user_id);
void key_reset_all_own_keys();
void _throw_status(::PEP_STATUS status);
void leave_device_group();
::PEP_STATUS _messageToSend(::message *msg);
::PEP_STATUS notifyHandshake(::pEp_identity *me, ::pEp_identity *partner, ::sync_handshake_signal signal);
void deliverHandshakeResult(int result, bp::object identities);
} // namespace PythonAdapter
} // namespace pEp
#endif // ADAPTER_MAIN_HH

177
src/pEp/_pEp/basic_api.cc

@ -1,161 +1,152 @@
// This file is under GNU Affero General Public License 3.0
// see LICENSE.txt
// System
#include <sstream>
// Engine
#include <pEp/keymanagement.h>
#include <pEp/message_api.h>
#include <pEp/Adapter.hh>
// local
#include "basic_api.hh"
namespace pEp {
namespace PythonAdapter {
using namespace std;
namespace PythonAdapter {
void update_identity(Identity &ident) {
if (ident.address() == "")
void update_identity(Identity &ident) {
if (ident.address() == "") {
throw invalid_argument("address needed");
if (ident.user_id() == PEP_OWN_USERID)
throw runtime_error("update_identity: '"
PEP_OWN_USERID
"' may only be used for own identities");
PEP_STATUS status = update_identity(Adapter::session(), ident);
_throw_status(status);
}
if (ident.user_id() == PEP_OWN_USERID) {
throw runtime_error("update_identity: '" PEP_OWN_USERID "' may only be used for own identities");
}
::PEP_STATUS status = ::update_identity(Adapter::session(), ident);
_throw_status(status);
}
void myself(Identity &ident) {
if (ident.address() == "")
void myself(Identity &ident) {
if (ident.address() == "") {
throw invalid_argument("address needed");
if (ident.username() == "")
}
if (ident.username() == "") {
throw invalid_argument("username needed");
if (ident.user_id() == "")
}
if (ident.user_id() == "") {
ident.user_id(ident.address());
PEP_STATUS status = myself(Adapter::session(), ident);
_throw_status(status);
}
::PEP_STATUS status = ::myself(Adapter::session(), ident);
_throw_status(status);
}
string _trustwords(Identity me, Identity partner, string lang, bool full) {
if (me.fpr() == "" || partner.fpr() == "")
string _trustwords(Identity me, Identity partner, string lang, bool full) {
if (me.fpr() == "" || partner.fpr() == "") {
throw invalid_argument("fingerprint needed in Identities");
if (lang == "" && me.lang() == partner.lang())
}
if (lang == "" && me.lang() == partner.lang()) {
lang = me.lang();
char *words = NULL;
}
char *words = nullptr;
size_t size = 0;
PEP_STATUS status = get_trustwords(Adapter::session(), me, partner,
lang.c_str(), &words, &size, full);
::PEP_STATUS status = ::get_trustwords(Adapter::session(), me, partner, lang.c_str(), &words, &size, full);
_throw_status(status);
return words;
}
}
void trust_personal_key(Identity ident) {
if (ident.fpr() == "")
void trust_personal_key(Identity ident) {
if (ident.fpr() == "") {
throw invalid_argument("fingerprint needed in Identities");
if (ident.user_id() == "")
}
if (ident.user_id() == "") {
throw invalid_argument("user_id must be provided");
PEP_STATUS status = trust_personal_key(Adapter::session(), ident);
_throw_status(status);
}
::PEP_STATUS status = ::trust_personal_key(Adapter::session(), ident);
_throw_status(status);
}
void set_identity_flags(Identity ident, identity_flags_t flags) {
if (ident.address() == "")
void set_identity_flags(Identity ident,const ::identity_flags_t &flags) {
if (ident.address() == "") {
throw invalid_argument("address needed");
if (ident.user_id() == "")
}
if (ident.user_id() == "") {
throw invalid_argument("user_id needed");
PEP_STATUS status = set_identity_flags(Adapter::session(), ident, flags);
_throw_status(status);
}
::PEP_STATUS status = ::set_identity_flags(Adapter::session(), ident, flags);
_throw_status(status);
}
void unset_identity_flags(Identity ident, identity_flags_t flags) {
if (ident.address() == "")
void unset_identity_flags(Identity ident,const ::identity_flags_t &flags) {
if (ident.address() == "") {
throw invalid_argument("address needed");
if (ident.user_id() == "")
}
if (ident.user_id() == "") {
throw invalid_argument("user_id needed");
PEP_STATUS status = unset_identity_flags(Adapter::session(), ident, flags);
_throw_status(status);
}
::PEP_STATUS status = ::unset_identity_flags(Adapter::session(), ident, flags);
_throw_status(status);
}
void key_reset_trust(Identity ident) {
if (ident.fpr() == "")
void key_reset_trust(Identity ident) {
if (ident.fpr() == "") {
throw invalid_argument("fpr needed");
if (ident.address() == "")
}
if (ident.address() == "") {
throw invalid_argument("address needed");
if (ident.user_id() == "")
}
if (ident.user_id() == "") {
throw invalid_argument("user_id needed");
PEP_STATUS status = key_reset_trust(Adapter::session(), ident);
_throw_status(status);
}
boost::python::list import_key(string key_data) {
::identity_list *private_keys = NULL;
PEP_STATUS status = ::import_key(Adapter::session(), key_data.c_str(), key_data.size(), &private_keys);
if (status && status != PEP_KEY_IMPORTED)
::PEP_STATUS status = ::key_reset_trust(Adapter::session(), ident);
_throw_status(status);
}
auto result = boost::python::list();
bp::list import_key(const string &key_data) {
::identity_list *private_keys = nullptr;
::PEP_STATUS status = ::import_key(Adapter::session(), key_data.c_str(), key_data.size(), &private_keys);
if (status && status != ::PEP_KEY_IMPORTED) {
_throw_status(status);
}
auto result = bp::list();
for (::identity_list *il = private_keys; il && il->ident; il = il->next) {
::pEp_identity *ident = ::identity_dup(il->ident);
if (!ident) {
free_identity_list(private_keys);
::free_identity_list(private_keys);
throw bad_alloc();
}
result.append(Identity(ident));
}
free_identity_list(private_keys);
::free_identity_list(private_keys);
return result;
}
}
string export_key(Identity ident) {
PEP_STATUS status = PEP_STATUS_OK;
char *key_data = NULL;
string export_key(Identity ident) {
::PEP_STATUS status = ::PEP_STATUS_OK;
char *key_data = nullptr;
size_t size;
status = ::export_key(Adapter::session(), ident.fpr().c_str(), &key_data, &size);
_throw_status(status);
return key_data;
}
}
string export_secret_key(Identity ident) {
PEP_STATUS status = PEP_STATUS_OK;
string export_secret_key(Identity ident) {
::PEP_STATUS status = ::PEP_STATUS_OK;
char *key_data = NULL;
size_t size;
status = ::export_secret_key(Adapter::session(), ident.fpr().c_str(), &key_data, &size);
_throw_status(status);
return key_data;
}
}
void set_own_key(Identity &ident, string fpr) {
if (ident.address() == "")
void set_own_key(Identity &ident, const string &fpr) {
if (ident.address() == "") {
throw invalid_argument("address needed");
if (ident.username() == "")
}
if (ident.username() == "") {
throw invalid_argument("username needed");
if (ident.user_id() == "")
}
if (ident.user_id() == "") {
throw invalid_argument("user_id needed");
if (fpr == "")
}
if (fpr == "") {
throw invalid_argument("fpr needed");
}
const char *fpr_c = fpr.c_str();
PEP_STATUS status = set_own_key(Adapter::session(), ident, fpr_c);
::PEP_STATUS status = ::set_own_key(Adapter::session(), ident, fpr_c);
_throw_status(status);
}
} // namespace PythonAdapter
}
} // namespace PythonAdapter
} // namespace pEp

29
src/pEp/_pEp/basic_api.hh

@ -4,34 +4,35 @@
#ifndef BASIC_API_HH
#define BASIC_API_HH
#include "pEpmodule.hh"
#include "adapter_main.hh"
#include "identity.hh"
namespace pEp {
namespace PythonAdapter {
namespace PythonAdapter {
void update_identity(Identity &ident);
void update_identity(Identity &ident);
void myself(Identity &ident);
void myself(Identity &ident);
string _trustwords(Identity me, Identity partner, string lang, bool full);
string _trustwords(Identity me, Identity partner, string lang, bool full);
void trust_personal_key(Identity ident);
void trust_personal_key(Identity ident);
void set_identity_flags(Identity ident, identity_flags_t flags);
void set_identity_flags(Identity ident,const ::identity_flags_t &flags);
void unset_identity_flags(Identity ident, identity_flags_t flags);
void unset_identity_flags(Identity ident,const ::identity_flags_t &flags);
void key_reset_trust(Identity ident);
void key_reset_trust(Identity ident);
boost::python::list import_key(string key_data);
bp::list import_key(const string &key_data);
string export_key(Identity ident);
string export_key(Identity ident);
string export_secret_key(Identity ident);
string export_secret_key(Identity ident);
void set_own_key(Identity &ident, string fpr);
void set_own_key(Identity &ident, const string &fpr);
} /* namespace PythonAdapter */
} /* namespace PythonAdapter */
} /* namespace pEp */
#endif /* BASIC_API_HH */

231
src/pEp/_pEp/identity.cc

@ -1,170 +1,166 @@
// This file is under GNU Affero General Public License 3.0
// see LICENSE.txt
// System
#include <typeinfo>
#include <sstream>
// Engine
#include <pEp/identity_list.h>
#include <pEp/keymanagement.h>
#include <pEp/key_reset.h>
// local
#include "identity.hh"
#include "pEpmodule.hh"
#include "basic_api.hh"
#include "message_api.hh"
namespace pEp {
namespace PythonAdapter {
using namespace std;
using namespace boost::python;
Identity::Identity(string address, string username, string user_id,
string fpr, int comm_type, string lang, identity_flags_t flags)
: _ident(new_identity(address.c_str(), fpr.c_str(), user_id.c_str(),
username.c_str()), &::free_identity) {
if (!_ident)
namespace PythonAdapter {
Identity::Identity(string address, string username, string user_id, string fpr, int comm_type, string lang, ::identity_flags_t flags)
: _ident(::new_identity(address.c_str(), fpr.c_str(), user_id.c_str(), username.c_str()), &::free_identity) {
if (!_ident) {
throw bad_alloc();
_ident->comm_type = (PEP_comm_type) comm_type;
_ident->flags = (identity_flags_t) flags;
this->lang(lang);
}
_ident->comm_type = (::PEP_comm_type)comm_type;
_ident->flags = (::identity_flags_t)flags;
this->lang(lang);
}
Identity::Identity(const Identity &second)
Identity::Identity(const Identity &second)
: _ident(second._ident) {
}
}
Identity::Identity(pEp_identity *ident)
Identity::Identity(::pEp_identity *ident)
: _ident(ident, &::free_identity) {
}
}
Identity::~Identity() {
Identity::~Identity() {
}
}
Identity::operator pEp_identity *() {
Identity::operator ::pEp_identity *() {
return _ident.get();
}
}
Identity::operator const pEp_identity *() const {
Identity::operator const ::pEp_identity *() const {
return _ident.get();
}
}
string Identity::_repr() {
string Identity::_repr() {
stringstream build;
build << "Identity(";
string address;
if (_ident->address)
if (_ident->address) {
address = string(_ident->address);
}
build << repr(address) << ", ";
string username;
if (_ident->username)
if (_ident->username) {
username = string(_ident->username);
}
build << repr(username) << ", ";
string user_id;
if (_ident->user_id)
if (_ident->user_id) {
user_id = string(_ident->user_id);
}
build << repr(user_id) << ", ";
string fpr;
if (_ident->fpr)
if (_ident->fpr) {
fpr = string(_ident->fpr);
}
build << repr(fpr) << ", ";
build << (int) _ident->comm_type << ", ";
build << (int)_ident->comm_type << ", ";
string lang = _ident->lang;
build << repr(lang) << ")";
return build.str();
}
}
string Identity::_str() {
if (!(_ident->address && _ident->address[0]))
string Identity::_str() {
if (!(_ident->address && _ident->address[0])) {
return "";
if (!(_ident->username && _ident->username[0]))
}
if (!(_ident->username && _ident->username[0])) {
return _ident->address;
return string(_ident->username) + " <" + _ident->address + ">";
}
return string(_ident->username) + " <" + _ident->address + ">";
}
void Identity::username(string value) {
if (value.length() && value.length() < 5)
void Identity::username(string value) {
if (value.length() && value.length() < 5) {
throw length_error("username must be at least 5 characters");
}
str_attr(_ident->username, value);
}
}
void Identity::lang(string value) {
if (value == "")
void Identity::lang(string value) {
if (value == "") {
memset(_ident->lang, 0, 3);
else if (value.length() != 2)
} else if (value.length() != 2) {
throw length_error("length of lang must be 2");
else
} else {
memcpy(_ident->lang, value.c_str(), 3);
}
}
string Identity::lang() {
string Identity::lang() {
return _ident->lang;
}
}
int Identity::rating() {
if (!(_ident->address))
int Identity::rating() {
if (!(_ident->address)) {
throw invalid_argument("address must be given");
}
PEP_rating rating = PEP_rating_undefined;
PEP_STATUS status = ::identity_rating(Adapter::session(), _ident.get(), &rating);
::PEP_rating rating = ::PEP_rating_undefined;
::PEP_STATUS status = ::identity_rating(Adapter::session(), _ident.get(), &rating);
_throw_status(status);
return (int) rating;
}
return (int)rating;
}
PEP_color Identity::color() {
::PEP_color Identity::color() {
return _color(rating());
}
}
Identity Identity::copy() {
pEp_identity *dup = ::identity_dup(*this);
if (!dup)
Identity Identity::copy() {
::pEp_identity *dup = ::identity_dup(*this);
if (!dup) {
throw bad_alloc();
}
return Identity(dup);
}
}
Identity Identity::deepcopy(dict &) {
Identity Identity::deepcopy(bp::dict &) {
return copy();
}
}
void Identity::update() {
void Identity::update() {
update_identity(*this);
}
}
void Identity::key_reset(string fpr) {
PEP_STATUS status = ::key_reset_identity(Adapter::session(), *this,
fpr != "" ? fpr.c_str() : nullptr);
void Identity::key_reset(const string &fpr) {
::PEP_STATUS status = ::key_reset_identity(Adapter::session(), *this, fpr != "" ? fpr.c_str() : nullptr);
_throw_status(status);
}
}
void Identity::key_mistrusted() {
PEP_STATUS status = ::key_mistrusted(Adapter::session(), *this);
void Identity::key_mistrusted() {
::PEP_STATUS status = ::key_mistrusted(Adapter::session(), *this);
_throw_status(status);
}
}
bool Identity::is_pEp_user() {
bool Identity::is_pEp_user() {
bool result;
PEP_STATUS status = ::is_pEp_user(Adapter::session(), *this, &result);
::PEP_STATUS status = ::is_pEp_user(Adapter::session(), *this, &result);
_throw_status(status);
return result;
}
}
void Identity::enable_for_sync() {
PEP_STATUS status = ::enable_identity_for_sync(Adapter::session(), *this);
void Identity::enable_for_sync() {
::PEP_STATUS status = ::enable_identity_for_sync(Adapter::session(), *this);
_throw_status(status);
}
}
void Identity::disable_for_sync() {
PEP_STATUS status = ::disable_identity_for_sync(Adapter::session(), *this);
void Identity::disable_for_sync() {
::PEP_STATUS status = ::disable_identity_for_sync(Adapter::session(), *this);
_throw_status(status);
}
}
// Myself::Myself(string address, string username, string user_id, string lang)
// : Identity(address, username, user_id, "", 0, lang) {
@ -183,61 +179,66 @@ namespace pEp {
// pEp::PythonAdapter::myself(*this);
// }
Identity identity_attr(pEp_identity *&ident) {
if (!ident)
Identity identity_attr(::pEp_identity *&ident) {
if (!ident) {
throw out_of_range("no identity assigned");
}
pEp_identity *_dup = ::identity_dup(ident);
if (!_dup)
::pEp_identity *_dup = ::identity_dup(ident);
if (!_dup) {
throw bad_alloc();
}
Identity _ident(_dup);
return _ident;
}
}
void identity_attr(pEp_identity *&ident, object value) {
Identity &_ident = extract<Identity &>(value);
pEp_identity *_dup = ::identity_dup(_ident);
if (!_dup)
void identity_attr(::pEp_identity *&ident, bp::object value) {
Identity &_ident = bp::extract<Identity &>(value);
::pEp_identity *_dup = ::identity_dup(_ident);
if (!_dup) {
throw bad_alloc();
PEP_STATUS status = ::update_identity(Adapter::session(), _dup);
}
::PEP_STATUS status = ::update_identity(Adapter::session(), _dup);
_throw_status(status);
::free_identity(ident);
ident = _dup;
}
}
boost::python::list identitylist_attr(identity_list *&il) {
boost::python::list result;
bp::list identitylist_attr(::identity_list *&il) {
bp::list result;
for (identity_list *_il = il; _il && _il->ident; _il = _il->next) {
pEp_identity *ident = ::identity_dup(_il->ident);
if (!ident)
for (::identity_list *_il = il; _il && _il->ident; _il = _il->next) {
::pEp_identity *ident = ::identity_dup(_il->ident);
if (!ident) {
throw bad_alloc();
result.append(object(Identity(ident)));
}
result.append(bp::object(Identity(ident)));
}
return result;
}
}
void identitylist_attr(identity_list *&il, boost::python::list value) {
identity_list *_il = ::new_identity_list(NULL);
if (!_il)
void identitylist_attr(::identity_list *&il, bp::list value) {
::identity_list *_il = ::new_identity_list(nullptr);
if (!_il) {
throw bad_alloc();
}
identity_list *_i = _il;
::identity_list *_i = _il;
for (int i = 0; i < len(value); i++) {
extract < Identity & > extract_identity(value[i]);
bp::extract<Identity &> extract_identity(value[i]);
if (!extract_identity.check()) {
free_identity_list(_il);
::free_identity_list(_il);
}
pEp_identity *_ident = extract_identity();
pEp_identity *_dup = ::identity_dup(_ident);
::pEp_identity *_ident = extract_identity();
::pEp_identity *_dup = ::identity_dup(_ident);
if (!_dup) {
::free_identity_list(_il);
throw bad_alloc();
}
PEP_STATUS status = ::update_identity(Adapter::session(), _dup);
if (status != PEP_STATUS_OK) {
::PEP_STATUS status = ::update_identity(Adapter::session(), _dup);
if (status != ::PEP_STATUS_OK) {
::free_identity_list(_il);
_throw_status(status);
}
@ -250,8 +251,8 @@ namespace pEp {
::free_identity_list(il);
il = _il;
}
}
} // namespace PythonAdapter
} // namespace PythonAdapter
} // namespace pEp

60
src/pEp/_pEp/identity.hh

@ -5,47 +5,29 @@
#define IDENTITY_HH
// System
#include <boost/python.hpp>
#include <string>
#include <memory>
#include <cstddef>
// Engine
#include <pEp/pEpEngine.h>
#include <pEp/message_api.h>
//libpEpAdapter
#include "pEp/Adapter.hh"
// local
#include "adapter_main.hh"
#include "str_attr.hh"
namespace pEp {
namespace PythonAdapter {
using std::string;
using std::shared_ptr;
namespace PythonAdapter {
// Identity is owning a pEp_identity
class Identity {
class Identity {
protected:
shared_ptr <pEp_identity> _ident;
shared_ptr<::pEp_identity> _ident;
public:
Identity(string address = "", string username = "",
string user_id = "", string fpr = "", int comm_type = 0,
string lang = "", identity_flags_t flags = 0);
Identity(string address = "", string username = "", string user_id = "", string fpr = "", int comm_type = 0, string lang = "", ::identity_flags_t flags = 0);
Identity(const Identity &second);
Identity(pEp_identity *ident);
Identity(::pEp_identity *ident);
virtual ~Identity();
operator pEp_identity *();
operator ::pEp_identity *();
operator const pEp_identity *() const;
operator const ::pEp_identity *() const;
string _repr();
@ -67,29 +49,29 @@ namespace pEp {
void username(string value);
PEP_comm_type comm_type() { return _ident->comm_type; }
::PEP_comm_type comm_type() { return _ident->comm_type; }
void comm_type(PEP_comm_type value) { _ident->comm_type = value; };
void comm_type(::PEP_comm_type value) { _ident->comm_type = value; };
std::string lang();
void lang(std::string value);
identity_flags_t flags() { return _ident->flags; }
::identity_flags_t flags() { return _ident->flags; }
void flags(identity_flags_t flags) { _ident->flags = flags; }
void flags(::identity_flags_t flags) { _ident->flags = flags; }
int rating();
PEP_color color();
::PEP_color color();
Identity copy();
Identity deepcopy(dict &memo);
Identity deepcopy(bp::dict &memo);
virtual void update();
void key_reset(string fpr = "");
void key_reset(const string &fpr = "");
void key_mistrusted();
@ -98,7 +80,7 @@ namespace pEp {
void enable_for_sync();
void disable_for_sync();
};
};
// class Myself : public Identity {
// public:
@ -107,15 +89,15 @@ namespace pEp {
// virtual void update();
// };
Identity identity_attr(pEp_identity *&ident);
Identity identity_attr(::pEp_identity *&ident);
void identity_attr(pEp_identity *&ident, object value);
void identity_attr(::pEp_identity *&ident, bp::object value);
boost::python::list identitylist_attr(identity_list *&il);
bp::list identitylist_attr(::identity_list *&il);
void identitylist_attr(identity_list *&il, boost::python::list value);
void identitylist_attr(::identity_list *&il, bp::list value);
} // namespace PythonAdapter
} // namespace PythonAdapter
} // namespace pEp
#endif /* IDENTITY_HH */

320
src/pEp/_pEp/message.cc

@ -1,45 +1,36 @@
// This file is under GNU Affero General Public License 3.0
// see LICENSE.txt
// System
#include <cstdlib>
#include <cstring>
#include <stdexcept>
#include <sstream>
#include <vector>
#include <Python.h>
// Engine
#include <pEp/mime.h>
#include <pEp/keymanagement.h>
#include <pEp/message_api.h>
// local
#include "message.hh"
#include "message_api.hh"
namespace pEp {
namespace PythonAdapter {
using namespace std;
using namespace boost::python;
namespace PythonAdapter {
Message::Blob::Blob(bloblist_t *bl, bool chained) :
_bl(bl), part_of_chain(chained) {
if (!_bl)
Message::Blob::Blob(::bloblist_t *bl, bool chained)
: _bl(bl),
part_of_chain(chained) {
if (!_bl) {
throw bad_alloc();
}
}
Message::Blob::Blob(object data, string mime_type, string filename) :
_bl(new_bloblist(NULL, 0, NULL, NULL)), part_of_chain(false) {
if (!_bl)
Message::Blob::Blob(bp::object data, string mime_type, string filename)
: _bl(::new_bloblist(nullptr, 0, nullptr, nullptr)),
part_of_chain(false) {
if (!_bl) {
throw bad_alloc();
}
Py_buffer src;
int result = PyObject_GetBuffer(data.ptr(), &src, PyBUF_CONTIG_RO);
if (result)
if (result) {
throw invalid_argument("need a contiguous buffer to read");
}
char *mem = (char *) malloc(src.len);
char *mem = (char *)malloc(src.len);
if (!mem) {
PyBuffer_Release(&src);
throw bad_alloc();
@ -54,21 +45,21 @@ namespace pEp {
this->mime_type(mime_type);
this->filename(filename);
}
}
Message::Blob::Blob(const Message::Blob &second) :
_bl(second._bl), part_of_chain(true) {
Message::Blob::Blob(const Message::Blob &second)
: _bl(second._bl),
part_of_chain(true) {
}
}
Message::Blob::~Blob() {
Message::Blob::~Blob() {
if (!part_of_chain) {
free(_bl->value);
free(_bl);
}
}
}
string Message::Blob::_repr() {
string Message::Blob::_repr() {
stringstream build;
build << "Blob(";
if (!_bl) {
@ -76,193 +67,196 @@ namespace pEp {
} else {
build << "bytes(" << _bl->size << "), ";
string mime_type;
if (_bl->mime_type)
if (_bl->mime_type) {
mime_type = string(_bl->mime_type);
}
string filename;
if (_bl->filename)
if (_bl->filename) {
filename = string(_bl->filename);
}
build << repr(mime_type) << ", ";
build << repr(filename);
}
build << ")";
return build.str();
}
}
int Message::Blob::getbuffer(PyObject *self, Py_buffer *view, int flags) {
bloblist_t *bl = NULL;
int Message::Blob::getbuffer(PyObject *self, Py_buffer *view, int flags) {
::bloblist_t *bl = nullptr;
try {
Message::Blob &blob = extract<Message::Blob &>(self);
Message::Blob &blob = bp::extract<Message::Blob &>(self);
bl = blob._bl;
}
catch (exception &e) {
} catch (exception &e) {
PyErr_SetString(PyExc_RuntimeError, "extract not possible");
view->obj = NULL;
view->obj = nullptr;
return -1;
}
if (!(bl && bl->value)) {
PyErr_SetString(PyExc_RuntimeError, "no data available");
view->obj = NULL;
view->obj = nullptr;
return -1;
}
return PyBuffer_FillInfo(view, self, bl->value, bl->size, 0, flags);
}
}
string Message::Blob::decode(string encoding) {
string Message::Blob::decode(string encoding) {
if (encoding == "") {
string _mime_type = _bl->mime_type ? _bl->mime_type : "";
encoding = "ascii";
if (_mime_type == "application/pEp.sync")
if (_mime_type == "application/pEp.sync") {
encoding = "pep.sync";
}
if (_mime_type == "application/pEp.keyreset")
if (_mime_type == "application/pEp.keyreset") {
encoding = "pep.distribution";
}
object codecs = import("codecs");
object _decode = codecs.attr("decode");
return call<string>(_decode.ptr(), this, encoding);
}
bp::object codecs = bp::import("codecs");
bp::object _decode = codecs.attr("decode");
return bp::call<string>(_decode.ptr(), this, encoding);
}
PyBufferProcs Message::Blob::bp = {getbuffer, NULL};
PyBufferProcs Message::Blob::bp = {getbuffer, nullptr};
Message::Message(int dir, Identity *from)
: _msg(new_message((PEP_msg_direction) dir), &free_message) {
if (!_msg)
Message::Message(int dir, Identity *from)
: _msg(new_message((::PEP_msg_direction)dir), &::free_message) {
if (!_msg) {
throw bad_alloc();
}
if (from) {
_msg->from = ::identity_dup(*from);
if (!_msg->from)
if (!_msg->from) {
throw bad_alloc();
_msg->dir = (PEP_msg_direction) dir;
}
_msg->dir = (::PEP_msg_direction)dir;
}
}
Message::Message(string mimetext)
: _msg(NULL, &free_message) {
message *_cpy;
PEP_STATUS status = mime_decode_message(mimetext.c_str(),
mimetext.size(), &_cpy, NULL);
Message::Message(string mimetext)
: _msg(nullptr, &::free_message) {
::message *_cpy;
::PEP_STATUS status = ::mime_decode_message(mimetext.c_str(), mimetext.size(), &_cpy, nullptr);
switch (status) {
case PEP_STATUS_OK:
if (_cpy)
_cpy->dir = PEP_dir_outgoing;
else
_cpy = new_message(PEP_dir_outgoing);
case ::PEP_STATUS_OK:
if (_cpy) {
_cpy->dir = ::PEP_dir_outgoing;
} else {
_cpy = new_message(::PEP_dir_outgoing);
}
if (!_cpy)
if (!_cpy) {
throw bad_alloc();
}
_msg = shared_ptr<message>(_cpy);
_msg = shared_ptr<::message>(_cpy);
break;
case PEP_BUFFER_TOO_SMALL:
case ::PEP_BUFFER_TOO_SMALL:
throw runtime_error("mime_decode_message: buffer too small");
case PEP_CANNOT_CREATE_TEMP_FILE:
case ::PEP_CANNOT_CREATE_TEMP_FILE:
throw runtime_error("mime_decode_message: cannot create temp file");
case PEP_OUT_OF_MEMORY:
case ::PEP_OUT_OF_MEMORY:
throw bad_alloc();
default:
stringstream build;
build << "mime_decode_message: unknown error (" << (int) status << ")";
build << "mime_decode_message: unknown error (" << (int)status << ")";
throw runtime_error(build.str());
}
}
}
Message::Message(const Message &second)
Message::Message(const Message &second)
: _msg(second._msg) {
if (!_msg.get())
if (!_msg.get()) {
throw bad_alloc();
}
}
Message::Message(message *msg)
: _msg(::message_dup(msg), &free_message) {
}
Message::~Message() {
Message::Message(::message *msg)
: _msg(::message_dup(msg), &::free_message) {}
}
Message::~Message() {}
Message::operator message *() {
Message::operator ::message *() {
return _msg.get();
}
}
Message::operator const message *() const {
Message::operator const ::message *() const {
return _msg.get();
}
}
string Message::_str() {
if (!(_msg->from && _msg->from->address && _msg->from->address[0]))
string Message::_str() {
if (!(_msg->from && _msg->from->address && _msg->from->address[0])) {
throw out_of_range(".from_.address missing");
}
char *mimetext;
string result;
PEP_STATUS status = mime_encode_message(*this, false, &mimetext, false);
::PEP_STATUS status = ::mime_encode_message(*this, false, &mimetext, false);
switch (status) {
case PEP_STATUS_OK:
case ::PEP_STATUS_OK:
result = mimetext;
free(mimetext);
break;
case PEP_BUFFER_TOO_SMALL:
case ::PEP_BUFFER_TOO_SMALL:
throw runtime_error("mime_encode_message: buffer too small");
case PEP_CANNOT_CREATE_TEMP_FILE:
case ::PEP_CANNOT_CREATE_TEMP_FILE:
throw runtime_error("mime_encode_message: cannot create temp file");
case PEP_OUT_OF_MEMORY:
case ::PEP_OUT_OF_MEMORY:
throw bad_alloc();
default:
stringstream build;
build << "mime_encode_message: unknown error (" << (int) status << ")";
build << "mime_encode_message: unknown error (" << (int)status << ")";
throw runtime_error(build.str());
}
return result;
}
}
string Message::_repr() {
string Message::_repr() {
stringstream build;
build << "Message(" << repr(_str()) << ")";
return build.str();
}
}
boost::python::tuple Message::attachments() {
boost::python::list l;
bp::tuple Message::attachments() {
bp::list l;
for (bloblist_t *bl = _msg->attachments; bl && bl->value; bl =
bl->next) {
for (::bloblist_t *bl = _msg->attachments; bl && bl->value; bl = bl->next) {
l.append(Blob(bl, true));
}
return boost::python::tuple(l);
}
return bp::tuple(l);
}
void Message::attachments(boost::python::list value) {
bloblist_t *bl = new_bloblist(NULL, 0, NULL, NULL);
if (!bl)
void Message::attachments(bp::list value) {
::bloblist_t *bl = ::new_bloblist(nullptr, 0, nullptr, nullptr);
if (!bl) {
throw bad_alloc();
}
bloblist_t *_l = bl;
::bloblist_t *_l = bl;
for (int i = 0; i < len(value); i++) {
Message::Blob &blob = extract<Message::Blob &>(value[i]);
_l = bloblist_add(_l, blob._bl->value, blob._bl->size,
blob._bl->mime_type, blob._bl->filename);
Message::Blob &blob = bp::extract<Message::Blob &>(value[i]);
_l = bloblist_add(_l, blob._bl->value, blob._bl->size, blob._bl->mime_type, blob._bl->filename);
if (!_l) {
for (_l = bl; _l && _l->value;) {
free(_l->mime_type);
free(_l->filename);
bloblist_t *_ll = _l;
::bloblist_t *_ll = _l;
_l = _l->next;
free(_ll);
}
@ -271,115 +265,123 @@ namespace pEp {
}
for (int i = 0; i < len(value); i++) {
Message::Blob &blob = extract<Message::Blob &>(value[i]);
blob._bl->value = NULL;
Message::Blob &blob = bp::extract<Message::Blob &>(value[i]);
blob._bl->value = nullptr;
blob._bl->size = 0;
free(blob._bl->mime_type);
blob._bl->mime_type = NULL;
blob._bl->mime_type = nullptr;
free(blob._bl->filename);
blob._bl->filename = NULL;
blob._bl->filename = nullptr;
}
free_bloblist(_msg->attachments);
_msg->attachments = bl;
}
}
Message Message::encrypt() {
boost::python::list extra;
return encrypt_message(*this, extra, PEP_enc_PGP_MIME, 0);
}
Message Message::encrypt() {
bp::list extra;
return encrypt_message(*this, extra, ::PEP_enc_PGP_MIME, 0);
}
Message Message::_encrypt(boost::python::list extra, int enc_format, int flags) {
if (!enc_format)
enc_format = PEP_enc_PGP_MIME;
return encrypt_message(*this, extra, enc_format, flags);
Message Message::_encrypt(bp::list extra, int enc_format, int flags) {
if (!enc_format) {
enc_format = ::PEP_enc_PGP_MIME;
}
return encrypt_message(*this, extra, enc_format, flags);
}
boost::python::tuple Message::decrypt(int flags) {
bp::tuple Message::decrypt(int flags) {
return pEp::PythonAdapter::decrypt_message(*this, flags);
}
}
PEP_rating Message::outgoing_rating() {
if (_msg->dir != PEP_dir_outgoing)
::PEP_rating Message::outgoing_rating() {
if (_msg->dir != ::PEP_dir_outgoing) {
throw invalid_argument("Message.dir must be outgoing");
}
if (from().address() == "")
if (from().address() == "") {
throw invalid_argument("from.address needed");
if (from().username() == "")
}
if (from().username() == "") {
throw invalid_argument("from.username needed");
}
if (len(to()) + len(cc()) == 0)
if (len(to()) + len(cc()) == 0) {
throw invalid_argument("either to or cc needed");
}
PEP_STATUS status = myself(Adapter::session(), _msg->from);
::PEP_STATUS status = myself(Adapter::session(), _msg->from);
_throw_status(status);
PEP_rating rating = PEP_rating_undefined;
::PEP_rating rating = ::PEP_rating_undefined;
status = outgoing_message_rating(Adapter::session(), *this, &rating);
_throw_status(status);
return rating;
}
}
PEP_color Message::outgoing_color() {
::PEP_color Message::outgoing_color() {
return _color(outgoing_rating());
}
}
Message Message::copy() {
message *dup = message_dup(*this);
if (!dup)
Message Message::copy() {
::message *dup = ::message_dup(*this);
if (!dup) {
throw bad_alloc();
return Message(dup);
}
return Message(dup);
}
Message Message::deepcopy(dict &) {
Message Message::deepcopy(bp::dict &) {
return copy();
}
}
Message outgoing_message(Identity me) {
if (me.address().empty() || me.user_id().empty())
Message outgoing_message(Identity me) {
if (me.address().empty() || me.user_id().empty()) {
throw runtime_error("at least address and user_id of own user needed");
}
::myself(Adapter::session(), me);
auto m = Message(PEP_dir_outgoing, &me);
auto m = Message(::PEP_dir_outgoing, &me);
return m;
}
}
static object update(Identity ident) {
if (ident.address().empty())
static bp::object update(Identity ident) {
if (ident.address().empty()) {
throw runtime_error("at least address needed");
update_identity(Adapter::session(), ident);
return object(ident);
}
::update_identity(Adapter::session(), ident);
return bp::object(ident);
}
static boost::python::list update(boost::python::list il) {
static bp::list update(bp::list il) {
for (int i = 0; i < len(il); i++) {
update(extract<Identity>(il[i]));
update(bp::extract<Identity>(il[i]));
}
return il;
}
}
Message incoming_message(string mime_text) {
Message incoming_message(string mime_text) {
auto m = Message(mime_text);
m.dir(PEP_dir_incoming);
m.dir(::PEP_dir_incoming);
try {
m.from(update(m.from()));
} catch (out_of_range &) {
}
catch (out_of_range &) {}
try {
m.recv_by(update(m.recv_by()));
} catch (out_of_range &) {
}
catch (out_of_range &) {}
m.to(update(m.to()));
m.cc(update(m.cc()));
m.reply_to(update(m.reply_to()));
return m;
}
}
} // namespace PythonAdapter
} // namespace PythonAdapter
} // namespace pEp

101
src/pEp/_pEp/message.hh

@ -4,29 +4,15 @@
#ifndef MESSAGE_HH
#define MESSAGE_HH
// System
#include <string>
#include <boost/python.hpp>
#include <boost/lexical_cast.hpp>
// Engine
#include <pEp/message.h>
#include <pEp/message_api.h>
// local
#include "adapter_main.hh"
#include "str_attr.hh"
#include "identity.hh"
namespace pEp {
namespace PythonAdapter {
using std::string;
using std::runtime_error;
using std::invalid_argument;
using boost::lexical_cast;
namespace PythonAdapter {
// Message is owning a message struct
class Message {
class Message {
shared_ptr<::message> _msg;
public:
@ -34,14 +20,13 @@ namespace pEp {
// one depending on part_of_chain
class Blob {
bloblist_t *_bl;
::bloblist_t *_bl;
bool part_of_chain;
public:
Blob(bloblist_t *bl = new_bloblist(NULL, 0, NULL, NULL),
bool chained = false);
Blob(::bloblist_t *bl = ::new_bloblist(nullptr, 0, nullptr, nullptr), bool chained = false);
Blob(object data, string mime_type = "", string filename = "");
Blob(bp::object data, string mime_type = "", string filename = "");
Blob(const Blob &second);
@ -71,27 +56,27 @@ namespace pEp {
static int getbuffer(PyObject *self, Py_buffer *view, int flags);
};
Message(int dir = PEP_dir_outgoing, Identity *from = NULL);
Message(int dir = ::PEP_dir_outgoing, Identity *from = nullptr);
Message(string mimetext);
Message(const Message &second);
Message(message *msg);
Message(::message *msg);
~Message();
operator message *();
operator ::message *();
operator const message *() const;
operator const ::message *() const;
string _str();
string _repr();
PEP_msg_direction dir() { return _msg->dir; }
::PEP_msg_direction dir() { return _msg->dir; }
void dir(PEP_msg_direction value) { _msg->dir = value; }
void dir(::PEP_msg_direction value) { _msg->dir = value; }
string id() { return str_attr(_msg->id); }
@ -109,9 +94,9 @@ namespace pEp {
void longmsg_formatted(string value) { str_attr(_msg->longmsg_formatted, value); }
boost::python::tuple attachments();
bp::tuple attachments();
void attachments(boost::python::list value);
void attachments(bp::list value);
time_t sent() { return timestamp_attr(_msg->sent); }
@ -123,72 +108,72 @@ namespace pEp {
Identity from() { return identity_attr(_msg->from); }
void from(object value) { identity_attr(_msg->from, value); }
void from(bp::object value) { identity_attr(_msg->from, value); }
boost::python::list to() { return identitylist_attr(_msg->to); }
bp::list to() { return identitylist_attr(_msg->to); }
void to(boost::python::list value) { identitylist_attr(_msg->to, value); }
void to(bp::list value) { identitylist_attr(_msg->to, value); }
Identity recv_by() { return identity_attr(_msg->recv_by); }
void recv_by(object value) { identity_attr(_msg->recv_by, value); }
void recv_by(bp::object value) { identity_attr(_msg->recv_by, value); }
boost::python::list cc() { return identitylist_attr(_msg->cc); }
bp::list cc() { return identitylist_attr(_msg->cc); }
void cc(boost::python::list value) { identitylist_attr(_msg->cc, value); }
void cc(bp::list value) { identitylist_attr(_msg->cc, value); }
boost::python::list bcc() { return identitylist_attr(_msg->bcc); }
bp::list bcc() { return identitylist_attr(_msg->bcc); }
void bcc(boost::python::list value) { identitylist_attr(_msg->bcc, value); }
void bcc(bp::list value) { identitylist_attr(_msg->bcc, value); }
boost::python::list reply_to() { return identitylist_attr(_msg->reply_to); }
bp::list reply_to() { return identitylist_attr(_msg->reply_to); }
void reply_to(boost::python::list value) { identitylist_attr(_msg->reply_to, value); }
void reply_to(bp::list value) { identitylist_attr(_msg->reply_to, value); }
boost::python::list in_reply_to() { return strlist_attr(_msg->in_reply_to); }
bp::list in_reply_to() { return strlist_attr(_msg->in_reply_to); }
void in_reply_to(boost::python::list value) { strlist_attr(_msg->in_reply_to, value); }
void in_reply_to(bp::list value) { strlist_attr(_msg->in_reply_to, value); }
boost::python::list references() { return strlist_attr(_msg->references); }
bp::list references() { return strlist_attr(_msg->references); }
void references(boost::python::list value) { strlist_attr(_msg->references, value); }
void references(bp::list value) { strlist_attr(_msg->references, value); }
boost::python::list keywords() { return strlist_attr(_msg->keywords); }
bp::list keywords() { return strlist_attr(_msg->keywords); }
void keywords(boost::python::list value) { strlist_attr(_msg->keywords, value); }
void keywords(bp::list value) { strlist_attr(_msg->keywords, value); }
string comments() { return str_attr(_msg->comments); }
void comments(string value) { str_attr(_msg->comments, value); }
dict opt_fields() { return strdict_attr(_msg->opt_fields); }
bp::dict opt_fields() { return strdict_attr(_msg->opt_fields); }
void opt_fields(dict value) { return strdict_attr(_msg->opt_fields, value); }
void opt_fields(bp::dict value) { return strdict_attr(_msg->opt_fields, value); }
PEP_enc_format enc_format() { return _msg->enc_format; }
::PEP_enc_format enc_format() { return _msg->enc_format; }
void enc_format(PEP_enc_format value) { _msg->enc_format = value; }
void enc_format(::PEP_enc_format value) { _msg->enc_format = value; }
Message encrypt();
Message _encrypt(boost::python::list extra, int enc_format = 4, int flags = 0);
Message _encrypt(bp::list extra, int enc_format = 4, int flags = 0);
boost::python::tuple decrypt(int flags = 0);
bp::tuple decrypt(int flags = 0);
PEP_rating outgoing_rating();
::PEP_rating outgoing_rating();
PEP_color outgoing_color();
::PEP_color outgoing_color();
Message deepcopy(dict &memo);
Message deepcopy(bp::dict &memo);
Message copy();
};
};
Message outgoing_message(Identity me);
Message outgoing_message(Identity me);
Message incoming_message(string mime_text);
Message incoming_message(string mime_text);
} /* namespace PythonAdapter */
} /* namespace PythonAdapter */
} /* namespace pEp */
#endif /* MESSAGE_HH */

165
src/pEp/_pEp/message_api.cc

@ -1,161 +1,158 @@
// This file is under GNU Affero General Public License 3.0
// see LICENSE.txt
// Engine
#include <pEp/pEpEngine.h>
#include <pEp/message_api.h>
#include <pEp/sync_api.h>
#include <pEp/sync_codec.h>
#include <pEp/distribution_codec.h>
// local
#include "message_api.hh"
#include "basic_api.hh"
namespace pEp {
namespace PythonAdapter {
using namespace std;
using namespace boost::python;
namespace PythonAdapter {
Message encrypt_message(Message src, boost::python::list extra, int enc_format, int flags) {
Message encrypt_message(Message src, bp::list extra, int enc_format, int flags) {
Identity _from = src.from();
if (_from.address() == "")
if (_from.address() == "") {
throw invalid_argument("encrypt_message: src.from_.address empty");
if (_from.username() == "")
}
if (_from.username() == "") {
throw invalid_argument("encrypt_message: src.from_.username empty");
}
if (_from.user_id() == "")
if (_from.user_id() == "") {
src.from().user_id(_from.address());
}
stringlist_t *_extra = to_stringlist(extra);
PEP_enc_format _enc_format = (PEP_enc_format) enc_format;
PEP_encrypt_flags_t _flags = (PEP_encrypt_flags_t) flags;
message *_dst = NULL;
::stringlist_t *_extra = to_stringlist(extra);
::PEP_enc_format _enc_format = (::PEP_enc_format)enc_format;
::PEP_encrypt_flags_t _flags = (::PEP_encrypt_flags_t)flags;
::message *_dst = nullptr;
message *_src = src;
PEP_STATUS status = encrypt_message(Adapter::session(), _src, _extra, &_dst,
_enc_format, _flags);
free_stringlist(_extra);
::message *_src = src;
::PEP_STATUS status = ::encrypt_message(Adapter::session(), _src, _extra, &_dst, _enc_format, _flags);
::free_stringlist(_extra);
_throw_status(status);
if (!_dst || _dst == _src)
if (!_dst || _dst == _src) {
return Message(_src);
}
return Message(_dst);
}
}
boost::python::tuple decrypt_message(Message src, int flags) {
message *_dst = NULL;
stringlist_t *_keylist = NULL;
PEP_rating _rating = PEP_rating_undefined;
PEP_decrypt_flags_t _flags = (PEP_decrypt_flags_t) flags;
message *_src = src;
bp::tuple decrypt_message(Message src, int flags) {
::message *_dst = nullptr;
::stringlist_t *_keylist = nullptr;
::PEP_rating _rating = ::PEP_rating_undefined;
::PEP_decrypt_flags_t _flags = (::PEP_decrypt_flags_t)flags;
::message *_src = src;
PEP_STATUS status = ::decrypt_message(Adapter::session(), _src, &_dst, &_keylist,
&_rating, &_flags);
::PEP_STATUS status = ::decrypt_message(Adapter::session(), _src, &_dst, &_keylist, &_rating, &_flags);
_throw_status(status);
boost::python::list keylist;
bp::list keylist;
if (_keylist) {
keylist = from_stringlist(_keylist);
free_stringlist(_keylist);
::free_stringlist(_keylist);
}
Message dst = _dst ? Message(_dst) : Message(src);
return boost::python::make_tuple(dst, keylist, _rating, _flags);
}
return bp::make_tuple(dst, keylist, _rating, _flags);
}
PEP_color _color(int rating) {
return ::color_from_rating((PEP_rating) rating);
}
::PEP_color _color(int rating) {
return ::color_from_rating((::PEP_rating)rating);
}
boost::python::tuple sync_decode(object buffer) {
bp::tuple sync_decode(bp::object buffer) {
Py_buffer src;
int result = PyObject_GetBuffer(buffer.ptr(), &src, PyBUF_CONTIG_RO);
if (result)
if (result) {
throw invalid_argument("need a contiguous buffer to read");
}
char *dst = NULL;
PEP_STATUS status = PER_to_XER_Sync_msg((char *) src.buf, src.len, &dst);
char *dst = nullptr;
::PEP_STATUS status = ::PER_to_XER_Sync_msg((char *)src.buf, src.len, &dst);
PyBuffer_Release(&src);
_throw_status(status);
string _dst(dst);
free(dst);
return boost::python::make_tuple(_dst, 0);
}
return bp::make_tuple(_dst, 0);
}
static boost::python::tuple sync_encode(string text) {
char *data = NULL;
static bp::tuple sync_encode(string text) {
char *data = nullptr;
size_t size = 0;
PEP_STATUS status = XER_to_PER_Sync_msg(text.c_str(), &data, &size);
::PEP_STATUS status = ::XER_to_PER_Sync_msg(text.c_str(), &data, &size);
_throw_status(status);
PyObject *ba = PyBytes_FromStringAndSize(data, size);
PyObject * ba = PyBytes_FromStringAndSize(data, size);
free(data);
if (!ba)
if (!ba) {
throw bad_alloc();
return boost::python::make_tuple(object(handle<>(ba)), 0);
}
boost::python::tuple Distribution_decode(object buffer) {
return bp::make_tuple(bp::object(bp::handle<>(ba)), 0);
}
bp::tuple Distribution_decode(bp::object buffer) {
Py_buffer src;
int result = PyObject_GetBuffer(buffer.ptr(), &src, PyBUF_CONTIG_RO);
if (result)
if (result) {
throw invalid_argument("need a contiguous buffer to read");
}
char *dst = NULL;
PEP_STATUS status = PER_to_XER_Distribution_msg((char *) src.buf, src.len, &dst);
char *dst = nullptr;
::PEP_STATUS status = ::PER_to_XER_Distribution_msg((char *)src.buf, src.len, &dst);
PyBuffer_Release(&src);
_throw_status(status);
string _dst(dst);
free(dst);
return boost::python::make_tuple(_dst, 0);
}
return bp::make_tuple(_dst, 0);
}
static boost::python::tuple Distribution_encode(string text) {
char *data = NULL;
static bp::tuple Distribution_encode(string text) {
char *data = nullptr;
size_t size = 0;
PEP_STATUS status = XER_to_PER_Distribution_msg(text.c_str(), &data, &size);
::PEP_STATUS status = ::XER_to_PER_Distribution_msg(text.c_str(), &data, &size);
_throw_status(status);
PyObject *ba = PyBytes_FromStringAndSize(data, size);
PyObject * ba = PyBytes_FromStringAndSize(data, size);
free(data);
if (!ba)
if (!ba) {
throw bad_alloc();
return boost::python::make_tuple(object(handle<>(ba)), 0);
}
object sync_search(string name) {
return bp::make_tuple(bp::object(bp::handle<>(ba)), 0);
}
bp::object sync_search(string name) {
if (name != "pep.sync") {
return object();
return bp::object();
} else {
object codecs = import("codecs");
object CodecInfo = codecs.attr("CodecInfo");
bp::object codecs = bp::import("codecs");
bp::object CodecInfo = codecs.attr("CodecInfo");
object _sync_decode = make_function(sync_decode);
object _sync_encode = make_function(sync_encode);
bp::object _sync_decode = make_function(sync_decode);
bp::object _sync_encode = make_function(sync_encode);
return call<object>(CodecInfo.ptr(), _sync_encode, _sync_decode);
}
return bp::call<bp::object>(CodecInfo.ptr(), _sync_encode, _sync_decode);
}
}
object distribution_search(string name) {
bp::object distribution_search(string name) {
if (name != "pep.distribution") {
return object();
return bp::object();
} else {
object codecs = import("codecs");
object CodecInfo = codecs.attr("CodecInfo");
bp::object codecs = bp::import("codecs");
bp::object CodecInfo = codecs.attr("CodecInfo");
object _distribution_decode = make_function(Distribution_decode);
object _distribution_encode = make_function(Distribution_encode);
bp::object _distribution_decode = make_function(Distribution_decode);
bp::object _distribution_encode = make_function(Distribution_encode);
return call<object>(CodecInfo.ptr(), _distribution_encode, _distribution_decode);
}
return bp::call<bp::object>(CodecInfo.ptr(), _distribution_encode, _distribution_decode);
}
}
} // namespace PythonAdapter
} // namespace pEp {
} // namespace PythonAdapter
} // namespace pEp

22
src/pEp/_pEp/message_api.hh

@ -4,27 +4,23 @@
#ifndef MESSAGE_API_HH
#define MESSAGE_API_HH
#include "pEpmodule.hh"
#include "adapter_main.hh"
#include "message.hh"
namespace pEp {
namespace PythonAdapter {
namespace PythonAdapter {
Message encrypt_message(
Message src,
boost::python::list extra = boost::python::list(),
int enc_format = 4,
int flags = 0
);
Message encrypt_message(Message src, bp::list extra = bp::list(), int enc_format = 4, int flags = 0);
boost::python::tuple decrypt_message(Message src, int flags = 0);
bp::tuple decrypt_message(Message src, int flags = 0);
PEP_color _color(int rating);
::PEP_color _color(int rating);
object sync_search(string name);
bp::object sync_search(string name);
object distribution_search(string name);
bp::object distribution_search(string name);
} /* namespace PythonAdapter */
} /* namespace PythonAdapter */
} /* namespace pEp */
#endif /* MESSAGE_API_HH */

360
src/pEp/_pEp/pEpmodule.cc

@ -1,200 +1,37 @@
// This file is under GNU Affero General Public License 3.0
// see LICENSE.txt
// System
#include <boost/python.hpp>
#include <boost/locale.hpp>
#include <string>
#include <sstream>
#include <iomanip>
#include <mutex>
// Engine
#include <pEp/key_reset.h>
#include <pEp/message_api.h>
#include <pEp/sync_api.h>
#include <pEp/status_to_string.h>
// libpEpAdapter
#include <pEp/Adapter.hh>
#include <pEp/callback_dispatcher.hh>
#include <pEp/pEpLog.hh>
// local
#include "pEpmodule.hh"
#include "adapter_main.hh"
#include "basic_api.hh"
#include "message.hh"
#include "message_api.hh"
//#include "user_interface.hh"
namespace pEp {
namespace PythonAdapter {
using namespace std;
using namespace boost::python;
static const char *version_string = "p≡p Python adapter version 0.3";
void init_before_main_module() {
pEpLog("called");
}
// hidden init function, wrapped by hello_world.init()
void _init_after_main_module() {
pEpLog("called");
callback_dispatcher.add(_messageToSend, notifyHandshake, nullptr, nullptr);
Adapter::_messageToSend = CallbackDispatcher::messageToSend;
}
void config_passive_mode(bool enable) {
::config_passive_mode(Adapter::session(), enable);
}
void config_unencrypted_subject(bool enable) {
::config_unencrypted_subject(Adapter::session(), enable);
}
void key_reset_user(string user_id, string fpr) {
if (user_id == "")
throw invalid_argument("user_id required");
PEP_STATUS status = ::key_reset_user(Adapter::session(),
user_id.c_str(), fpr != "" ? fpr.c_str() : nullptr);
_throw_status(status);
}
void key_reset_user2(string user_id) {
key_reset_user(user_id, "");
}
void key_reset_all_own_keys() {
PEP_STATUS status = ::key_reset_all_own_keys(Adapter::session());
_throw_status(status);
}
static string about() {
string version = string(version_string) + "\np≡p version "
+ PEP_VERSION + "\n";
return version;
}
void _throw_status(PEP_STATUS status) {
if (status == PEP_STATUS_OK)
return;
if (status >= 0x400 && status <= 0x4ff)
return;
if (status == PEP_OUT_OF_MEMORY)
throw bad_alloc();
if (status == PEP_ILLEGAL_VALUE)
throw invalid_argument("illegal value");
if (string(pEp_status_to_string(status)) == "unknown status code") {
stringstream build;
build << setfill('0') << "p≡p 0x" << setw(4) << hex << status;
throw runtime_error(build.str());
} else {
throw runtime_error(pEp_status_to_string(status));
}
}
PEP_STATUS _messageToSend(::message *msg) {
pEpLog("called");
try {
PyGILState_STATE gil = PyGILState_Ensure();
pEpLog("GIL Aquired");
object modref = import("pEp");
object funcref = modref.attr("message_to_send");
call<void>(funcref.ptr(), Message());
PyGILState_Release(gil);
pEpLog("GIL released");
} catch (exception &e) {}
return PEP_STATUS_OK;
}
PEP_STATUS notifyHandshake(pEp_identity *me, pEp_identity *partner, sync_handshake_signal signal) {
pEpLog("called");
try {
PyGILState_STATE gil = PyGILState_Ensure();
pEpLog("GIL Aquired");
object modref = import("pEp");
object funcref = modref.attr("notify_handshake");
call<void>(funcref.ptr(), me, partner, signal);
PyGILState_Release(gil);
pEpLog("GIL released");
} catch (exception &e) {}
return PEP_STATUS_OK;
}
void start_sync() {
CallbackDispatcher::start_sync();
}
void shutdown_sync() {
CallbackDispatcher::stop_sync();
}
void debug_color(int ansi_color) {
::set_debug_color(Adapter::session(), ansi_color);
}
void leave_device_group() {
::leave_device_group(Adapter::session());
}
bool is_sync_active() {
return Adapter::is_sync_running();
}
void testfunc() {
_messageToSend(NULL);
}
void deliverHandshakeResult(int result, object identities) {
identity_list *shared_identities = nullptr;
if (identities != boost::python::api::object() && boost::python::len(identities)) {
shared_identities = new_identity_list(nullptr);
if (!shared_identities)
throw bad_alloc();
try {
identity_list *si = shared_identities;
for (int i = 0; i < boost::python::len(identities); ++i) {
Identity ident = extract<Identity>(identities[i]);
si = identity_list_add(si, ident);
if (!si)
throw bad_alloc();
}
}
catch (exception &ex) {
free_identity_list(shared_identities);
throw ex;
}
}
PEP_STATUS status = ::deliverHandshakeResult(Adapter::session(), (sync_handshake_result) result, shared_identities);
free_identity_list(shared_identities);
_throw_status(status);
}
BOOST_PYTHON_MODULE(_pEp) {
namespace PythonAdapter {
BOOST_PYTHON_MODULE(_pEp) {
using boost::python::def;
using boost::python::class_;
using boost::python::enum_;
init_before_main_module();
// Module init function called by pEp.init()
def("_init_after_main_module", _init_after_main_module);
def("testfunc", &testfunc);
docstring_options doc_options(true, false, false);
boost::locale::generator gen;
bp::docstring_options doc_options(true, false, false);
bl::generator gen;
std::locale::global(gen(""));
scope().attr("about") = about();
scope().attr("per_user_directory") = per_user_directory();
scope().attr("per_machine_directory") = per_machine_directory();
scope().attr("engine_version") = get_engine_version();
scope().attr("protocol_version") = get_protocol_version();
bp::scope().attr("about") = about();
bp::scope().attr("per_user_directory") = ::per_user_directory();
bp::scope().attr("per_machine_directory") = ::per_machine_directory();
bp::scope().attr("engine_version") = ::get_engine_version();
bp::scope().attr("protocol_version") = ::get_protocol_version();
def("passive_mode", config_passive_mode,
"do not attach pub keys to all messages");
@ -236,19 +73,19 @@ namespace pEp {
" lang ISO 639-1 language code for language being preferred\n"
" on this communication channel\n"
)
.def(boost::python::init<string>())
.def(boost::python::init<string, string>())
.def(boost::python::init<string, string, string>())
.def(boost::python::init<string, string, string, string>())
.def(boost::python::init<string, string, string, string, int>())
.def(boost::python::init<string, string, string, string, int, string>())
.def(bp::init<string>())
.def(bp::init<string, string>())
.def(bp::init<string, string, string>())
.def(bp::init<string, string, string, string>())
.def(bp::init<string, string, string, string, int>())
.def(bp::init<string, string, string, string, int, string>())
.def("__repr__", &Identity::_repr)
.def("__str__", &Identity::_str,
"string representation of this identity\n"
"following the pattern 'username < address >'\n"
)
.def("key_reset", &Identity::key_reset,
boost::python::arg("fpr")=object(""),
bp::arg("fpr")=bp::object(""),
"reset the default database status for the identity / keypair provided. If this\n"
"corresponds to the own user and a private key, also revoke the key, generate a\n"
"new one, and communicate the reset to recently contacted pEp partners for this\n"
@ -256,7 +93,7 @@ namespace pEp {
"completely fresh on next contact from the partner.")
.def("key_mistrusted", &Identity::key_mistrusted,
boost::python::arg("fpr")=object(""),
bp::arg("fpr")=bp::object(""),
"If you want updated trust on the identity, you ll have"
"to call update_identity or myself respectively after this."
"N.B. If you are calling this on a key that is the identity or user default,"
@ -287,13 +124,13 @@ namespace pEp {
.add_property("comm_type", (int(Identity::*)())
(PEP_comm_type(Identity::*)()) &Identity::comm_type,
(void(Identity::*)(int))
(void(Identity::*)(PEP_comm_type)) &Identity::comm_type,
(void(Identity::*)(::PEP_comm_type)) &Identity::comm_type,
"communication type, first rating level (p≡p internal)")
.add_property("lang", (string(Identity::*)()) &Identity::lang,
(void(Identity::*)(string)) &Identity::lang,
"ISO 639-1 language code")
.add_property("flags", (identity_flags_t(Identity::*)()) &Identity::flags,
(void(Identity::*)(identity_flags_t)) &Identity::flags,
(void(Identity::*)(::identity_flags_t)) &Identity::flags,
"flags (p≡p internal)")
.add_property("rating", &Identity::rating, "rating of Identity")
.add_property("color", &Identity::color, "color of Identity as PEP_color")
@ -312,9 +149,9 @@ namespace pEp {
" data bytes-like object\n"
" mime_type MIME type for the data\n"
" filename filename to store the data\n",
boost::python::init< object, char const*, char const* >(args("data", "mime_type", "filename")))
.def(boost::python::init<object, string>())
.def(boost::python::init<object>())
bp::init< bp::object, char const*, char const* >(bp::args("data", "mime_type", "filename")))
.def(bp::init<bp::object, string>())
.def(bp::init<bp::object>())
.def("__repr__", &Message::Blob::_repr)
.def("__len__", &Message::Blob::size, "size of Blob data in bytes")
.def("decode", (string(Message::Blob::*)()) &Message::Blob::decode)
@ -350,9 +187,9 @@ namespace pEp {
"\n"
" mime_text text in Multipurpose Internet Mail Extensions format\n"
)
.def(boost::python::init<int>())
.def(boost::python::init<int, Identity *>())
.def(boost::python::init<string>())
.def(bp::init<int>())
.def(bp::init<int, Identity *>())
.def(bp::init<string>())
.def("__str__", &Message::_str,
"the string representation of a Message is it's MIME text"
)
@ -360,7 +197,7 @@ namespace pEp {
.add_property("dir", (int(Message::*)())
(PEP_msg_direction(Message::*)()) &Message::dir,
(void(Message::*)(int))
(void(Message::*)(PEP_msg_direction)) &Message::dir,
(void(Message::*)(::PEP_msg_direction)) &Message::dir,
"0: incoming, 1: outgoing message")
.add_property("id", (string(Message::*)()) &Message::id,
(void(Message::*)(string)) &Message::id,
@ -374,8 +211,8 @@ namespace pEp {
.add_property("longmsg_formatted", (string(Message::*)()) &Message::longmsg_formatted,
(void(Message::*)(string)) &Message::longmsg_formatted,
"HTML body or fromatted long version of message")
.add_property("attachments", (boost::python::tuple(Message::*)()) &Message::attachments,
(void(Message::*)(boost::python::list)) &Message::attachments,
.add_property("attachments", (bp::tuple(Message::*)()) &Message::attachments,
(void(Message::*)(bp::list)) &Message::attachments,
"tuple of Blobs with attachments; setting moves Blobs to attachment tuple")
.add_property("sent", (time_t(Message::*)()) &Message::sent,
(void(Message::*)(time_t)) &Message::sent,
@ -384,47 +221,47 @@ namespace pEp {
(void(Message::*)(time_t)) &Message::recv,
"time when message was received in UTC seconds since epoch")
.add_property("from_", (Identity(Message::*)()) &Message::from,
(void(Message::*)(object)) &Message::from,
(void(Message::*)(bp::object)) &Message::from,
"identity where message is from")
.add_property("to", (boost::python::list(Message::*)()) &Message::to,
(void(Message::*)(boost::python::list)) &Message::to,
.add_property("to", (bp::list(Message::*)()) &Message::to,
(void(Message::*)(bp::list)) &Message::to,
"list of identities message is going to")
.add_property("recv_by", (Identity(Message::*)()) &Message::recv_by,
(void(Message::*)(object)) &Message::recv_by,
(void(Message::*)(bp::object)) &Message::recv_by,
"identity where message was received by")
.add_property("cc", (boost::python::list(Message::*)()) &Message::cc,
(void(Message::*)(boost::python::list)) &Message::cc,
.add_property("cc", (bp::list(Message::*)()) &Message::cc,
(void(Message::*)(bp::list)) &Message::cc,
"list of identities message is going cc")
.add_property("bcc", (boost::python::list(Message::*)()) &Message::bcc,
(void(Message::*)(boost::python::list)) &Message::bcc,
.add_property("bcc", (bp::list(Message::*)()) &Message::bcc,
(void(Message::*)(bp::list)) &Message::bcc,
"list of identities message is going bcc")
.add_property("reply_to", (boost::python::list(Message::*)()) &Message::reply_to,
(void(Message::*)(boost::python::list)) &Message::reply_to,
.add_property("reply_to", (bp::list(Message::*)()) &Message::reply_to,
(void(Message::*)(bp::list)) &Message::reply_to,
"list of identities where message will be replied to")
.add_property("in_reply_to", (boost::python::list(Message::*)()) &Message::in_reply_to,
(void(Message::*)(boost::python::list)) &Message::in_reply_to,
.add_property("in_reply_to", (bp::list(Message::*)()) &Message::in_reply_to,
(void(Message::*)(bp::list)) &Message::in_reply_to,
"in_reply_to list")
.add_property("references", (boost::python::list(Message::*)()) &Message::references,
(void(Message::*)(boost::python::list)) &Message::references,
.add_property("references", (bp::list(Message::*)()) &Message::references,
(void(Message::*)(bp::list)) &Message::references,
"message IDs of messages this one is referring to")
.add_property("keywords", (boost::python::list(Message::*)()) &Message::keywords,
(void(Message::*)(boost::python::list)) &Message::keywords,
.add_property("keywords", (bp::list(Message::*)()) &Message::keywords,
(void(Message::*)(bp::list)) &Message::keywords,
"keywords this message should be stored under")
.add_property("comments", (string(Message::*)()) &Message::comments,
(void(Message::*)(string)) &Message::comments,
"comments added to message")
.add_property("opt_fields", (dict(Message::*)()) &Message::opt_fields,
(void(Message::*)(dict)) &Message::opt_fields,
.add_property("opt_fields", (bp::dict(Message::*)()) &Message::opt_fields,
(void(Message::*)(bp::dict)) &Message::opt_fields,
"opt_fields of message")
.add_property("enc_format", (int(Message::*)())
(PEP_enc_format(Message::*)()) &Message::enc_format,
(void(Message::*)(int))
(void(Message::*)(PEP_enc_format)) &Message::enc_format,
(void(Message::*)(::PEP_enc_format)) &Message::enc_format,
"0: unencrypted, 1: inline PGP, 2: S/MIME, 3: PGP/MIME, 4: p≡p format")
.def("encrypt", (Message(Message::*)())&Message::encrypt)
.def("encrypt", (Message(Message::*)(boost::python::list))&Message::_encrypt)
.def("encrypt", (Message(Message::*)(boost::python::list, int))&Message::_encrypt)
.def("encrypt", (Message(Message::*)(boost::python::list, int, int))&Message::_encrypt,
.def("encrypt", (Message(Message::*)(bp::list))&Message::_encrypt)
.def("encrypt", (Message(Message::*)(bp::list, int))&Message::_encrypt)
.def("encrypt", (Message(Message::*)(bp::list, int, int))&Message::_encrypt,
"msg2 = msg1.encrypt(extra_keys=[], enc_format='pEp', flags=0)\n"
"\n"
"encrypts a p≡p message and returns the encrypted message\n"
@ -435,7 +272,7 @@ namespace pEp {
" 3 for PGP/MIME, 4 for pEp\n"
" flags 1 is force encryption\n"
)
.def("decrypt", &Message::decrypt, boost::python::arg("flags")=0,
.def("decrypt", &Message::decrypt, bp::arg("flags")=0,
"msg2, keys, rating, flags = msg1.decrypt()\n"
"\n"
"decrypts a p≡p message and returns a tuple with data\n"
@ -470,10 +307,10 @@ namespace pEp {
"mark a key as trusted with a person\n"
);
enum_<identity_flags>("identity_flags")
.value("PEP_idf_not_for_sync", PEP_idf_not_for_sync)
.value("PEP_idf_list", PEP_idf_list)
.value("PEP_idf_devicegroup", PEP_idf_devicegroup);
enum_<::identity_flags>("identity_flags")
.value("PEP_idf_not_for_sync", ::PEP_idf_not_for_sync)
.value("PEP_idf_list", ::PEP_idf_list)
.value("PEP_idf_devicegroup", ::PEP_idf_devicegroup);
def("set_identity_flags", &set_identity_flags,
"set_identity_flags(ident, flags)\n"
@ -529,25 +366,25 @@ namespace pEp {
// message API
enum_<PEP_rating>("rating")
.value("_undefined", PEP_rating_undefined)
.value("cannot_decrypt", PEP_rating_cannot_decrypt)
.value("have_no_key", PEP_rating_have_no_key)
.value("unencrypted", PEP_rating_unencrypted)
.value("unreliable", PEP_rating_unreliable)
.value("reliable", PEP_rating_reliable)
.value("trusted", PEP_rating_trusted)
.value("trusted_and_anonymized", PEP_rating_trusted_and_anonymized)
.value("fully_anonymous", PEP_rating_fully_anonymous)
.value("mistrust", PEP_rating_mistrust)
.value("b0rken", PEP_rating_b0rken)
.value("under_attack", PEP_rating_under_attack);
enum_<PEP_color>("colorvalue")
.value("no_color", PEP_color_no_color)
.value("yellow", PEP_color_yellow)
.value("green", PEP_color_green)
.value("red", PEP_color_red);
enum_<::PEP_rating>("rating")
.value("_undefined", ::PEP_rating_undefined)
.value("cannot_decrypt", ::PEP_rating_cannot_decrypt)
.value("have_no_key", ::PEP_rating_have_no_key)
.value("unencrypted", ::PEP_rating_unencrypted)
.value("unreliable", ::PEP_rating_unreliable)
.value("reliable", ::PEP_rating_reliable)
.value("trusted", ::PEP_rating_trusted)
.value("trusted_and_anonymized", ::PEP_rating_trusted_and_anonymized)
.value("fully_anonymous", ::PEP_rating_fully_anonymous)
.value("mistrust", ::PEP_rating_mistrust)
.value("b0rken", ::PEP_rating_b0rken)
.value("under_attack", ::PEP_rating_under_attack);
enum_<::PEP_color>("colorvalue")
.value("no_color", ::PEP_color_no_color)
.value("yellow", ::PEP_color_yellow)
.value("green", ::PEP_color_green)
.value("red", ::PEP_color_red);
def("incoming_message", &incoming_message,
@ -572,17 +409,17 @@ namespace pEp {
// Sync API
enum_<sync_handshake_signal>("sync_handshake_signal")
.value("SYNC_NOTIFY_UNDEFINED", SYNC_NOTIFY_UNDEFINED)
.value("SYNC_NOTIFY_INIT_ADD_OUR_DEVICE", SYNC_NOTIFY_INIT_ADD_OUR_DEVICE)
.value("SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE", SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE)
.value("SYNC_NOTIFY_INIT_FORM_GROUP", SYNC_NOTIFY_INIT_FORM_GROUP)
.value("SYNC_NOTIFY_TIMEOUT", SYNC_NOTIFY_TIMEOUT)
.value("SYNC_NOTIFY_ACCEPTED_DEVICE_ADDED", SYNC_NOTIFY_ACCEPTED_DEVICE_ADDED)
.value("SYNC_NOTIFY_ACCEPTED_GROUP_CREATED", SYNC_NOTIFY_ACCEPTED_GROUP_CREATED)
.value("SYNC_NOTIFY_ACCEPTED_DEVICE_ACCEPTED", SYNC_NOTIFY_ACCEPTED_DEVICE_ACCEPTED)
.value("SYNC_NOTIFY_SOLE", SYNC_NOTIFY_SOLE)
.value("SYNC_NOTIFY_IN_GROUP", SYNC_NOTIFY_IN_GROUP);
enum_<::sync_handshake_signal>("sync_handshake_signal")
.value("SYNC_NOTIFY_UNDEFINED", ::SYNC_NOTIFY_UNDEFINED)
.value("SYNC_NOTIFY_INIT_ADD_OUR_DEVICE", ::SYNC_NOTIFY_INIT_ADD_OUR_DEVICE)
.value("SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE", ::SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE)
.value("SYNC_NOTIFY_INIT_FORM_GROUP", ::SYNC_NOTIFY_INIT_FORM_GROUP)
.value("SYNC_NOTIFY_TIMEOUT", ::SYNC_NOTIFY_TIMEOUT)
.value("SYNC_NOTIFY_ACCEPTED_DEVICE_ADDED", ::SYNC_NOTIFY_ACCEPTED_DEVICE_ADDED)
.value("SYNC_NOTIFY_ACCEPTED_GROUP_CREATED", ::SYNC_NOTIFY_ACCEPTED_GROUP_CREATED)
.value("SYNC_NOTIFY_ACCEPTED_DEVICE_ACCEPTED", ::SYNC_NOTIFY_ACCEPTED_DEVICE_ACCEPTED)
.value("SYNC_NOTIFY_SOLE", ::SYNC_NOTIFY_SOLE)
.value("SYNC_NOTIFY_IN_GROUP", ::SYNC_NOTIFY_IN_GROUP);
// auto user_interface_class = class_<UserInterface, UserInterface_callback, boost::noncopyable>(
// "UserInterface",
@ -601,7 +438,7 @@ namespace pEp {
// "\n"
// "overwrite this method with an implementation of a handshake dialog")
// .def("deliverHandshakeResult", &UserInterface::deliverHandshakeResult,
// boost::python::arg("identities")=object(),
// bp::arg("identities")=object(),
// "deliverHandshakeResult(self, result, identities=None)\n"
// "\n"
// " result -1: cancel, 0: accepted, 1: rejected\n"
@ -610,7 +447,7 @@ namespace pEp {
// "call to deliver the handshake result of the handshake dialog"
// );
def("deliver_handshake_result", &deliverHandshakeResult, boost::python::arg("identities")=object(),
def("deliver_handshake_result", &deliverHandshakeResult, bp::arg("identities")=bp::object(),
"deliverHandshakeResult(self, result, identities=None)\n"
"\n"
" result -1: cancel, 0: accepted, 1: rejected\n"
@ -648,9 +485,8 @@ namespace pEp {
// codecs
call< object >(((object)(import("codecs").attr("register"))).ptr(), make_function(sync_search));
call< object >(((object)(import("codecs").attr("register"))).ptr(), make_function(distribution_search));
}
} // namespace PythonAdapter
bp::call< bp::object >(((bp::object)(bp::import("codecs").attr("register"))).ptr(), make_function(sync_search));
bp::call< bp::object >(((bp::object)(bp::import("codecs").attr("register"))).ptr(), make_function(distribution_search));
}
} // namespace PythonAdapter
} // namespace pEp

24
src/pEp/_pEp/pEpmodule.hh

@ -4,32 +4,12 @@
#ifndef PEPMODULE_HH
#define PEPMODULE_HH
// Engine
#include <pEp/pEpEngine.h>
// local
#include "message.hh"
namespace pEp {
namespace PythonAdapter {
extern string device_name;
void config_passive_mode(bool enable);
void config_unencrypted_subject(bool enable);
void key_reset_user(string user_id, string fpr);
void key_reset_all_own_keys();
void _throw_status(PEP_STATUS status);
PEP_STATUS _messageToSend(::message *msg);
namespace PythonAdapter {
PEP_STATUS notifyHandshake(pEp_identity *me, pEp_identity *partner, sync_handshake_signal signal);
} /* namespace PythonAdapter */
} /* namespace PythonAdapter */
} /* namespace pEp */
#endif /* PEPMODULE_HH */

138
src/pEp/_pEp/str_attr.cc

@ -1,81 +1,78 @@
// This file is under GNU Affero General Public License 3.0
// see LICENSE.txt
// System
#include <cstdlib>
#include <boost/python.hpp>
#include <boost/locale.hpp>
// local
#include "str_attr.hh"
namespace pEp {
namespace PythonAdapter {
using namespace std;
using namespace boost::python;
using namespace boost::locale;
namespace PythonAdapter {
object repr(object s) {
bp::object repr(bp::object s) {
return s.attr("__repr__")();
}
}
string repr(string s) {
str _s = s.c_str();
object _r = _s.attr("__repr__")();
string r = extract<string>(_r);
string repr(const string &s) {
bp::str _s = s.c_str();
bp::object _r = _s.attr("__repr__")();
string r = bp::extract<string>(_r);
return r;
}
}
string str_attr(char *&str) {
if (!str)
string str_attr(char *&str) {
if (!str) {
return string("");
return string(str);
}
return string(str);
}
void str_attr(char *&str, string value) {
string normalized = normalize(value, norm_nfc);
void str_attr(char *&str, const string &value) {
string normalized = normalize(value, bl::norm_nfc);
free(str);
str = strdup(normalized.c_str());
if (!str)
if (!str) {
throw bad_alloc();
}
}
time_t timestamp_attr(timestamp *&ts) {
if (!ts)
time_t timestamp_attr(::timestamp *&ts) {
if (!ts) {
return 0;
}
return timegm(ts);
}
}
void timestamp_attr(timestamp *&ts, time_t value) {
void timestamp_attr(::timestamp *&ts, time_t value) {
free_timestamp(ts);
ts = new_timestamp(value);
}
ts = ::new_timestamp(value);
}
boost::python::list strlist_attr(stringlist_t *&sl) {
boost::python::list result;
bp::list strlist_attr(::stringlist_t *&sl) {
bp::list result;
for (stringlist_t *_sl = sl; _sl && _sl->value; _sl = _sl->next) {
for (const ::stringlist_t *_sl = sl; _sl && _sl->value; _sl = _sl->next) {
string s(_sl->value);
result.append(object(s));
result.append(bp::object(s));
}
return result;
}
}
void strlist_attr(stringlist_t *&sl, boost::python::list value) {
stringlist_t *_sl = new_stringlist(NULL);
if (!_sl)
void strlist_attr(::stringlist_t *&sl, bp::list value) {
::stringlist_t *_sl = ::new_stringlist(NULL);
if (!_sl) {
throw bad_alloc();
}
stringlist_t *_s = _sl;
::stringlist_t *_s = _sl;
for (int i = 0; i < len(value); i++) {
extract <string> extract_string(value[i]);
bp::extract<string> extract_string(value[i]);
if (!extract_string.check()) {
free_stringlist(_sl);
}
string s = extract_string();
s = normalize(s, norm_nfc);
s = normalize(s, bl::norm_nfc);
_s = stringlist_add(_s, s.c_str());
if (!_s) {
free_stringlist(_sl);
@ -85,14 +82,13 @@ namespace pEp {
free_stringlist(sl);
sl = _sl;
}
}
dict strdict_attr(stringpair_list_t *&spl) {
dict result;
bp::dict strdict_attr(::stringpair_list_t *&spl) {
bp::dict result;
for (stringpair_list_t *_spl = spl; _spl && _spl->value; _spl =
_spl->next) {
stringpair_t *p = _spl->value;
for (::stringpair_list_t *_spl = spl; _spl && _spl->value; _spl = _spl->next) {
::stringpair_t *p = _spl->value;
if (p->key && p->value) {
string key(p->key);
string value(p->value);
@ -102,26 +98,28 @@ namespace pEp {
}
return result;
}
}
void strdict_attr(stringpair_list_t *&spl, dict value) {
stringpair_list_t *_spl = new_stringpair_list(NULL);
if (!_spl)
void strdict_attr(::stringpair_list_t *&spl, bp::dict value) {
::stringpair_list_t *_spl = ::new_stringpair_list(nullptr);
if (!_spl) {
throw bad_alloc();
}
stringpair_list_t *_s = _spl;
::stringpair_list_t *_s = _spl;
for (int i = 0; i < len(value); i++) {
extract <string> extract_key(value.keys()[i]);
extract <string> extract_value(value.values()[i]);
bp::extract<string> extract_key(value.keys()[i]);
bp::extract<string> extract_value(value.values()[i]);
if (!(extract_key.check() && extract_value.check()))
if (!(extract_key.check() && extract_value.check())) {
free_stringpair_list(_spl);
}
string key = extract_key();
key = normalize(key, norm_nfc);
key = normalize(key, bl::norm_nfc);
string _value = extract_value();
_value = normalize(_value, norm_nfc);
stringpair_t *pair = new_stringpair(key.c_str(), _value.c_str());
_value = normalize(_value, bl::norm_nfc);
::stringpair_t *pair = ::new_stringpair(key.c_str(), _value.c_str());
if (!pair) {
free_stringpair_list(_spl);
throw bad_alloc();
@ -135,18 +133,20 @@ namespace pEp {
free_stringpair_list(spl);
spl = _spl;
}
}
stringlist_t *to_stringlist(boost::python::list l) {
stringlist_t *result = new_stringlist(NULL);
if (!result)
::stringlist_t *to_stringlist(bp::list l) {
::stringlist_t *result = ::new_stringlist(nullptr);
if (!result) {
throw bad_alloc();
}
stringlist_t *_s = result;
::stringlist_t *_s = result;
for (int i = 0; i < len(l); i++) {
extract <string> extract_string(l[i]);
if (!extract_string.check())
bp::extract<string> extract_string(l[i]);
if (!extract_string.check()) {
free_stringlist(result);
}
string s = extract_string();
_s = stringlist_add(_s, s.c_str());
if (!_s) {
@ -156,17 +156,17 @@ namespace pEp {
}
return result;
}
}
boost::python::list from_stringlist(const stringlist_t *sl) {
boost::python::list result;
for (const stringlist_t *_sl = sl; _sl && _sl->value; _sl = _sl->next) {
bp::list from_stringlist(const ::stringlist_t *sl) {
bp::list result;
for (const ::stringlist_t *_sl = sl; _sl && _sl->value; _sl = _sl->next) {
string s = _sl->value;
result.append(s);
}
return result;
}
}
} // namespace PythonAdapter
} // namespace PythonAdapter
} // namespace pEp {

40
src/pEp/_pEp/str_attr.hh

@ -4,38 +4,34 @@
#ifndef STR_ATTR_HH
#define STR_ATTR_HH
// System
#include <string>
// Engine
#include <pEp/pEpEngine.h>
#include <pEp/timestamp.h>
#include <pEp/stringlist.h>
#include <pEp/stringpair.h>
#include "adapter_main.hh"
namespace pEp {
namespace PythonAdapter {
using std::string;
using boost::python::object;
using boost::python::dict;
object repr(object s);
string repr(string s);
bp::object repr(bp::object s);
string repr(const string &s);
string str_attr(char *&str);
void str_attr(char *&str, string value);
time_t timestamp_attr(timestamp *&ts);
void timestamp_attr(timestamp *&ts, time_t value);
void str_attr(char *&str, const string &value);
time_t timestamp_attr(::timestamp *&ts);
void timestamp_attr(::timestamp *&ts, time_t value);
bp::list strlist_attr(::stringlist_t *&sl);
void strlist_attr(::stringlist_t *&sl, bp::list value);
bp::dict strdict_attr(::stringpair_list_t *&spl);
boost::python::list strlist_attr(stringlist_t *&sl);
void strlist_attr(stringlist_t *&sl, boost::python::list value);
void strdict_attr(::stringpair_list_t *&spl, bp::dict value);
dict strdict_attr(stringpair_list_t *&spl);
void strdict_attr(stringpair_list_t *&spl, dict value);
::stringlist_t *to_stringlist(bp::list l);
stringlist_t *to_stringlist(boost::python::list l);
boost::python::list from_stringlist(const stringlist_t *sl);
bp::list from_stringlist(const ::stringlist_t *sl);
} /* namespace PythonAdapter */
} /* namespace pEp */

100
src/pEp/_pEp/user_interface.cc

@ -1,88 +1,83 @@
// This file is under GNU Affero General Public License 3.0
// see LICENSE.txt
// System
#include <cassert>
// local
#include "user_interface.hh"
namespace pEp {
namespace PythonAdapter {
using namespace std;
using namespace boost::python;
namespace PythonAdapter {
UserInterface *UserInterface::_ui = nullptr;
UserInterface *UserInterface::_ui = nullptr;
UserInterface::UserInterface() {
if (_ui)
UserInterface::UserInterface() {
if (_ui) {
throw runtime_error("only one UserInterface thread allowed");
_ui = this;
}
_ui = this;
}
UserInterface::~UserInterface() {
UserInterface::~UserInterface() {
_ui = nullptr;
}
UserInterface_callback::UserInterface_callback(PyObject *self)
: UserInterface(),
_self(self) {
// adapter.ui_object(self);
// ::PEP_STATUS status = ::register_sync_callbacks(Adapter::session(),
// (void *) this, _notifyHandshake, retrieve_next_sync_event);
// assert(status == ::PEP_STATUS_OK);
// if (status)
// _throw_status(status);
}
UserInterface_callback::~UserInterface_callback() {
// ::unregister_sync_callbacks(Adapter::session());
}
::PEP_STATUS UserInterface::_notifyHandshake(::pEp_identity *me, ::pEp_identity *partner, ::sync_handshake_signal signal) {
if (!(me && partner)) {
return ::PEP_ILLEGAL_VALUE;
}
UserInterface_callback::UserInterface_callback(PyObject *self) :
UserInterface(), _self(self) {
// adapter.ui_object(self);
// PEP_STATUS status = ::register_sync_callbacks(Adapter::session(),
// (void *) this, _notifyHandshake, retrieve_next_sync_event);
// assert(status == PEP_STATUS_OK);
// if (status)
// _throw_status(status);
}
UserInterface_callback::~UserInterface_callback() {
// ::unregister_sync_callbacks(Adapter::session());
}
PEP_STATUS UserInterface::_notifyHandshake(
pEp_identity *me, pEp_identity *partner,
sync_handshake_signal signal
) {
if (!(me && partner))
return PEP_ILLEGAL_VALUE;
auto that = dynamic_cast< UserInterface_callback * >(_ui);
that->notifyHandshake(Identity(me), Identity(partner), signal);
return PEP_STATUS_OK;
}
return ::PEP_STATUS_OK;
}
void UserInterface::deliverHandshakeResult(int result, object identities) {
void UserInterface::deliverHandshakeResult(int result, bp::object identities) {
identity_list *shared_identities = nullptr;
if (identities != boost::python::api::object() && boost::python::len(identities)) {
if (identities != bp::api::object() && bp::len(identities)) {
shared_identities = new_identity_list(nullptr);
if (!shared_identities)
if (!shared_identities) {
throw bad_alloc();
}
try {
identity_list *si = shared_identities;
for (int i = 0; i < boost::python::len(identities); ++i) {
Identity ident = extract<Identity>(identities[i]);
for (int i = 0; i < bp::len(identities); ++i) {
Identity ident = bp::extract<Identity>(identities[i]);
si = identity_list_add(si, ident);
if (!si)
if (!si) {
throw bad_alloc();
}
}
catch (exception &ex) {
} catch (exception &ex) {
free_identity_list(shared_identities);
throw ex;
}
}
PEP_STATUS status = ::deliverHandshakeResult(Adapter::session(),
(sync_handshake_result) result, shared_identities);
::PEP_STATUS status = ::deliverHandshakeResult(Adapter::session(), (sync_handshake_result)result, shared_identities);
free_identity_list(shared_identities);
_throw_status(status);
}
}
//PEP_rating UserInterface::get_key_rating_for_user(string user_id, string fpr)
//{
// PEP_rating result;
// PEP_STATUS status =
// ::PEP_STATUS status =
// ::get_key_rating_for_user(Adapter::session(),
// user_id.c_str(), fpr.c_str(), &result);
// _throw_status(status);
@ -104,7 +99,7 @@ namespace pEp {
// }
// i = 0;
// }
// nanosleep((const struct timespec[]){{0, 100000000L}}, NULL);
// nanosleep((const struct timespec[]){{0, 100000000L}}, nullptr);
// }
//
// if (timeout)
@ -113,11 +108,10 @@ namespace pEp {
// return adapter.queue().pop_front();
//}
void UserInterface_callback::notifyHandshake(
Identity me, Identity partner, sync_handshake_signal signal) {
call_method<void>(_self, "notifyHandshake", me, partner, signal);
}
void UserInterface_callback::notifyHandshake(Identity me, Identity partner, sync_handshake_signal signal) {
bp::call_method<void>(_self, "notifyHandshake", me, partner, signal);
}
} // namespace PythonAdapter
} // namespace pEp {
} // namespace PythonAdapter
} // namespace pEp

42
src/pEp/_pEp/user_interface.hh

@ -4,57 +4,41 @@
#ifndef USER_INTERFACE_HH
#define USER_INTERFACE_HH
// System
#include <csetjmp>
// Engine
#include <pEp/sync_api.h>
#include <pEp/message_api.h>
// local
#include "pEpmodule.hh"
#include "adapter_main.hh"
#include "identity.hh"
namespace pEp {
namespace PythonAdapter {
namespace PythonAdapter {
class UserInterface {
class UserInterface {
static UserInterface *_ui;
public:
UserInterface();
virtual ~UserInterface();
virtual void notifyHandshake(
Identity me,
Identity partner,
sync_handshake_signal signal) {
virtual void notifyHandshake(Identity me, Identity partner, ::sync_handshake_signal signal) {
throw runtime_error("override this method");
}
virtual void deliverHandshakeResult(int result, object identities);
virtual void deliverHandshakeResult(int result, bp::object identities);
// PEP_rating get_key_rating_for_user(string user_id, string fpr);
// PEP_rating get_key_rating_for_user(string user_id, string fpr);
protected:
static PEP_STATUS _notifyHandshake(pEp_identity *me, pEp_identity *partner, sync_handshake_signal signal);
};
static ::PEP_STATUS _notifyHandshake(::pEp_identity *me, ::pEp_identity *partner, ::sync_handshake_signal signal);
};
class UserInterface_callback : public UserInterface {
class UserInterface_callback : public UserInterface {
PyObject *_self;
public:
UserInterface_callback(PyObject *self);
~UserInterface_callback();
void notifyHandshake(
Identity me,
Identity partner,
sync_handshake_signal signal
);
};
void notifyHandshake(Identity me, Identity partner, sync_handshake_signal signal);
};
} /* namespace PythonAdapter */
} /* namespace PythonAdapter */
} /* namespace pEp */
#endif /* USER_INTERFACE_HH */

Loading…
Cancel
Save