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 .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 .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 all: dist
# Install pEpACIDgen from local repo clone, not from pypi
install-pepacidgen:
pip3 install -r requirements.txt --find-links ../pEpACIDgen/dist
# Build # Build
# ===== # =====
compile: gen: install-pepacidgen
$(MAKE) -C src/pEp/_gen gen
compile: gen
python3 setup.py build_ext $(DEBUG_OPT) $(PREFIX_OPT) python3 setup.py build_ext $(DEBUG_OPT) $(PREFIX_OPT)
compile-inplace: compile-inplace: gen
python3 setup.py build_ext $(DEBUG_OPT) $(PREFIX_OPT) --inplace python3 setup.py build_ext $(DEBUG_OPT) $(PREFIX_OPT) --inplace
# Packaging # Packaging
@ -57,8 +65,6 @@ envtest:
install-test: compile install-test: compile
pip3 install .[test] pip3 install .[test]
# TODO: maybe use setup.py test?
# --forked, because every test needs a separate process, see PYADPT-100
test: test:
pytest pytest
@ -80,6 +86,7 @@ clean-all: clean
rm -rf $(VENV_DIR) rm -rf $(VENV_DIR)
clean: clean-docs clean: clean-docs
$(MAKE) -C src/pEp/_gen clean-all
rm -rf $(BUILD_DIR) rm -rf $(BUILD_DIR)
rm -rf $(DIST_DIR) rm -rf $(DIST_DIR)
rm -rf $(PYTHON_ARTIFACTS) rm -rf $(PYTHON_ARTIFACTS)
@ -88,3 +95,14 @@ clean: clean-docs
clean-docs: clean-docs:
make clean -C 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 DIST_DIR = ./dist
VERSION_FILE = ./src/pEp/__version__.py VERSION_FILE = ./src/pEp/__version__.py
BUILD_INPLACE = ./src/pEp/_pEp.cpython-38-darwin.so BUILD_INPLACE = ./src/pEp/_pEp.cpython-38-darwin.so
BUILD_INPLACE += ./src/pEp/_gen.cpython-38-darwin.so
PYTHON_ARTIFACTS += ./.eggs PYTHON_ARTIFACTS += ./.eggs
PYTHON_ARTIFACTS += ./src/pEp.egg-info PYTHON_ARTIFACTS += ./src/pEp.egg-info
PYTHON_ARTIFACTS += ./.pytest_cache 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 pEp
=========== ----------
Module contents
---------------
.. automodule:: pEp .. automodule:: pEp
:members: :members:
:imported-members: :imported-members:
:undoc-members: :undoc-members:
:show-inheritance: :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, # 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, # relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css". # 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 # Custom sidebar templates, must be a dictionary that maps document names
# to template names. # to template names.

3
docs/source/index.rst

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

3
pyproject.toml

@ -5,7 +5,8 @@
requires =[ requires =[
"setuptools >=39.2.0", "setuptools >=39.2.0",
"setuptools_scm >= 4.1.2", "setuptools_scm >= 4.1.2",
"wheel >= 0.35.1" ] "wheel >= 0.35.1",
"pybind11 >= 2.6.2" ]
build-backend = "setuptools.build_meta" 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 >=39.2.0
setuptools_scm >= 4.1.2 setuptools_scm >= 4.1.2
wheel >= 0.35.1 wheel >= 0.35.1
pybind11 >= 2.6.2
[options.extras_require] [options.extras_require]
# To install these dependencies, run pip install .[test] # To install these dependencies, run pip install .[test]
test = test =

20
setup.py

@ -7,7 +7,6 @@
from __future__ import print_function from __future__ import print_function
import sys import sys
import os import os
from os import environ from os import environ
from os.path import join from os.path import join
@ -174,6 +173,14 @@ class BuildExtCommand(build_ext):
module_pEp.libraries = libs module_pEp.libraries = libs
module_pEp.extra_compile_args = compile_flags 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("Include Dirs:", module_pEp.include_dirs)
pEpLog("Libs Dirs:", module_pEp.library_dirs) pEpLog("Libs Dirs:", module_pEp.library_dirs)
pEpLog("Libraries:", module_pEp.libraries) pEpLog("Libraries:", module_pEp.libraries)
@ -195,6 +202,7 @@ if sys.version_info[0] < 3:
module_pEp = Extension( module_pEp = Extension(
'pEp._pEp', 'pEp._pEp',
sources=[ sources=[
'src/pEp/_pEp/adapter_main.cc',
'src/pEp/_pEp/pEpmodule.cc', 'src/pEp/_pEp/pEpmodule.cc',
'src/pEp/_pEp/basic_api.cc', 'src/pEp/_pEp/basic_api.cc',
'src/pEp/_pEp/identity.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 # "MAIN" Function
setup( setup(
package_dir={'': 'src'}, package_dir={'': 'src'},
packages=['pEp'], packages=['pEp'],
ext_modules=[module_pEp], ext_modules=[module_pEp, module_gen],
cmdclass={ cmdclass={
'build_ext': BuildExtCommand, '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 # Imports all symbols EXCEPT the ones beginning with underscore
from ._pEp import * from ._pEp import *
from ._gen import *
# import the native module into the current namespace because we also need to access the names beginning # 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 # with an underscore (of _pEp), but we dont want to import them into this module
import pEp._pEp import pEp._pEp
import pEp._gen
# Executed on module import # Executed on module import
def init(): 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 // This file is under GNU Affero General Public License 3.0
// see LICENSE.txt // 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" #include "basic_api.hh"
namespace pEp { namespace pEp {
namespace PythonAdapter { namespace PythonAdapter {
using namespace std;
void update_identity(Identity &ident) { void update_identity(Identity &ident) {
if (ident.address() == "") if (ident.address() == "") {
throw invalid_argument("address needed"); 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) { void myself(Identity &ident) {
if (ident.address() == "") if (ident.address() == "") {
throw invalid_argument("address needed"); throw invalid_argument("address needed");
if (ident.username() == "") }
if (ident.username() == "") {
throw invalid_argument("username needed"); throw invalid_argument("username needed");
}
if (ident.user_id() == "") if (ident.user_id() == "") {
ident.user_id(ident.address()); 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) { string _trustwords(Identity me, Identity partner, string lang, bool full) {
if (me.fpr() == "" || partner.fpr() == "") if (me.fpr() == "" || partner.fpr() == "") {
throw invalid_argument("fingerprint needed in Identities"); throw invalid_argument("fingerprint needed in Identities");
}
if (lang == "" && me.lang() == partner.lang()) if (lang == "" && me.lang() == partner.lang()) {
lang = me.lang(); lang = me.lang();
}
char *words = NULL; char *words = nullptr;
size_t size = 0; size_t size = 0;
PEP_STATUS status = get_trustwords(Adapter::session(), me, partner, ::PEP_STATUS status = ::get_trustwords(Adapter::session(), me, partner, lang.c_str(), &words, &size, full);
lang.c_str(), &words, &size, full);
_throw_status(status); _throw_status(status);
return words; return words;
} }
void trust_personal_key(Identity ident) { void trust_personal_key(Identity ident) {
if (ident.fpr() == "") if (ident.fpr() == "") {
throw invalid_argument("fingerprint needed in Identities"); throw invalid_argument("fingerprint needed in Identities");
if (ident.user_id() == "") }
if (ident.user_id() == "") {
throw invalid_argument("user_id must be provided"); 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) { void set_identity_flags(Identity ident,const ::identity_flags_t &flags) {
if (ident.address() == "") if (ident.address() == "") {
throw invalid_argument("address needed"); throw invalid_argument("address needed");
if (ident.user_id() == "") }
if (ident.user_id() == "") {
throw invalid_argument("user_id needed"); 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) { void unset_identity_flags(Identity ident,const ::identity_flags_t &flags) {
if (ident.address() == "") if (ident.address() == "") {
throw invalid_argument("address needed"); throw invalid_argument("address needed");
if (ident.user_id() == "") }
if (ident.user_id() == "") {
throw invalid_argument("user_id needed"); 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) { void key_reset_trust(Identity ident) {
if (ident.fpr() == "") if (ident.fpr() == "") {
throw invalid_argument("fpr needed"); throw invalid_argument("fpr needed");
if (ident.address() == "") }
if (ident.address() == "") {
throw invalid_argument("address needed"); throw invalid_argument("address needed");
if (ident.user_id() == "") }
if (ident.user_id() == "") {
throw invalid_argument("user_id needed"); throw invalid_argument("user_id needed");
PEP_STATUS status = key_reset_trust(Adapter::session(), ident);
_throw_status(status);
} }
::PEP_STATUS status = ::key_reset_trust(Adapter::session(), ident);
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)
_throw_status(status); _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) { for (::identity_list *il = private_keys; il && il->ident; il = il->next) {
::pEp_identity *ident = ::identity_dup(il->ident); ::pEp_identity *ident = ::identity_dup(il->ident);
if (!ident) { if (!ident) {
free_identity_list(private_keys); ::free_identity_list(private_keys);
throw bad_alloc(); throw bad_alloc();
} }
result.append(Identity(ident)); result.append(Identity(ident));
} }
::free_identity_list(private_keys);
free_identity_list(private_keys);
return result; return result;
} }
string export_key(Identity ident) { string export_key(Identity ident) {
PEP_STATUS status = PEP_STATUS_OK; ::PEP_STATUS status = ::PEP_STATUS_OK;
char *key_data = NULL; char *key_data = nullptr;
size_t size; size_t size;
status = ::export_key(Adapter::session(), ident.fpr().c_str(), &key_data, &size); status = ::export_key(Adapter::session(), ident.fpr().c_str(), &key_data, &size);
_throw_status(status); _throw_status(status);
return key_data; return key_data;
} }
string export_secret_key(Identity ident) { string export_secret_key(Identity ident) {
PEP_STATUS status = PEP_STATUS_OK; ::PEP_STATUS status = ::PEP_STATUS_OK;
char *key_data = NULL; char *key_data = NULL;
size_t size; size_t size;
status = ::export_secret_key(Adapter::session(), ident.fpr().c_str(), &key_data, &size); status = ::export_secret_key(Adapter::session(), ident.fpr().c_str(), &key_data, &size);
_throw_status(status); _throw_status(status);
return key_data; return key_data;
} }
void set_own_key(Identity &ident, string fpr) { void set_own_key(Identity &ident, const string &fpr) {
if (ident.address() == "") if (ident.address() == "") {
throw invalid_argument("address needed"); throw invalid_argument("address needed");
if (ident.username() == "") }
if (ident.username() == "") {
throw invalid_argument("username needed"); throw invalid_argument("username needed");
if (ident.user_id() == "") }
if (ident.user_id() == "") {
throw invalid_argument("user_id needed"); throw invalid_argument("user_id needed");
if (fpr == "") }
if (fpr == "") {
throw invalid_argument("fpr needed"); throw invalid_argument("fpr needed");
}
const char *fpr_c = fpr.c_str(); 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); _throw_status(status);
} }
} // namespace PythonAdapter
} // namespace PythonAdapter
} // namespace pEp } // namespace pEp

29
src/pEp/_pEp/basic_api.hh

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

60
src/pEp/_pEp/identity.hh

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

320
src/pEp/_pEp/message.cc

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

101
src/pEp/_pEp/message.hh

@ -4,29 +4,15 @@
#ifndef MESSAGE_HH #ifndef MESSAGE_HH
#define MESSAGE_HH #define MESSAGE_HH
// System #include "adapter_main.hh"
#include <string>
#include <boost/python.hpp>
#include <boost/lexical_cast.hpp>
// Engine
#include <pEp/message.h>
#include <pEp/message_api.h>
// local
#include "str_attr.hh" #include "str_attr.hh"
#include "identity.hh" #include "identity.hh"
namespace pEp { namespace pEp {
namespace PythonAdapter { namespace PythonAdapter {
using std::string;
using std::runtime_error;
using std::invalid_argument;
using boost::lexical_cast;
// Message is owning a message struct // Message is owning a message struct
class Message {
class Message {
shared_ptr<::message> _msg; shared_ptr<::message> _msg;
public: public:
@ -34,14 +20,13 @@ namespace pEp {
// one depending on part_of_chain // one depending on part_of_chain
class Blob { class Blob {
bloblist_t *_bl; ::bloblist_t *_bl;
bool part_of_chain; bool part_of_chain;
public: public:
Blob(bloblist_t *bl = new_bloblist(NULL, 0, NULL, NULL), Blob(::bloblist_t *bl = ::new_bloblist(nullptr, 0, nullptr, nullptr), bool chained = false);
bool chained = false);
Blob(object data, string mime_type = "", string filename = ""); Blob(bp::object data, string mime_type = "", string filename = "");
Blob(const Blob &second); Blob(const Blob &second);
@ -71,27 +56,27 @@ namespace pEp {
static int getbuffer(PyObject *self, Py_buffer *view, int flags); 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(string mimetext);
Message(const Message &second); Message(const Message &second);
Message(message *msg); Message(::message *msg);
~Message(); ~Message();
operator message *(); operator ::message *();
operator const message *() const; operator const ::message *() const;
string _str(); string _str();
string _repr(); 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); } string id() { return str_attr(_msg->id); }
@ -109,9 +94,9 @@ namespace pEp {
void longmsg_formatted(string value) { str_attr(_msg->longmsg_formatted, value); } 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); } time_t sent() { return timestamp_attr(_msg->sent); }
@ -123,72 +108,72 @@ namespace pEp {
Identity from() { return identity_attr(_msg->from); } 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); } 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); } string comments() { return str_attr(_msg->comments); }
void comments(string value) { str_attr(_msg->comments, value); } 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();
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 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 */ } /* namespace pEp */
#endif /* MESSAGE_HH */ #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 // This file is under GNU Affero General Public License 3.0
// see LICENSE.txt // 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 // local
#include "message_api.hh" #include "message_api.hh"
#include "basic_api.hh"
namespace pEp { namespace pEp {
namespace PythonAdapter { namespace PythonAdapter {
using namespace std;
using namespace boost::python;
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(); Identity _from = src.from();
if (_from.address() == "") if (_from.address() == "") {
throw invalid_argument("encrypt_message: src.from_.address empty"); throw invalid_argument("encrypt_message: src.from_.address empty");
if (_from.username() == "") }
if (_from.username() == "") {
throw invalid_argument("encrypt_message: src.from_.username empty"); throw invalid_argument("encrypt_message: src.from_.username empty");
}
if (_from.user_id() == "") if (_from.user_id() == "") {
src.from().user_id(_from.address()); src.from().user_id(_from.address());
}
stringlist_t *_extra = to_stringlist(extra); ::stringlist_t *_extra = to_stringlist(extra);
PEP_enc_format _enc_format = (PEP_enc_format) enc_format; ::PEP_enc_format _enc_format = (::PEP_enc_format)enc_format;
PEP_encrypt_flags_t _flags = (PEP_encrypt_flags_t) flags; ::PEP_encrypt_flags_t _flags = (::PEP_encrypt_flags_t)flags;
message *_dst = NULL; ::message *_dst = nullptr;
message *_src = src; ::message *_src = src;
PEP_STATUS status = encrypt_message(Adapter::session(), _src, _extra, &_dst, ::PEP_STATUS status = ::encrypt_message(Adapter::session(), _src, _extra, &_dst, _enc_format, _flags);
_enc_format, _flags); ::free_stringlist(_extra);
free_stringlist(_extra);
_throw_status(status); _throw_status(status);
if (!_dst || _dst == _src) if (!_dst || _dst == _src) {
return Message(_src); return Message(_src);
}
return Message(_dst); return Message(_dst);
} }
boost::python::tuple decrypt_message(Message src, int flags) { bp::tuple decrypt_message(Message src, int flags) {
message *_dst = NULL; ::message *_dst = nullptr;
stringlist_t *_keylist = NULL; ::stringlist_t *_keylist = nullptr;
PEP_rating _rating = PEP_rating_undefined; ::PEP_rating _rating = ::PEP_rating_undefined;
PEP_decrypt_flags_t _flags = (PEP_decrypt_flags_t) flags; ::PEP_decrypt_flags_t _flags = (::PEP_decrypt_flags_t)flags;
message *_src = src; ::message *_src = src;
PEP_STATUS status = ::decrypt_message(Adapter::session(), _src, &_dst, &_keylist, ::PEP_STATUS status = ::decrypt_message(Adapter::session(), _src, &_dst, &_keylist, &_rating, &_flags);
&_rating, &_flags);
_throw_status(status); _throw_status(status);
boost::python::list keylist; bp::list keylist;
if (_keylist) { if (_keylist) {
keylist = from_stringlist(_keylist); keylist = from_stringlist(_keylist);
free_stringlist(_keylist); ::free_stringlist(_keylist);
} }
Message dst = _dst ? Message(_dst) : Message(src); 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) { ::PEP_color _color(int rating) {
return ::color_from_rating((PEP_rating) 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; Py_buffer src;
int result = PyObject_GetBuffer(buffer.ptr(), &src, PyBUF_CONTIG_RO); int result = PyObject_GetBuffer(buffer.ptr(), &src, PyBUF_CONTIG_RO);
if (result) if (result) {
throw invalid_argument("need a contiguous buffer to read"); throw invalid_argument("need a contiguous buffer to read");
}
char *dst = NULL; char *dst = nullptr;
PEP_STATUS status = PER_to_XER_Sync_msg((char *) src.buf, src.len, &dst); ::PEP_STATUS status = ::PER_to_XER_Sync_msg((char *)src.buf, src.len, &dst);
PyBuffer_Release(&src); PyBuffer_Release(&src);
_throw_status(status); _throw_status(status);
string _dst(dst); string _dst(dst);
free(dst); free(dst);
return boost::python::make_tuple(_dst, 0); return bp::make_tuple(_dst, 0);
} }
static boost::python::tuple sync_encode(string text) { static bp::tuple sync_encode(string text) {
char *data = NULL; char *data = nullptr;
size_t size = 0; 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); _throw_status(status);
PyObject *ba = PyBytes_FromStringAndSize(data, size); PyObject * ba = PyBytes_FromStringAndSize(data, size);
free(data); free(data);
if (!ba) if (!ba) {
throw bad_alloc(); 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; Py_buffer src;
int result = PyObject_GetBuffer(buffer.ptr(), &src, PyBUF_CONTIG_RO); int result = PyObject_GetBuffer(buffer.ptr(), &src, PyBUF_CONTIG_RO);
if (result) if (result) {
throw invalid_argument("need a contiguous buffer to read"); throw invalid_argument("need a contiguous buffer to read");
}
char *dst = NULL; char *dst = nullptr;
PEP_STATUS status = PER_to_XER_Distribution_msg((char *) src.buf, src.len, &dst); ::PEP_STATUS status = ::PER_to_XER_Distribution_msg((char *)src.buf, src.len, &dst);
PyBuffer_Release(&src); PyBuffer_Release(&src);
_throw_status(status); _throw_status(status);
string _dst(dst); string _dst(dst);
free(dst); free(dst);
return boost::python::make_tuple(_dst, 0); return bp::make_tuple(_dst, 0);
} }
static boost::python::tuple Distribution_encode(string text) { static bp::tuple Distribution_encode(string text) {
char *data = NULL; char *data = nullptr;
size_t size = 0; 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); _throw_status(status);
PyObject *ba = PyBytes_FromStringAndSize(data, size); PyObject * ba = PyBytes_FromStringAndSize(data, size);
free(data); free(data);
if (!ba) if (!ba) {
throw bad_alloc(); 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") { if (name != "pep.sync") {
return object(); return bp::object();
} else { } else {
object codecs = import("codecs"); bp::object codecs = bp::import("codecs");
object CodecInfo = codecs.attr("CodecInfo"); bp::object CodecInfo = codecs.attr("CodecInfo");
object _sync_decode = make_function(sync_decode); bp::object _sync_decode = make_function(sync_decode);
object _sync_encode = make_function(sync_encode); 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") { if (name != "pep.distribution") {
return object(); return bp::object();
} else { } else {
object codecs = import("codecs"); bp::object codecs = bp::import("codecs");
object CodecInfo = codecs.attr("CodecInfo"); bp::object CodecInfo = codecs.attr("CodecInfo");
object _distribution_decode = make_function(Distribution_decode); bp::object _distribution_decode = make_function(Distribution_decode);
object _distribution_encode = make_function(Distribution_encode); 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 PythonAdapter
} // namespace pEp { } // namespace pEp

22
src/pEp/_pEp/message_api.hh

@ -4,27 +4,23 @@
#ifndef MESSAGE_API_HH #ifndef MESSAGE_API_HH
#define MESSAGE_API_HH #define MESSAGE_API_HH
#include "pEpmodule.hh" #include "adapter_main.hh"
#include "message.hh"
namespace pEp { namespace pEp {
namespace PythonAdapter { namespace PythonAdapter {
Message encrypt_message( Message encrypt_message(Message src, bp::list extra = bp::list(), int enc_format = 4, int flags = 0);
Message src,
boost::python::list extra = boost::python::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 */ } /* namespace pEp */
#endif /* MESSAGE_API_HH */ #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 // This file is under GNU Affero General Public License 3.0
// see LICENSE.txt // 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 // local
#include "pEpmodule.hh" #include "adapter_main.hh"
#include "basic_api.hh" #include "basic_api.hh"
#include "message.hh"
#include "message_api.hh" #include "message_api.hh"
//#include "user_interface.hh"
namespace pEp { namespace pEp {
namespace PythonAdapter { namespace PythonAdapter {
using namespace std;
using namespace boost::python;
BOOST_PYTHON_MODULE(_pEp) {
static const char *version_string = "p≡p Python adapter version 0.3"; using boost::python::def;
using boost::python::class_;
void init_before_main_module() { using boost::python::enum_;
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) {
init_before_main_module(); init_before_main_module();
// Module init function called by pEp.init() // Module init function called by pEp.init()
def("_init_after_main_module", _init_after_main_module); def("_init_after_main_module", _init_after_main_module);
def("testfunc", &testfunc); def("testfunc", &testfunc);
docstring_options doc_options(true, false, false); bp::docstring_options doc_options(true, false, false);
boost::locale::generator gen; bl::generator gen;
std::locale::global(gen("")); std::locale::global(gen(""));
scope().attr("about") = about(); bp::scope().attr("about") = about();
scope().attr("per_user_directory") = per_user_directory(); bp::scope().attr("per_user_directory") = ::per_user_directory();
scope().attr("per_machine_directory") = per_machine_directory(); bp::scope().attr("per_machine_directory") = ::per_machine_directory();
scope().attr("engine_version") = get_engine_version(); bp::scope().attr("engine_version") = ::get_engine_version();
scope().attr("protocol_version") = get_protocol_version(); bp::scope().attr("protocol_version") = ::get_protocol_version();
def("passive_mode", config_passive_mode, def("passive_mode", config_passive_mode,
"do not attach pub keys to all messages"); "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" " lang ISO 639-1 language code for language being preferred\n"
" on this communication channel\n" " on this communication channel\n"
) )
.def(boost::python::init<string>()) .def(bp::init<string>())
.def(boost::python::init<string, string>()) .def(bp::init<string, string>())
.def(boost::python::init<string, string, string>()) .def(bp::init<string, string, string>())
.def(boost::python::init<string, string, string, string>()) .def(bp::init<string, string, string, string>())
.def(boost::python::init<string, string, string, string, int>()) .def(bp::init<string, string, string, string, int>())
.def(boost::python::init<string, string, string, string, int, string>()) .def(bp::init<string, string, string, string, int, string>())
.def("__repr__", &Identity::_repr) .def("__repr__", &Identity::_repr)
.def("__str__", &Identity::_str, .def("__str__", &Identity::_str,
"string representation of this identity\n" "string representation of this identity\n"
"following the pattern 'username < address >'\n" "following the pattern 'username < address >'\n"
) )
.def("key_reset", &Identity::key_reset, .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" "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" "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" "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.") "completely fresh on next contact from the partner.")
.def("key_mistrusted", &Identity::key_mistrusted, .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" "If you want updated trust on the identity, you ll have"
"to call update_identity or myself respectively after this." "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," "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::*)()) .add_property("comm_type", (int(Identity::*)())
(PEP_comm_type(Identity::*)()) &Identity::comm_type, (PEP_comm_type(Identity::*)()) &Identity::comm_type,
(void(Identity::*)(int)) (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)") "communication type, first rating level (p≡p internal)")
.add_property("lang", (string(Identity::*)()) &Identity::lang, .add_property("lang", (string(Identity::*)()) &Identity::lang,
(void(Identity::*)(string)) &Identity::lang, (void(Identity::*)(string)) &Identity::lang,
"ISO 639-1 language code") "ISO 639-1 language code")
.add_property("flags", (identity_flags_t(Identity::*)()) &Identity::flags, .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)") "flags (p≡p internal)")
.add_property("rating", &Identity::rating, "rating of Identity") .add_property("rating", &Identity::rating, "rating of Identity")
.add_property("color", &Identity::color, "color of Identity as PEP_color") .add_property("color", &Identity::color, "color of Identity as PEP_color")
@ -312,9 +149,9 @@ namespace pEp {
" data bytes-like object\n" " data bytes-like object\n"
" mime_type MIME type for the data\n" " mime_type MIME type for the data\n"
" filename filename to store the data\n", " filename filename to store the data\n",
boost::python::init< object, char const*, char const* >(args("data", "mime_type", "filename"))) bp::init< bp::object, char const*, char const* >(bp::args("data", "mime_type", "filename")))
.def(boost::python::init<object, string>()) .def(bp::init<bp::object, string>())
.def(boost::python::init<object>()) .def(bp::init<bp::object>())
.def("__repr__", &Message::Blob::_repr) .def("__repr__", &Message::Blob::_repr)
.def("__len__", &Message::Blob::size, "size of Blob data in bytes") .def("__len__", &Message::Blob::size, "size of Blob data in bytes")
.def("decode", (string(Message::Blob::*)()) &Message::Blob::decode) .def("decode", (string(Message::Blob::*)()) &Message::Blob::decode)
@ -350,9 +187,9 @@ namespace pEp {
"\n" "\n"
" mime_text text in Multipurpose Internet Mail Extensions format\n" " mime_text text in Multipurpose Internet Mail Extensions format\n"
) )
.def(boost::python::init<int>()) .def(bp::init<int>())
.def(boost::python::init<int, Identity *>()) .def(bp::init<int, Identity *>())
.def(boost::python::init<string>()) .def(bp::init<string>())
.def("__str__", &Message::_str, .def("__str__", &Message::_str,
"the string representation of a Message is it's MIME text" "the string representation of a Message is it's MIME text"
) )
@ -360,7 +197,7 @@ namespace pEp {
.add_property("dir", (int(Message::*)()) .add_property("dir", (int(Message::*)())
(PEP_msg_direction(Message::*)()) &Message::dir, (PEP_msg_direction(Message::*)()) &Message::dir,
(void(Message::*)(int)) (void(Message::*)(int))
(void(Message::*)(PEP_msg_direction)) &Message::dir, (void(Message::*)(::PEP_msg_direction)) &Message::dir,
"0: incoming, 1: outgoing message") "0: incoming, 1: outgoing message")
.add_property("id", (string(Message::*)()) &Message::id, .add_property("id", (string(Message::*)()) &Message::id,
(void(Message::*)(string)) &Message::id, (void(Message::*)(string)) &Message::id,
@ -374,8 +211,8 @@ namespace pEp {
.add_property("longmsg_formatted", (string(Message::*)()) &Message::longmsg_formatted, .add_property("longmsg_formatted", (string(Message::*)()) &Message::longmsg_formatted,
(void(Message::*)(string)) &Message::longmsg_formatted, (void(Message::*)(string)) &Message::longmsg_formatted,
"HTML body or fromatted long version of message") "HTML body or fromatted long version of message")
.add_property("attachments", (boost::python::tuple(Message::*)()) &Message::attachments, .add_property("attachments", (bp::tuple(Message::*)()) &Message::attachments,
(void(Message::*)(boost::python::list)) &Message::attachments, (void(Message::*)(bp::list)) &Message::attachments,
"tuple of Blobs with attachments; setting moves Blobs to attachment tuple") "tuple of Blobs with attachments; setting moves Blobs to attachment tuple")
.add_property("sent", (time_t(Message::*)()) &Message::sent, .add_property("sent", (time_t(Message::*)()) &Message::sent,
(void(Message::*)(time_t)) &Message::sent, (void(Message::*)(time_t)) &Message::sent,
@ -384,47 +221,47 @@ namespace pEp {
(void(Message::*)(time_t)) &Message::recv, (void(Message::*)(time_t)) &Message::recv,
"time when message was received in UTC seconds since epoch") "time when message was received in UTC seconds since epoch")
.add_property("from_", (Identity(Message::*)()) &Message::from, .add_property("from_", (Identity(Message::*)()) &Message::from,
(void(Message::*)(object)) &Message::from, (void(Message::*)(bp::object)) &Message::from,
"identity where message is from") "identity where message is from")
.add_property("to", (boost::python::list(Message::*)()) &Message::to, .add_property("to", (bp::list(Message::*)()) &Message::to,
(void(Message::*)(boost::python::list)) &Message::to, (void(Message::*)(bp::list)) &Message::to,
"list of identities message is going to") "list of identities message is going to")
.add_property("recv_by", (Identity(Message::*)()) &Message::recv_by, .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") "identity where message was received by")
.add_property("cc", (boost::python::list(Message::*)()) &Message::cc, .add_property("cc", (bp::list(Message::*)()) &Message::cc,
(void(Message::*)(boost::python::list)) &Message::cc, (void(Message::*)(bp::list)) &Message::cc,
"list of identities message is going cc") "list of identities message is going cc")
.add_property("bcc", (boost::python::list(Message::*)()) &Message::bcc, .add_property("bcc", (bp::list(Message::*)()) &Message::bcc,
(void(Message::*)(boost::python::list)) &Message::bcc, (void(Message::*)(bp::list)) &Message::bcc,
"list of identities message is going bcc") "list of identities message is going bcc")
.add_property("reply_to", (boost::python::list(Message::*)()) &Message::reply_to, .add_property("reply_to", (bp::list(Message::*)()) &Message::reply_to,
(void(Message::*)(boost::python::list)) &Message::reply_to, (void(Message::*)(bp::list)) &Message::reply_to,
"list of identities where message will be replied to") "list of identities where message will be replied to")
.add_property("in_reply_to", (boost::python::list(Message::*)()) &Message::in_reply_to, .add_property("in_reply_to", (bp::list(Message::*)()) &Message::in_reply_to,
(void(Message::*)(boost::python::list)) &Message::in_reply_to, (void(Message::*)(bp::list)) &Message::in_reply_to,
"in_reply_to list") "in_reply_to list")
.add_property("references", (boost::python::list(Message::*)()) &Message::references, .add_property("references", (bp::list(Message::*)()) &Message::references,
(void(Message::*)(boost::python::list)) &Message::references, (void(Message::*)(bp::list)) &Message::references,
"message IDs of messages this one is referring to") "message IDs of messages this one is referring to")
.add_property("keywords", (boost::python::list(Message::*)()) &Message::keywords, .add_property("keywords", (bp::list(Message::*)()) &Message::keywords,
(void(Message::*)(boost::python::list)) &Message::keywords, (void(Message::*)(bp::list)) &Message::keywords,
"keywords this message should be stored under") "keywords this message should be stored under")
.add_property("comments", (string(Message::*)()) &Message::comments, .add_property("comments", (string(Message::*)()) &Message::comments,
(void(Message::*)(string)) &Message::comments, (void(Message::*)(string)) &Message::comments,
"comments added to message") "comments added to message")
.add_property("opt_fields", (dict(Message::*)()) &Message::opt_fields, .add_property("opt_fields", (bp::dict(Message::*)()) &Message::opt_fields,
(void(Message::*)(dict)) &Message::opt_fields, (void(Message::*)(bp::dict)) &Message::opt_fields,
"opt_fields of message") "opt_fields of message")
.add_property("enc_format", (int(Message::*)()) .add_property("enc_format", (int(Message::*)())
(PEP_enc_format(Message::*)()) &Message::enc_format, (PEP_enc_format(Message::*)()) &Message::enc_format,
(void(Message::*)(int)) (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") "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::*)())&Message::encrypt)
.def("encrypt", (Message(Message::*)(boost::python::list))&Message::_encrypt) .def("encrypt", (Message(Message::*)(bp::list))&Message::_encrypt)
.def("encrypt", (Message(Message::*)(boost::python::list, int))&Message::_encrypt) .def("encrypt", (Message(Message::*)(bp::list, int))&Message::_encrypt)
.def("encrypt", (Message(Message::*)(boost::python::list, int, int))&Message::_encrypt, .def("encrypt", (Message(Message::*)(bp::list, int, int))&Message::_encrypt,
"msg2 = msg1.encrypt(extra_keys=[], enc_format='pEp', flags=0)\n" "msg2 = msg1.encrypt(extra_keys=[], enc_format='pEp', flags=0)\n"
"\n" "\n"
"encrypts a p≡p message and returns the encrypted message\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" " 3 for PGP/MIME, 4 for pEp\n"
" flags 1 is force encryption\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" "msg2, keys, rating, flags = msg1.decrypt()\n"
"\n" "\n"
"decrypts a p≡p message and returns a tuple with data\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" "mark a key as trusted with a person\n"
); );
enum_<identity_flags>("identity_flags") enum_<::identity_flags>("identity_flags")
.value("PEP_idf_not_for_sync", PEP_idf_not_for_sync) .value("PEP_idf_not_for_sync", ::PEP_idf_not_for_sync)
.value("PEP_idf_list", PEP_idf_list) .value("PEP_idf_list", ::PEP_idf_list)
.value("PEP_idf_devicegroup", PEP_idf_devicegroup); .value("PEP_idf_devicegroup", ::PEP_idf_devicegroup);
def("set_identity_flags", &set_identity_flags, def("set_identity_flags", &set_identity_flags,
"set_identity_flags(ident, flags)\n" "set_identity_flags(ident, flags)\n"
@ -529,25 +366,25 @@ namespace pEp {
// message API // message API
enum_<PEP_rating>("rating") enum_<::PEP_rating>("rating")
.value("_undefined", PEP_rating_undefined) .value("_undefined", ::PEP_rating_undefined)
.value("cannot_decrypt", PEP_rating_cannot_decrypt) .value("cannot_decrypt", ::PEP_rating_cannot_decrypt)
.value("have_no_key", PEP_rating_have_no_key) .value("have_no_key", ::PEP_rating_have_no_key)
.value("unencrypted", PEP_rating_unencrypted) .value("unencrypted", ::PEP_rating_unencrypted)
.value("unreliable", PEP_rating_unreliable) .value("unreliable", ::PEP_rating_unreliable)
.value("reliable", PEP_rating_reliable) .value("reliable", ::PEP_rating_reliable)
.value("trusted", PEP_rating_trusted) .value("trusted", ::PEP_rating_trusted)
.value("trusted_and_anonymized", PEP_rating_trusted_and_anonymized) .value("trusted_and_anonymized", ::PEP_rating_trusted_and_anonymized)
.value("fully_anonymous", PEP_rating_fully_anonymous) .value("fully_anonymous", ::PEP_rating_fully_anonymous)
.value("mistrust", PEP_rating_mistrust) .value("mistrust", ::PEP_rating_mistrust)
.value("b0rken", PEP_rating_b0rken) .value("b0rken", ::PEP_rating_b0rken)
.value("under_attack", PEP_rating_under_attack); .value("under_attack", ::PEP_rating_under_attack);
enum_<PEP_color>("colorvalue") enum_<::PEP_color>("colorvalue")
.value("no_color", PEP_color_no_color) .value("no_color", ::PEP_color_no_color)
.value("yellow", PEP_color_yellow) .value("yellow", ::PEP_color_yellow)
.value("green", PEP_color_green) .value("green", ::PEP_color_green)
.value("red", PEP_color_red); .value("red", ::PEP_color_red);
def("incoming_message", &incoming_message, def("incoming_message", &incoming_message,
@ -572,17 +409,17 @@ namespace pEp {
// Sync API // Sync API
enum_<sync_handshake_signal>("sync_handshake_signal") enum_<::sync_handshake_signal>("sync_handshake_signal")
.value("SYNC_NOTIFY_UNDEFINED", SYNC_NOTIFY_UNDEFINED) .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_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_ADD_OTHER_DEVICE", ::SYNC_NOTIFY_INIT_ADD_OTHER_DEVICE)
.value("SYNC_NOTIFY_INIT_FORM_GROUP", SYNC_NOTIFY_INIT_FORM_GROUP) .value("SYNC_NOTIFY_INIT_FORM_GROUP", ::SYNC_NOTIFY_INIT_FORM_GROUP)
.value("SYNC_NOTIFY_TIMEOUT", SYNC_NOTIFY_TIMEOUT) .value("SYNC_NOTIFY_TIMEOUT", ::SYNC_NOTIFY_TIMEOUT)
.value("SYNC_NOTIFY_ACCEPTED_DEVICE_ADDED", SYNC_NOTIFY_ACCEPTED_DEVICE_ADDED) .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_GROUP_CREATED", ::SYNC_NOTIFY_ACCEPTED_GROUP_CREATED)
.value("SYNC_NOTIFY_ACCEPTED_DEVICE_ACCEPTED", SYNC_NOTIFY_ACCEPTED_DEVICE_ACCEPTED) .value("SYNC_NOTIFY_ACCEPTED_DEVICE_ACCEPTED", ::SYNC_NOTIFY_ACCEPTED_DEVICE_ACCEPTED)
.value("SYNC_NOTIFY_SOLE", SYNC_NOTIFY_SOLE) .value("SYNC_NOTIFY_SOLE", ::SYNC_NOTIFY_SOLE)
.value("SYNC_NOTIFY_IN_GROUP", SYNC_NOTIFY_IN_GROUP); .value("SYNC_NOTIFY_IN_GROUP", ::SYNC_NOTIFY_IN_GROUP);
// auto user_interface_class = class_<UserInterface, UserInterface_callback, boost::noncopyable>( // auto user_interface_class = class_<UserInterface, UserInterface_callback, boost::noncopyable>(
// "UserInterface", // "UserInterface",
@ -601,7 +438,7 @@ namespace pEp {
// "\n" // "\n"
// "overwrite this method with an implementation of a handshake dialog") // "overwrite this method with an implementation of a handshake dialog")
// .def("deliverHandshakeResult", &UserInterface::deliverHandshakeResult, // .def("deliverHandshakeResult", &UserInterface::deliverHandshakeResult,
// boost::python::arg("identities")=object(), // bp::arg("identities")=object(),
// "deliverHandshakeResult(self, result, identities=None)\n" // "deliverHandshakeResult(self, result, identities=None)\n"
// "\n" // "\n"
// " result -1: cancel, 0: accepted, 1: rejected\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" // "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" "deliverHandshakeResult(self, result, identities=None)\n"
"\n" "\n"
" result -1: cancel, 0: accepted, 1: rejected\n" " result -1: cancel, 0: accepted, 1: rejected\n"
@ -648,9 +485,8 @@ namespace pEp {
// codecs // codecs
call< object >(((object)(import("codecs").attr("register"))).ptr(), make_function(sync_search)); bp::call< bp::object >(((bp::object)(bp::import("codecs").attr("register"))).ptr(), make_function(sync_search));
call< object >(((object)(import("codecs").attr("register"))).ptr(), make_function(distribution_search)); bp::call< bp::object >(((bp::object)(bp::import("codecs").attr("register"))).ptr(), make_function(distribution_search));
} }
} // namespace PythonAdapter
} // namespace PythonAdapter
} // namespace pEp } // namespace pEp

24
src/pEp/_pEp/pEpmodule.hh

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

40
src/pEp/_pEp/str_attr.hh

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

100
src/pEp/_pEp/user_interface.cc

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

42
src/pEp/_pEp/user_interface.hh

@ -4,57 +4,41 @@
#ifndef USER_INTERFACE_HH #ifndef USER_INTERFACE_HH
#define USER_INTERFACE_HH #define USER_INTERFACE_HH
// System #include "adapter_main.hh"
#include <csetjmp> #include "identity.hh"
// Engine
#include <pEp/sync_api.h>
#include <pEp/message_api.h>
// local
#include "pEpmodule.hh"
namespace pEp { namespace pEp {
namespace PythonAdapter { namespace PythonAdapter {
class UserInterface { class UserInterface {
static UserInterface *_ui; static UserInterface *_ui;
public: public:
UserInterface(); UserInterface();
virtual ~UserInterface(); virtual ~UserInterface();
virtual void notifyHandshake( virtual void notifyHandshake(Identity me, Identity partner, ::sync_handshake_signal signal) {
Identity me,
Identity partner,
sync_handshake_signal signal) {
throw runtime_error("override this method"); 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: 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; PyObject *_self;
public: public:
UserInterface_callback(PyObject *self); UserInterface_callback(PyObject *self);
~UserInterface_callback(); ~UserInterface_callback();
void notifyHandshake( void notifyHandshake(Identity me, Identity partner, sync_handshake_signal signal);
Identity me, };
Identity partner,
sync_handshake_signal signal
);
};
} /* namespace PythonAdapter */ } /* namespace PythonAdapter */
} /* namespace pEp */ } /* namespace pEp */
#endif /* USER_INTERFACE_HH */ #endif /* USER_INTERFACE_HH */

Loading…
Cancel
Save