
16 changed files with 1556 additions and 1472 deletions
@ -1,164 +1,172 @@ |
|||
// This file is under GNU Affero General Public License 3.0
|
|||
// see LICENSE.txt
|
|||
|
|||
// System
|
|||
#include <sstream> |
|||
|
|||
// Engine
|
|||
#include <pEp/keymanagement.h> |
|||
#include <pEp/message_api.h> |
|||
#include <pEp/Adapter.hh> |
|||
|
|||
// local
|
|||
#include "basic_api.hh" |
|||
|
|||
namespace pEp { |
|||
namespace PythonAdapter { |
|||
void update_identity(Identity& ident) |
|||
{ |
|||
if (ident.address() == "") |
|||
throw invalid_argument("address needed"); |
|||
if (ident.user_id() == PEP_OWN_USERID) |
|||
throw runtime_error("update_identity: '" PEP_OWN_USERID |
|||
"' may only be used for own identities"); |
|||
|
|||
PEP_STATUS status = update_identity(pEp::Adapter::session(), ident); |
|||
_throw_status(status); |
|||
} |
|||
|
|||
void myself(Identity& ident) |
|||
{ |
|||
if (ident.address() == "") |
|||
throw invalid_argument("address needed"); |
|||
if (ident.username() == "") |
|||
throw invalid_argument("username needed"); |
|||
namespace PythonAdapter { |
|||
using namespace std; |
|||
|
|||
void update_identity(Identity& ident) |
|||
{ |
|||
if (ident.address() == "") |
|||
throw invalid_argument("address needed"); |
|||
if (ident.user_id() == PEP_OWN_USERID) |
|||
throw runtime_error("update_identity: '" PEP_OWN_USERID |
|||
"' may only be used for own identities"); |
|||
|
|||
PEP_STATUS status = update_identity(pEp::Adapter::session(), ident); |
|||
_throw_status(status); |
|||
} |
|||
|
|||
if (ident.user_id() == "") |
|||
ident.user_id(ident.address()); |
|||
void myself(Identity& ident) |
|||
{ |
|||
if (ident.address() == "") |
|||
throw invalid_argument("address needed"); |
|||
if (ident.username() == "") |
|||
throw invalid_argument("username needed"); |
|||
|
|||
PEP_STATUS status = myself(pEp::Adapter::session(), ident); |
|||
_throw_status(status); |
|||
} |
|||
if (ident.user_id() == "") |
|||
ident.user_id(ident.address()); |
|||
|
|||
string _trustwords(Identity me, Identity partner, string lang, bool full) |
|||
{ |
|||
if (me.fpr() == "" || partner.fpr() == "") |
|||
throw invalid_argument("fingerprint needed in Identities"); |
|||
PEP_STATUS status = myself(pEp::Adapter::session(), ident); |
|||
_throw_status(status); |
|||
} |
|||
|
|||
if (lang == "" && me.lang() == partner.lang()) |
|||
lang = me.lang(); |
|||
string _trustwords(Identity me, Identity partner, string lang, bool full) |
|||
{ |
|||
if (me.fpr() == "" || partner.fpr() == "") |
|||
throw invalid_argument("fingerprint needed in Identities"); |
|||
|
|||
char *words = NULL; |
|||
size_t size = 0; |
|||
PEP_STATUS status = get_trustwords(pEp::Adapter::session(), me, partner, |
|||
lang.c_str(),&words, &size, full); |
|||
_throw_status(status); |
|||
return words; |
|||
} |
|||
if (lang == "" && me.lang() == partner.lang()) |
|||
lang = me.lang(); |
|||
|
|||
void trust_personal_key(Identity ident) |
|||
{ |
|||
if (ident.fpr() == "") |
|||
throw invalid_argument("fingerprint needed in Identities"); |
|||
if (ident.user_id() == "") |
|||
throw invalid_argument("user_id must be provided"); |
|||
char *words = NULL; |
|||
size_t size = 0; |
|||
PEP_STATUS status = get_trustwords(pEp::Adapter::session(), me, partner, |
|||
lang.c_str(),&words, &size, full); |
|||
_throw_status(status); |
|||
return words; |
|||
} |
|||
|
|||
PEP_STATUS status = trust_personal_key(pEp::Adapter::session(), ident); |
|||
_throw_status(status); |
|||
} |
|||
void trust_personal_key(Identity ident) |
|||
{ |
|||
if (ident.fpr() == "") |
|||
throw invalid_argument("fingerprint needed in Identities"); |
|||
if (ident.user_id() == "") |
|||
throw invalid_argument("user_id must be provided"); |
|||
|
|||
void set_identity_flags(Identity ident, identity_flags_t flags) |
|||
{ |
|||
if (ident.address() == "") |
|||
throw invalid_argument("address needed"); |
|||
if (ident.user_id() == "") |
|||
throw invalid_argument("user_id needed"); |
|||
PEP_STATUS status = trust_personal_key(pEp::Adapter::session(), ident); |
|||
_throw_status(status); |
|||
} |
|||
|
|||
PEP_STATUS status = set_identity_flags(pEp::Adapter::session(), ident, flags); |
|||
_throw_status(status); |
|||
} |
|||
void set_identity_flags(Identity ident, identity_flags_t flags) |
|||
{ |
|||
if (ident.address() == "") |
|||
throw invalid_argument("address needed"); |
|||
if (ident.user_id() == "") |
|||
throw invalid_argument("user_id needed"); |
|||
|
|||
void unset_identity_flags(Identity ident, identity_flags_t flags) |
|||
{ |
|||
if (ident.address() == "") |
|||
throw invalid_argument("address needed"); |
|||
if (ident.user_id() == "") |
|||
throw invalid_argument("user_id needed"); |
|||
PEP_STATUS status = set_identity_flags(pEp::Adapter::session(), ident, flags); |
|||
_throw_status(status); |
|||
} |
|||
|
|||
PEP_STATUS status = unset_identity_flags(pEp::Adapter::session(), ident, flags); |
|||
_throw_status(status); |
|||
} |
|||
void unset_identity_flags(Identity ident, identity_flags_t flags) |
|||
{ |
|||
if (ident.address() == "") |
|||
throw invalid_argument("address needed"); |
|||
if (ident.user_id() == "") |
|||
throw invalid_argument("user_id needed"); |
|||
|
|||
void key_reset_trust(Identity ident) |
|||
{ |
|||
if (ident.fpr() == "") |
|||
throw invalid_argument("fpr needed"); |
|||
if (ident.address() == "") |
|||
throw invalid_argument("address needed"); |
|||
if (ident.user_id() == "") |
|||
throw invalid_argument("user_id needed"); |
|||
|
|||
PEP_STATUS status = key_reset_trust(pEp::Adapter::session(), ident); |
|||
_throw_status(status); |
|||
} |
|||
PEP_STATUS status = unset_identity_flags(pEp::Adapter::session(), ident, flags); |
|||
_throw_status(status); |
|||
} |
|||
|
|||
void key_reset_trust(Identity ident) |
|||
{ |
|||
if (ident.fpr() == "") |
|||
throw invalid_argument("fpr needed"); |
|||
if (ident.address() == "") |
|||
throw invalid_argument("address needed"); |
|||
if (ident.user_id() == "") |
|||
throw invalid_argument("user_id needed"); |
|||
|
|||
PEP_STATUS status = key_reset_trust(pEp::Adapter::session(), ident); |
|||
_throw_status(status); |
|||
} |
|||
|
|||
|
|||
boost::python::list import_key(string key_data) |
|||
{ |
|||
::identity_list *private_keys = NULL; |
|||
PEP_STATUS status = ::import_key(pEp::Adapter::session(), key_data.c_str(), key_data.size(), &private_keys); |
|||
if (status && status != PEP_KEY_IMPORTED) |
|||
_throw_status(status); |
|||
|
|||
auto result = boost::python::list(); |
|||
for (::identity_list *il = private_keys; il && il->ident; il=il->next) { |
|||
::pEp_identity *ident = ::identity_dup(il->ident); |
|||
if (!ident) { |
|||
free_identity_list(private_keys); |
|||
throw bad_alloc(); |
|||
} |
|||
result.append(Identity(ident)); |
|||
} |
|||
boost::python::list import_key(string key_data) |
|||
{ |
|||
::identity_list *private_keys = NULL; |
|||
PEP_STATUS status = ::import_key(pEp::Adapter::session(), key_data.c_str(), key_data.size(), &private_keys); |
|||
if (status && status != PEP_KEY_IMPORTED) |
|||
_throw_status(status); |
|||
|
|||
auto result = boost::python::list(); |
|||
for (::identity_list *il = private_keys; il && il->ident; il=il->next) { |
|||
::pEp_identity *ident = ::identity_dup(il->ident); |
|||
if (!ident) { |
|||
free_identity_list(private_keys); |
|||
return result; |
|||
throw bad_alloc(); |
|||
} |
|||
result.append(Identity(ident)); |
|||
} |
|||
|
|||
string export_key(Identity ident) |
|||
{ |
|||
PEP_STATUS status = PEP_STATUS_OK; |
|||
char* key_data = NULL; |
|||
size_t size; |
|||
status = ::export_key(pEp::Adapter::session(), ident.fpr().c_str(), &key_data, &size); |
|||
free_identity_list(private_keys); |
|||
return result; |
|||
} |
|||
|
|||
_throw_status(status); |
|||
return key_data; |
|||
} |
|||
string export_key(Identity ident) |
|||
{ |
|||
PEP_STATUS status = PEP_STATUS_OK; |
|||
char* key_data = NULL; |
|||
size_t size; |
|||
status = ::export_key(pEp::Adapter::session(), ident.fpr().c_str(), &key_data, &size); |
|||
|
|||
string export_secret_key(Identity ident) |
|||
{ |
|||
PEP_STATUS status = PEP_STATUS_OK; |
|||
char* key_data = NULL; |
|||
size_t size; |
|||
status = ::export_secret_key(pEp::Adapter::session(), ident.fpr().c_str(), &key_data, &size); |
|||
_throw_status(status); |
|||
return key_data; |
|||
} |
|||
|
|||
_throw_status(status); |
|||
return key_data; |
|||
} |
|||
string export_secret_key(Identity ident) |
|||
{ |
|||
PEP_STATUS status = PEP_STATUS_OK; |
|||
char* key_data = NULL; |
|||
size_t size; |
|||
status = ::export_secret_key(pEp::Adapter::session(), ident.fpr().c_str(), &key_data, &size); |
|||
|
|||
void set_own_key(Identity& ident, string fpr) |
|||
{ |
|||
if (ident.address() == "") |
|||
throw invalid_argument("address needed"); |
|||
if (ident.username() == "") |
|||
throw invalid_argument("username needed"); |
|||
if (ident.user_id() == "") |
|||
throw invalid_argument("user_id needed"); |
|||
if (fpr == "") |
|||
throw invalid_argument("fpr needed"); |
|||
|
|||
|
|||
const char* fpr_c = fpr.c_str(); |
|||
PEP_STATUS status = set_own_key(pEp::Adapter::session(), ident, fpr_c); |
|||
_throw_status(status); |
|||
} |
|||
} |
|||
_throw_status(status); |
|||
return key_data; |
|||
} |
|||
|
|||
void set_own_key(Identity& ident, string fpr) |
|||
{ |
|||
if (ident.address() == "") |
|||
throw invalid_argument("address needed"); |
|||
if (ident.username() == "") |
|||
throw invalid_argument("username needed"); |
|||
if (ident.user_id() == "") |
|||
throw invalid_argument("user_id needed"); |
|||
if (fpr == "") |
|||
throw invalid_argument("fpr needed"); |
|||
|
|||
|
|||
const char* fpr_c = fpr.c_str(); |
|||
PEP_STATUS status = set_own_key(pEp::Adapter::session(), ident, fpr_c); |
|||
_throw_status(status); |
|||
} |
|||
|
|||
} // namespace PythonAdapter
|
|||
} // namespace pEp {
|
|||
|
|||
|
|||
|
@ -1,279 +1,285 @@ |
|||
// This file is under GNU Affero General Public License 3.0
|
|||
// see LICENSE.txt
|
|||
|
|||
// System
|
|||
#include <typeinfo> |
|||
#include <sstream> |
|||
|
|||
// Engine
|
|||
#include <pEp/identity_list.h> |
|||
#include <pEp/keymanagement.h> |
|||
#include <pEp/key_reset.h> |
|||
|
|||
// local
|
|||
#include "identity.hh" |
|||
#include "pEpmodule.hh" |
|||
#include "basic_api.hh" |
|||
#include "message_api.hh" |
|||
|
|||
namespace pEp { |
|||
namespace PythonAdapter { |
|||
|
|||
Identity::Identity(string address, string username, string user_id, |
|||
string fpr, int comm_type, string lang, identity_flags_t flags) |
|||
: _ident(new_identity(address.c_str(), fpr.c_str(), user_id.c_str(), |
|||
username.c_str()), &::free_identity) |
|||
{ |
|||
if (!_ident) |
|||
throw bad_alloc(); |
|||
_ident->comm_type = (PEP_comm_type) comm_type; |
|||
_ident->flags = (identity_flags_t) flags; |
|||
this->lang(lang); |
|||
} |
|||
namespace PythonAdapter { |
|||
using namespace std; |
|||
using namespace boost::python; |
|||
|
|||
Identity::Identity(string address, string username, string user_id, |
|||
string fpr, int comm_type, string lang, identity_flags_t flags) |
|||
: _ident(new_identity(address.c_str(), fpr.c_str(), user_id.c_str(), |
|||
username.c_str()), &::free_identity) |
|||
{ |
|||
if (!_ident) |
|||
throw bad_alloc(); |
|||
_ident->comm_type = (PEP_comm_type) comm_type; |
|||
_ident->flags = (identity_flags_t) flags; |
|||
this->lang(lang); |
|||
} |
|||
|
|||
Identity::Identity(const Identity& second) |
|||
: _ident(second._ident) |
|||
{ |
|||
Identity::Identity(const Identity& second) |
|||
: _ident(second._ident) |
|||
{ |
|||
|
|||
} |
|||
} |
|||
|
|||
Identity::Identity(pEp_identity *ident) |
|||
: _ident(ident, &::free_identity) |
|||
{ |
|||
Identity::Identity(pEp_identity *ident) |
|||
: _ident(ident, &::free_identity) |
|||
{ |
|||
|
|||
} |
|||
} |
|||
|
|||
Identity::~Identity() |
|||
{ |
|||
Identity::~Identity() |
|||
{ |
|||
|
|||
} |
|||
} |
|||
|
|||
Identity::operator pEp_identity *() |
|||
{ |
|||
return _ident.get(); |
|||
} |
|||
Identity::operator pEp_identity *() |
|||
{ |
|||
return _ident.get(); |
|||
} |
|||
|
|||
Identity::operator const pEp_identity *() const |
|||
{ |
|||
return _ident.get(); |
|||
} |
|||
Identity::operator const pEp_identity *() const |
|||
{ |
|||
return _ident.get(); |
|||
} |
|||
|
|||
string Identity::_repr() |
|||
{ |
|||
stringstream build; |
|||
build << "Identity("; |
|||
string address; |
|||
if (_ident->address) |
|||
address = string(_ident->address); |
|||
build << repr(address) << ", "; |
|||
string username; |
|||
if (_ident->username) |
|||
username = string(_ident->username); |
|||
build << repr(username) << ", "; |
|||
string user_id; |
|||
if (_ident->user_id) |
|||
user_id = string(_ident->user_id); |
|||
build << repr(user_id) << ", "; |
|||
string fpr; |
|||
if (_ident->fpr) |
|||
fpr = string(_ident->fpr); |
|||
build << repr(fpr) << ", "; |
|||
build << (int) _ident->comm_type << ", "; |
|||
string lang = _ident->lang; |
|||
build << repr(lang) << ")"; |
|||
return build.str(); |
|||
} |
|||
string Identity::_repr() |
|||
{ |
|||
stringstream build; |
|||
build << "Identity("; |
|||
string address; |
|||
if (_ident->address) |
|||
address = string(_ident->address); |
|||
build << repr(address) << ", "; |
|||
string username; |
|||
if (_ident->username) |
|||
username = string(_ident->username); |
|||
build << repr(username) << ", "; |
|||
string user_id; |
|||
if (_ident->user_id) |
|||
user_id = string(_ident->user_id); |
|||
build << repr(user_id) << ", "; |
|||
string fpr; |
|||
if (_ident->fpr) |
|||
fpr = string(_ident->fpr); |
|||
build << repr(fpr) << ", "; |
|||
build << (int) _ident->comm_type << ", "; |
|||
string lang = _ident->lang; |
|||
build << repr(lang) << ")"; |
|||
return build.str(); |
|||
} |
|||
|
|||
string Identity::_str() |
|||
{ |
|||
if (!(_ident->address && _ident->address[0])) |
|||
return ""; |
|||
if (!(_ident->username && _ident->username[0])) |
|||
return _ident->address; |
|||
return string(_ident->username) + " <" + _ident->address + ">"; |
|||
} |
|||
string Identity::_str() |
|||
{ |
|||
if (!(_ident->address && _ident->address[0])) |
|||
return ""; |
|||
if (!(_ident->username && _ident->username[0])) |
|||
return _ident->address; |
|||
return string(_ident->username) + " <" + _ident->address + ">"; |
|||
} |
|||
|
|||
void Identity::username(string value) |
|||
{ |
|||
if (value.length() && value.length() < 5) |
|||
throw length_error("username must be at least 5 characters"); |
|||
void Identity::username(string value) |
|||
{ |
|||
if (value.length() && value.length() < 5) |
|||
throw length_error("username must be at least 5 characters"); |
|||
|
|||
str_attr(_ident->username, value); |
|||
} |
|||
str_attr(_ident->username, value); |
|||
} |
|||
|
|||
void Identity::lang(string value) |
|||
{ |
|||
if (value == "") |
|||
memset(_ident->lang, 0, 3); |
|||
else if (value.length() != 2) |
|||
throw length_error("length of lang must be 2"); |
|||
else |
|||
memcpy(_ident->lang, value.c_str(), 3); |
|||
} |
|||
void Identity::lang(string value) |
|||
{ |
|||
if (value == "") |
|||
memset(_ident->lang, 0, 3); |
|||
else if (value.length() != 2) |
|||
throw length_error("length of lang must be 2"); |
|||
else |
|||
memcpy(_ident->lang, value.c_str(), 3); |
|||
} |
|||
|
|||
string Identity::lang() |
|||
{ |
|||
return _ident->lang; |
|||
} |
|||
string Identity::lang() |
|||
{ |
|||
return _ident->lang; |
|||
} |
|||
|
|||
int Identity::rating() |
|||
{ |
|||
if (!(_ident->address)) |
|||
throw invalid_argument("address must be given"); |
|||
int Identity::rating() |
|||
{ |
|||
if (!(_ident->address)) |
|||
throw invalid_argument("address must be given"); |
|||
|
|||
PEP_rating rating = PEP_rating_undefined; |
|||
PEP_STATUS status = ::identity_rating(pEp::Adapter::session(), _ident.get(), &rating); |
|||
_throw_status(status); |
|||
PEP_rating rating = PEP_rating_undefined; |
|||
PEP_STATUS status = ::identity_rating(pEp::Adapter::session(), _ident.get(), &rating); |
|||
_throw_status(status); |
|||
|
|||
return (int) rating; |
|||
} |
|||
return (int) rating; |
|||
} |
|||
|
|||
PEP_color Identity::color() |
|||
{ |
|||
return _color(rating()); |
|||
} |
|||
PEP_color Identity::color() |
|||
{ |
|||
return _color(rating()); |
|||
} |
|||
|
|||
Identity Identity::copy() |
|||
{ |
|||
pEp_identity *dup = ::identity_dup(*this); |
|||
if (!dup) |
|||
throw bad_alloc(); |
|||
Identity Identity::copy() |
|||
{ |
|||
pEp_identity *dup = ::identity_dup(*this); |
|||
if (!dup) |
|||
throw bad_alloc(); |
|||
|
|||
return Identity(dup); |
|||
} |
|||
return Identity(dup); |
|||
} |
|||
|
|||
Identity Identity::deepcopy(dict&) |
|||
{ |
|||
return copy(); |
|||
} |
|||
Identity Identity::deepcopy(dict&) |
|||
{ |
|||
return copy(); |
|||
} |
|||
|
|||
void Identity::update() |
|||
{ |
|||
update_identity(*this); |
|||
} |
|||
void Identity::update() |
|||
{ |
|||
update_identity(*this); |
|||
} |
|||
|
|||
void Identity::key_reset(string fpr) |
|||
{ |
|||
PEP_STATUS status = ::key_reset_identity(pEp::Adapter::session(), *this, |
|||
fpr != "" ? fpr.c_str() : nullptr); |
|||
_throw_status(status); |
|||
} |
|||
void Identity::key_reset(string fpr) |
|||
{ |
|||
PEP_STATUS status = ::key_reset_identity(pEp::Adapter::session(), *this, |
|||
fpr != "" ? fpr.c_str() : nullptr); |
|||
_throw_status(status); |
|||
} |
|||
|
|||
void Identity::key_mistrusted() |
|||
{ |
|||
PEP_STATUS status = ::key_mistrusted(pEp::Adapter::session(), *this); |
|||
_throw_status(status); |
|||
} |
|||
void Identity::key_mistrusted() |
|||
{ |
|||
PEP_STATUS status = ::key_mistrusted(pEp::Adapter::session(), *this); |
|||
_throw_status(status); |
|||
} |
|||
|
|||
bool Identity::is_pEp_user() |
|||
{ |
|||
bool result; |
|||
PEP_STATUS status = ::is_pEp_user(pEp::Adapter::session(), *this, &result); |
|||
_throw_status(status); |
|||
return result; |
|||
} |
|||
bool Identity::is_pEp_user() |
|||
{ |
|||
bool result; |
|||
PEP_STATUS status = ::is_pEp_user(pEp::Adapter::session(), *this, &result); |
|||
_throw_status(status); |
|||
return result; |
|||
} |
|||
|
|||
void Identity::enable_for_sync() |
|||
{ |
|||
PEP_STATUS status = ::enable_identity_for_sync(pEp::Adapter::session(), *this); |
|||
_throw_status(status); |
|||
} |
|||
void Identity::enable_for_sync() |
|||
{ |
|||
PEP_STATUS status = ::enable_identity_for_sync(pEp::Adapter::session(), *this); |
|||
_throw_status(status); |
|||
} |
|||
|
|||
void Identity::disable_for_sync() |
|||
{ |
|||
PEP_STATUS status = ::disable_identity_for_sync(pEp::Adapter::session(), *this); |
|||
_throw_status(status); |
|||
} |
|||
void Identity::disable_for_sync() |
|||
{ |
|||
PEP_STATUS status = ::disable_identity_for_sync(pEp::Adapter::session(), *this); |
|||
_throw_status(status); |
|||
} |
|||
|
|||
Myself::Myself(string address, string username, string user_id, string lang) |
|||
: Identity(address, username, user_id, "", 0, lang) |
|||
Myself::Myself(string address, string username, string user_id, string lang) |
|||
: Identity(address, username, user_id, "", 0, lang) |
|||
|
|||
{ |
|||
if (!(address.length() && username.length())) |
|||
throw invalid_argument("address and username must be set"); |
|||
if (lang.length() && lang.length() != 2) |
|||
throw length_error("lang must be an ISO 639-1 language code or empty"); |
|||
{ |
|||
if (!(address.length() && username.length())) |
|||
throw invalid_argument("address and username must be set"); |
|||
if (lang.length() && lang.length() != 2) |
|||
throw length_error("lang must be an ISO 639-1 language code or empty"); |
|||
|
|||
// FIXME: should set .me
|
|||
// _ident->me = true;
|
|||
if (user_id.length()) |
|||
throw runtime_error("user_id feature not yet implemented for Myself"); |
|||
} |
|||
// FIXME: should set .me
|
|||
// _ident->me = true;
|
|||
if (user_id.length()) |
|||
throw runtime_error("user_id feature not yet implemented for Myself"); |
|||
} |
|||
|
|||
void Myself::update() |
|||
{ |
|||
pEp::PythonAdapter::myself(*this); |
|||
} |
|||
void Myself::update() |
|||
{ |
|||
pEp::PythonAdapter::myself(*this); |
|||
} |
|||
|
|||
Identity identity_attr(pEp_identity *&ident) |
|||
{ |
|||
if (!ident) |
|||
throw out_of_range("no identity assigned"); |
|||
Identity identity_attr(pEp_identity *&ident) |
|||
{ |
|||
if (!ident) |
|||
throw out_of_range("no identity assigned"); |
|||
|
|||
pEp_identity *_dup = identity_dup(ident); |
|||
if (!_dup) |
|||
throw bad_alloc(); |
|||
pEp_identity *_dup = identity_dup(ident); |
|||
if (!_dup) |
|||
throw bad_alloc(); |
|||
|
|||
Identity _ident(_dup); |
|||
return _ident; |
|||
} |
|||
Identity _ident(_dup); |
|||
return _ident; |
|||
} |
|||
|
|||
void identity_attr(pEp_identity *&ident, object value) |
|||
{ |
|||
Identity& _ident = extract< Identity& >(value); |
|||
pEp_identity *_dup = ::identity_dup(_ident); |
|||
if (!_dup) |
|||
throw bad_alloc(); |
|||
PEP_STATUS status = update_identity(pEp::Adapter::session(), _dup); |
|||
_throw_status(status); |
|||
free_identity(ident); |
|||
ident = _dup; |
|||
} |
|||
void identity_attr(pEp_identity *&ident, object value) |
|||
{ |
|||
Identity& _ident = extract< Identity& >(value); |
|||
pEp_identity *_dup = ::identity_dup(_ident); |
|||
if (!_dup) |
|||
throw bad_alloc(); |
|||
PEP_STATUS status = update_identity(pEp::Adapter::session(), _dup); |
|||
_throw_status(status); |
|||
free_identity(ident); |
|||
ident = _dup; |
|||
} |
|||
|
|||
boost::python::list identitylist_attr(identity_list *&il) |
|||
{ |
|||
boost::python::list result; |
|||
|
|||
boost::python::list identitylist_attr(identity_list *&il) |
|||
{ |
|||
boost::python::list result; |
|||
for (identity_list *_il = il; _il && _il->ident; _il = _il->next) { |
|||
pEp_identity *ident = ::identity_dup(_il->ident); |
|||
if (!ident) |
|||
throw bad_alloc(); |
|||
result.append(object(Identity(ident))); |
|||
} |
|||
|
|||
for (identity_list *_il = il; _il && _il->ident; _il = _il->next) { |
|||
pEp_identity *ident = ::identity_dup(_il->ident); |
|||
if (!ident) |
|||
throw bad_alloc(); |
|||
result.append(object(Identity(ident))); |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
return result; |
|||
void identitylist_attr(identity_list *&il, boost::python::list value) |
|||
{ |
|||
identity_list *_il = new_identity_list(NULL); |
|||
if (!_il) |
|||
throw bad_alloc(); |
|||
|
|||
identity_list *_i = _il; |
|||
for (int i=0; i<len(value); i++) { |
|||
extract< Identity& > extract_identity(value[i]); |
|||
if (!extract_identity.check()) { |
|||
free_identity_list(_il); |
|||
} |
|||
|
|||
void identitylist_attr(identity_list *&il, boost::python::list value) |
|||
{ |
|||
identity_list *_il = new_identity_list(NULL); |
|||
if (!_il) |
|||
throw bad_alloc(); |
|||
|
|||
identity_list *_i = _il; |
|||
for (int i=0; i<len(value); i++) { |
|||
extract< Identity& > extract_identity(value[i]); |
|||
if (!extract_identity.check()) { |
|||
free_identity_list(_il); |
|||
} |
|||
pEp_identity *_ident = extract_identity(); |
|||
pEp_identity *_dup = ::identity_dup(_ident); |
|||
if (!_dup) { |
|||
free_identity_list(_il); |
|||
throw bad_alloc(); |
|||
} |
|||
PEP_STATUS status = update_identity(pEp::Adapter::session(), _dup); |
|||
if (status != PEP_STATUS_OK) { |
|||
free_identity_list(_il); |
|||
_throw_status(status); |
|||
} |
|||
_i = identity_list_add(_i, _dup); |
|||
if (!_i) { |
|||
free_identity_list(_il); |
|||
throw bad_alloc(); |
|||
} |
|||
} |
|||
|
|||
free_identity_list(il); |
|||
il = _il; |
|||
pEp_identity *_ident = extract_identity(); |
|||
pEp_identity *_dup = ::identity_dup(_ident); |
|||
if (!_dup) { |
|||
free_identity_list(_il); |
|||
throw bad_alloc(); |
|||
} |
|||
PEP_STATUS status = update_identity(pEp::Adapter::session(), _dup); |
|||
if (status != PEP_STATUS_OK) { |
|||
free_identity_list(_il); |
|||
_throw_status(status); |
|||
} |
|||
_i = identity_list_add(_i, _dup); |
|||
if (!_i) { |
|||
free_identity_list(_il); |
|||
throw bad_alloc(); |
|||
} |
|||
} |
|||
|
|||
free_identity_list(il); |
|||
il = _il; |
|||
} |
|||
|
|||
} // namespace PythonAdapter
|
|||
} // namespace pEp {
|
|||
|
|||
|
@ -1,408 +1,413 @@ |
|||
// This file is under GNU Affero General Public License 3.0
|
|||
// see LICENSE.txt
|
|||
|
|||
#include <Python.h> |
|||
// System
|
|||
#include <cstdlib> |
|||
#include <cstring> |
|||
#include <stdexcept> |
|||
#include <sstream> |
|||
#include <vector> |
|||
#include <Python.h> |
|||
|
|||
// Engine
|
|||
#include <pEp/mime.h> |
|||
#include <pEp/keymanagement.h> |
|||
#include <pEp/message_api.h> |
|||
|
|||
// local
|
|||
#include "message.hh" |
|||
#include "message_api.hh" |
|||
|
|||
namespace pEp { |
|||
namespace PythonAdapter { |
|||
using namespace std; |
|||
|
|||
Message::Blob::Blob(bloblist_t *bl, bool chained) : |
|||
_bl(bl), part_of_chain(chained) |
|||
{ |
|||
if (!_bl) |
|||
throw bad_alloc(); |
|||
} |
|||
namespace PythonAdapter { |
|||
using namespace std; |
|||
using namespace boost::python; |
|||
|
|||
Message::Blob::Blob(bloblist_t *bl, bool chained) : |
|||
_bl(bl), part_of_chain(chained) |
|||
{ |
|||
if (!_bl) |
|||
throw bad_alloc(); |
|||
} |
|||
|
|||
Message::Blob::Blob(object data, string mime_type, string filename) : |
|||
_bl(new_bloblist(NULL, 0, NULL, NULL)), part_of_chain(false) |
|||
{ |
|||
if (!_bl) |
|||
throw bad_alloc(); |
|||
Message::Blob::Blob(object data, string mime_type, string filename) : |
|||
_bl(new_bloblist(NULL, 0, NULL, NULL)), part_of_chain(false) |
|||
{ |
|||
if (!_bl) |
|||
throw bad_alloc(); |
|||
|
|||
Py_buffer src; |
|||
int result = PyObject_GetBuffer(data.ptr(), &src, PyBUF_CONTIG_RO); |
|||
if (result) |
|||
throw invalid_argument("need a contiguous buffer to read"); |
|||
|
|||
char *mem = (char *)malloc(src.len); |
|||
if (!mem) { |
|||
PyBuffer_Release(&src); |
|||
throw bad_alloc(); |
|||
} |
|||
|
|||
Py_buffer src; |
|||
int result = PyObject_GetBuffer(data.ptr(), &src, PyBUF_CONTIG_RO); |
|||
if (result) |
|||
throw invalid_argument("need a contiguous buffer to read"); |
|||
memcpy(mem, src.buf, src.len); |
|||
free(_bl->value); |
|||
_bl->size = src.len; |
|||
_bl->value = mem; |
|||
|
|||
char *mem = (char *)malloc(src.len); |
|||
if (!mem) { |
|||
PyBuffer_Release(&src); |
|||
throw bad_alloc(); |
|||
} |
|||
PyBuffer_Release(&src); |
|||
|
|||
memcpy(mem, src.buf, src.len); |
|||
free(_bl->value); |
|||
_bl->size = src.len; |
|||
_bl->value = mem; |
|||
this->mime_type(mime_type); |
|||
this->filename(filename); |
|||
} |
|||
|
|||
PyBuffer_Release(&src); |
|||
Message::Blob::Blob(const Message::Blob& second) : |
|||
_bl(second._bl), part_of_chain(true) |
|||
{ |
|||
|
|||
this->mime_type(mime_type); |
|||
this->filename(filename); |
|||
} |
|||
} |
|||
|
|||
Message::Blob::Blob(const Message::Blob& second) : |
|||
_bl(second._bl), part_of_chain(true) |
|||
{ |
|||
Message::Blob::~Blob() |
|||
{ |
|||
if (!part_of_chain) { |
|||
free(_bl->value); |
|||
free(_bl); |
|||
} |
|||
} |
|||
|
|||
} |
|||
string Message::Blob::_repr() |
|||
{ |
|||
stringstream build; |
|||
build << "Blob("; |
|||
if (!_bl) { |
|||
build << "b'', '', ''"; |
|||
} |
|||
else { |
|||
build << "bytes(" << _bl->size << "), "; |
|||
string mime_type; |
|||
if (_bl->mime_type) |
|||
mime_type = string(_bl->mime_type); |
|||
string filename; |
|||
if (_bl->filename) |
|||
filename = string(_bl->filename); |
|||
build << repr(mime_type) << ", "; |
|||
build << repr(filename); |
|||
} |
|||
build << ")"; |
|||
return build.str(); |
|||
} |
|||
|
|||
Message::Blob::~Blob() |
|||
{ |
|||
if (!part_of_chain) { |
|||
free(_bl->value); |
|||
free(_bl); |
|||
} |
|||
} |
|||
int Message::Blob::getbuffer(PyObject *self, Py_buffer *view, int flags) { |
|||
bloblist_t *bl = NULL; |
|||
|
|||
string Message::Blob::_repr() |
|||
{ |
|||
stringstream build; |
|||
build << "Blob("; |
|||
if (!_bl) { |
|||
build << "b'', '', ''"; |
|||
} |
|||
else { |
|||
build << "bytes(" << _bl->size << "), "; |
|||
string mime_type; |
|||
if (_bl->mime_type) |
|||
mime_type = string(_bl->mime_type); |
|||
string filename; |
|||
if (_bl->filename) |
|||
filename = string(_bl->filename); |
|||
build << repr(mime_type) << ", "; |
|||
build << repr(filename); |
|||
} |
|||
build << ")"; |
|||
return build.str(); |
|||
} |
|||
try { |
|||
Message::Blob& blob = extract< Message::Blob& >(self); |
|||
bl = blob._bl; |
|||
} |
|||
catch (exception& e) { |
|||
PyErr_SetString(PyExc_RuntimeError, "extract not possible"); |
|||
view->obj = NULL; |
|||
return -1; |
|||
} |
|||
|
|||
int Message::Blob::getbuffer(PyObject *self, Py_buffer *view, int flags) { |
|||
bloblist_t *bl = NULL; |
|||
if (!(bl && bl->value)) { |
|||
PyErr_SetString(PyExc_RuntimeError, "no data available"); |
|||
view->obj = NULL; |
|||
return -1; |
|||
} |
|||
|
|||
try { |
|||
Message::Blob& blob = extract< Message::Blob& >(self); |
|||
bl = blob._bl; |
|||
} |
|||
catch (exception& e) { |
|||
PyErr_SetString(PyExc_RuntimeError, "extract not possible"); |
|||
view->obj = NULL; |
|||
return -1; |
|||
} |
|||
return PyBuffer_FillInfo(view, self, bl->value, bl->size, 0, flags); |
|||
} |
|||
|
|||
if (!(bl && bl->value)) { |
|||
PyErr_SetString(PyExc_RuntimeError, "no data available"); |
|||
view->obj = NULL; |
|||
return -1; |
|||
} |
|||
string Message::Blob::decode(string encoding) |
|||
{ |
|||
if (encoding == "") { |
|||
string _mime_type = _bl->mime_type ? _bl->mime_type : ""; |
|||
encoding = "ascii"; |
|||
|
|||
return PyBuffer_FillInfo(view, self, bl->value, bl->size, 0, flags); |
|||
} |
|||
if (_mime_type == "application/pEp.sync") |
|||
encoding = "pep.sync"; |
|||
|
|||
string Message::Blob::decode(string encoding) |
|||
{ |
|||
if (encoding == "") { |
|||
string _mime_type = _bl->mime_type ? _bl->mime_type : ""; |
|||
encoding = "ascii"; |
|||
if (_mime_type == "application/pEp.keyreset") |
|||
encoding = "pep.distribution"; |
|||
|
|||
if (_mime_type == "application/pEp.sync") |
|||
encoding = "pep.sync"; |
|||
} |
|||
object codecs = import("codecs"); |
|||
object _decode = codecs.attr("decode"); |
|||
return call< string >(_decode.ptr(), this, encoding); |
|||
} |
|||
|
|||
if (_mime_type == "application/pEp.keyreset") |
|||
encoding = "pep.distribution"; |
|||
PyBufferProcs Message::Blob::bp = { getbuffer, NULL }; |
|||
|
|||
} |
|||
object codecs = import("codecs"); |
|||
object _decode = codecs.attr("decode"); |
|||
return call< string >(_decode.ptr(), this, encoding); |
|||
} |
|||
Message::Message(int dir, Identity *from) |
|||
: _msg(new_message((PEP_msg_direction) dir), &free_message) |
|||
{ |
|||
if (!_msg) |
|||
throw bad_alloc(); |
|||
|
|||
PyBufferProcs Message::Blob::bp = { getbuffer, NULL }; |
|||
if (from) { |
|||
_msg->from = ::identity_dup(*from); |
|||
if (!_msg->from) |
|||
throw bad_alloc(); |
|||
_msg->dir = (PEP_msg_direction) dir; |
|||
} |
|||
} |
|||
|
|||
Message::Message(int dir, Identity *from) |
|||
: _msg(new_message((PEP_msg_direction) dir), &free_message) |
|||
{ |
|||
if (!_msg) |
|||
Message::Message(string mimetext) |
|||
: _msg(NULL, &free_message) |
|||
{ |
|||
message *_cpy; |
|||
PEP_STATUS status = mime_decode_message(mimetext.c_str(), |
|||
mimetext.size(), &_cpy, NULL); |
|||
switch (status) { |
|||
case PEP_STATUS_OK: |
|||
if (_cpy) |
|||
_cpy->dir = PEP_dir_outgoing; |
|||
else |
|||
_cpy = new_message(PEP_dir_outgoing); |
|||
|
|||
if (!_cpy) |
|||
throw bad_alloc(); |
|||
|
|||
if (from) { |
|||
_msg->from = ::identity_dup(*from); |
|||
if (!_msg->from) |
|||
throw bad_alloc(); |
|||
_msg->dir = (PEP_msg_direction) dir; |
|||
} |
|||
} |
|||
_msg = shared_ptr< message >(_cpy); |
|||
break; |
|||
|
|||
Message::Message(string mimetext) |
|||
: _msg(NULL, &free_message) |
|||
{ |
|||
message *_cpy; |
|||
PEP_STATUS status = mime_decode_message(mimetext.c_str(), |
|||
mimetext.size(), &_cpy, NULL); |
|||
switch (status) { |
|||
case PEP_STATUS_OK: |
|||
if (_cpy) |
|||
_cpy->dir = PEP_dir_outgoing; |
|||
else |
|||
_cpy = new_message(PEP_dir_outgoing); |
|||
|
|||
if (!_cpy) |
|||
throw bad_alloc(); |
|||
|
|||
_msg = shared_ptr< message >(_cpy); |
|||
break; |
|||
|
|||
case PEP_BUFFER_TOO_SMALL: |
|||
throw runtime_error("mime_decode_message: buffer too small"); |
|||
|
|||
case PEP_CANNOT_CREATE_TEMP_FILE: |
|||
throw runtime_error("mime_decode_message: cannot create temp file"); |
|||
|
|||
case PEP_OUT_OF_MEMORY: |
|||
throw bad_alloc(); |
|||
|
|||
default: |
|||
stringstream build; |
|||
build << "mime_decode_message: unknown error (" << (int) status << ")"; |
|||
throw runtime_error(build.str()); |
|||
} |
|||
} |
|||
case PEP_BUFFER_TOO_SMALL: |
|||
throw runtime_error("mime_decode_message: buffer too small"); |
|||
|
|||
Message::Message(const Message& second) |
|||
: _msg(second._msg) |
|||
{ |
|||
if (!_msg.get()) |
|||
throw bad_alloc(); |
|||
} |
|||
case PEP_CANNOT_CREATE_TEMP_FILE: |
|||
throw runtime_error("mime_decode_message: cannot create temp file"); |
|||
|
|||
Message::Message(message *msg) |
|||
: _msg(::message_dup(msg), &free_message) |
|||
{ |
|||
case PEP_OUT_OF_MEMORY: |
|||
throw bad_alloc(); |
|||
|
|||
} |
|||
default: |
|||
stringstream build; |
|||
build << "mime_decode_message: unknown error (" << (int) status << ")"; |
|||
throw runtime_error(build.str()); |
|||
} |
|||
} |
|||
|
|||
Message::~Message() |
|||
{ |
|||
Message::Message(const Message& second) |
|||
: _msg(second._msg) |
|||
{ |
|||
if (!_msg.get()) |
|||
throw bad_alloc(); |
|||
} |
|||
|
|||
} |
|||
Message::Message(message *msg) |
|||
: _msg(::message_dup(msg), &free_message) |
|||
{ |
|||
|
|||
Message::operator message *() |
|||
{ |
|||
return _msg.get(); |
|||
} |
|||
} |
|||
|
|||
Message::operator const message *() const |
|||
{ |
|||
return _msg.get(); |
|||
} |
|||
Message::~Message() |
|||
{ |
|||
|
|||
string Message::_str() |
|||
{ |
|||
if (!(_msg->from && _msg->from->address && _msg->from->address[0])) |
|||
throw out_of_range(".from_.address missing"); |
|||
} |
|||
|
|||
char *mimetext; |
|||
string result; |
|||
Message::operator message *() |
|||
{ |
|||
return _msg.get(); |
|||
} |
|||
|
|||
PEP_STATUS status = mime_encode_message(*this, false, &mimetext, false); |
|||
switch (status) { |
|||
case PEP_STATUS_OK: |
|||
result = mimetext; |
|||
free(mimetext); |
|||
break; |
|||
Message::operator const message *() const |
|||
{ |
|||
return _msg.get(); |
|||
} |
|||
|
|||
case PEP_BUFFER_TOO_SMALL: |
|||
throw runtime_error("mime_encode_message: buffer too small"); |
|||
string Message::_str() |
|||
{ |
|||
if (!(_msg->from && _msg->from->address && _msg->from->address[0])) |
|||
throw out_of_range(".from_.address missing"); |
|||
|
|||
case PEP_CANNOT_CREATE_TEMP_FILE: |
|||
throw runtime_error("mime_encode_message: cannot create temp file"); |
|||
char *mimetext; |
|||
string result; |
|||
|
|||
case PEP_OUT_OF_MEMORY: |
|||
throw bad_alloc(); |
|||
PEP_STATUS status = mime_encode_message(*this, false, &mimetext, false); |
|||
switch (status) { |
|||
case PEP_STATUS_OK: |
|||
result = mimetext; |
|||
free(mimetext); |
|||
break; |
|||
|
|||
default: |
|||
stringstream build; |
|||
build << "mime_encode_message: unknown error (" << (int) status << ")"; |
|||
throw runtime_error(build.str()); |
|||
} |
|||
case PEP_BUFFER_TOO_SMALL: |
|||
throw runtime_error("mime_encode_message: buffer too small"); |
|||
|
|||
return result; |
|||
} |
|||
case PEP_CANNOT_CREATE_TEMP_FILE: |
|||
throw runtime_error("mime_encode_message: cannot create temp file"); |
|||
|
|||
string Message::_repr() |
|||
{ |
|||
case PEP_OUT_OF_MEMORY: |
|||
throw bad_alloc(); |
|||
|
|||
default: |
|||
stringstream build; |
|||
build << "Message(" << repr(_str()) << ")"; |
|||
return build.str(); |
|||
} |
|||
build << "mime_encode_message: unknown error (" << (int) status << ")"; |
|||
throw runtime_error(build.str()); |
|||
} |
|||
|
|||
boost::python::tuple Message::attachments() |
|||
{ |
|||
boost::python::list l; |
|||
return result; |
|||
} |
|||
|
|||
for (bloblist_t *bl = _msg->attachments; bl && bl->value; bl = |
|||
bl->next) { |
|||
l.append(Blob(bl, true)); |
|||
} |
|||
string Message::_repr() |
|||
{ |
|||
stringstream build; |
|||
build << "Message(" << repr(_str()) << ")"; |
|||
return build.str(); |
|||
} |
|||
|
|||
return boost::python::tuple(l); |
|||
} |
|||
boost::python::tuple Message::attachments() |
|||
{ |
|||
boost::python::list l; |
|||
|
|||
void Message::attachments(boost::python::list value) |
|||
{ |
|||
bloblist_t *bl = new_bloblist(NULL, 0, NULL, NULL); |
|||
if (!bl) |
|||
throw bad_alloc(); |
|||
for (bloblist_t *bl = _msg->attachments; bl && bl->value; bl = |
|||
bl->next) { |
|||
l.append(Blob(bl, true)); |
|||
} |
|||
|
|||
bloblist_t *_l = bl; |
|||
for (int i=0; i<len(value); i++) { |
|||
Message::Blob& blob = extract< Message::Blob& >(value[i]); |
|||
_l = bloblist_add(_l, blob._bl->value, blob._bl->size, |
|||
blob._bl->mime_type, blob._bl->filename); |
|||
if (!_l) { |
|||
for (_l = bl; _l && _l->value; ) { |
|||
free(_l->mime_type); |
|||
free(_l->filename); |
|||
bloblist_t *_ll = _l; |
|||
_l = _l->next; |
|||
free(_ll); |
|||
} |
|||
throw bad_alloc(); |
|||
} |
|||
} |
|||
return boost::python::tuple(l); |
|||
} |
|||
|
|||
for (int i=0; i<len(value); i++) { |
|||
Message::Blob& blob = extract< Message::Blob& >(value[i]); |
|||
blob._bl->value = NULL; |
|||
blob._bl->size = 0; |
|||
free(blob._bl->mime_type); |
|||
blob._bl->mime_type = NULL; |
|||
free(blob._bl->filename); |
|||
blob._bl->filename = NULL; |
|||
void Message::attachments(boost::python::list value) |
|||
{ |
|||
bloblist_t *bl = new_bloblist(NULL, 0, NULL, NULL); |
|||
if (!bl) |
|||
throw bad_alloc(); |
|||
|
|||
bloblist_t *_l = bl; |
|||
for (int i=0; i<len(value); i++) { |
|||
Message::Blob& blob = extract< Message::Blob& >(value[i]); |
|||
_l = bloblist_add(_l, blob._bl->value, blob._bl->size, |
|||
blob._bl->mime_type, blob._bl->filename); |
|||
if (!_l) { |
|||
for (_l = bl; _l && _l->value; ) { |
|||
free(_l->mime_type); |
|||
free(_l->filename); |
|||
bloblist_t *_ll = _l; |
|||
_l = _l->next; |
|||
free(_ll); |
|||
} |
|||
|
|||
free_bloblist(_msg->attachments); |
|||
_msg->attachments = bl; |
|||
throw bad_alloc(); |
|||
} |
|||
} |
|||
|
|||
Message Message::encrypt() |
|||
{ |
|||
boost::python::list extra; |
|||
return encrypt_message(*this, extra, PEP_enc_PGP_MIME, 0); |
|||
} |
|||
for (int i=0; i<len(value); i++) { |
|||
Message::Blob& blob = extract< Message::Blob& >(value[i]); |
|||
blob._bl->value = NULL; |
|||
blob._bl->size = 0; |
|||
free(blob._bl->mime_type); |
|||
blob._bl->mime_type = NULL; |
|||
free(blob._bl->filename); |
|||
blob._bl->filename = NULL; |
|||
} |
|||
|
|||
Message Message::_encrypt(boost::python::list extra, int enc_format, int flags) |
|||
{ |
|||
if (!enc_format) |
|||
enc_format = PEP_enc_PGP_MIME; |
|||
return encrypt_message(*this, extra, enc_format, flags); |
|||
} |
|||
free_bloblist(_msg->attachments); |
|||
_msg->attachments = bl; |
|||
} |
|||
|
|||
boost::python::tuple Message::decrypt(int flags) { |
|||
return pEp::PythonAdapter::decrypt_message(*this, flags); |
|||
} |
|||
Message Message::encrypt() |
|||
{ |
|||
boost::python::list extra; |
|||
return encrypt_message(*this, extra, PEP_enc_PGP_MIME, 0); |
|||
} |
|||
|
|||
PEP_rating Message::outgoing_rating() |
|||
{ |
|||
if (_msg->dir != PEP_dir_outgoing) |
|||
throw invalid_argument("Message.dir must be outgoing"); |
|||
Message Message::_encrypt(boost::python::list extra, int enc_format, int flags) |
|||
{ |
|||
if (!enc_format) |
|||
enc_format = PEP_enc_PGP_MIME; |
|||
return encrypt_message(*this, extra, enc_format, flags); |
|||
} |
|||
|
|||
if (from().address() == "") |
|||
throw invalid_argument("from.address needed"); |
|||
if (from().username() == "") |
|||
throw invalid_argument("from.username needed"); |
|||
boost::python::tuple Message::decrypt(int flags) { |
|||
return pEp::PythonAdapter::decrypt_message(*this, flags); |
|||
} |
|||
|
|||
if (len(to()) + len(cc()) == 0) |
|||
throw invalid_argument("either to or cc needed"); |
|||
PEP_rating Message::outgoing_rating() |
|||
{ |
|||
if (_msg->dir != PEP_dir_outgoing) |
|||
throw invalid_argument("Message.dir must be outgoing"); |
|||
|
|||
PEP_STATUS status = myself(pEp::Adapter::session(), _msg->from); |
|||
_throw_status(status); |
|||
if (from().address() == "") |
|||
throw invalid_argument("from.address needed"); |
|||
if (from().username() == "") |
|||
throw invalid_argument("from.username needed"); |
|||
|
|||
PEP_rating rating = PEP_rating_undefined; |
|||
status = outgoing_message_rating(pEp::Adapter::session(), *this, &rating); |
|||
_throw_status(status); |
|||
if (len(to()) + len(cc()) == 0) |
|||
throw invalid_argument("either to or cc needed"); |
|||
|
|||
return rating; |
|||
} |
|||
PEP_STATUS status = myself(pEp::Adapter::session(), _msg->from); |
|||
_throw_status(status); |
|||
|
|||
PEP_color Message::outgoing_color() |
|||
{ |
|||
return _color(outgoing_rating()); |
|||
} |
|||
PEP_rating rating = PEP_rating_undefined; |
|||
status = outgoing_message_rating(pEp::Adapter::session(), *this, &rating); |
|||
_throw_status(status); |
|||
|
|||
Message Message::copy() |
|||
{ |
|||
message *dup = message_dup(*this); |
|||
if (!dup) |
|||
throw bad_alloc(); |
|||
return Message(dup); |
|||
} |
|||
return rating; |
|||
} |
|||
|
|||
Message Message::deepcopy(dict&) |
|||
{ |
|||
return copy(); |
|||
} |
|||
PEP_color Message::outgoing_color() |
|||
{ |
|||
return _color(outgoing_rating()); |
|||
} |
|||
|
|||
Message outgoing_message(Identity me) |
|||
{ |
|||
if (me.address().empty() || me.user_id().empty()) |
|||
throw runtime_error("at least address and user_id of own user needed"); |
|||
Message Message::copy() |
|||
{ |
|||
message *dup = message_dup(*this); |
|||
if (!dup) |
|||
throw bad_alloc(); |
|||
return Message(dup); |
|||
} |
|||
|
|||
::myself(pEp::Adapter::session(), me); |
|||
auto m = Message(PEP_dir_outgoing, &me); |
|||
return m; |
|||
} |
|||
Message Message::deepcopy(dict&) |
|||
{ |
|||
return copy(); |
|||
} |
|||
|
|||
static object update(Identity ident) |
|||
{ |
|||
if (ident.address().empty()) |
|||
throw runtime_error("at least address needed"); |
|||
update_identity(pEp::Adapter::session(), ident); |
|||
return object(ident); |
|||
} |
|||
Message outgoing_message(Identity me) |
|||
{ |
|||
if (me.address().empty() || me.user_id().empty()) |
|||
throw runtime_error("at least address and user_id of own user needed"); |
|||
|
|||
static boost::python::list update(boost::python::list il) |
|||
{ |
|||
for (int i=0; i<len(il); i++) { |
|||
update(extract< Identity >(il[i])); |
|||
} |
|||
::myself(pEp::Adapter::session(), me); |
|||
auto m = Message(PEP_dir_outgoing, &me); |
|||
return m; |
|||
} |
|||
|
|||
return il; |
|||
} |
|||
static object update(Identity ident) |
|||
{ |
|||
if (ident.address().empty()) |
|||
throw runtime_error("at least address needed"); |
|||
update_identity(pEp::Adapter::session(), ident); |
|||
return object(ident); |
|||
} |
|||
|
|||
Message incoming_message(string mime_text) |
|||
{ |
|||
auto m = Message(mime_text); |
|||
m.dir(PEP_dir_incoming); |
|||
static boost::python::list update(boost::python::list il) |
|||
{ |
|||
for (int i=0; i<len(il); i++) { |
|||
update(extract< Identity >(il[i])); |
|||
} |
|||
|
|||
try { |
|||
m.from(update(m.from())); |
|||
} |
|||
catch (out_of_range&) { } |
|||
return il; |
|||
} |
|||
|
|||
try { |
|||
m.recv_by(update(m.recv_by())); |
|||
} |
|||
catch (out_of_range&) { } |
|||
Message incoming_message(string mime_text) |
|||
{ |
|||
auto m = Message(mime_text); |
|||
m.dir(PEP_dir_incoming); |
|||
|
|||
m.to(update(m.to())); |
|||
m.cc(update(m.cc())); |
|||
m.reply_to(update(m.reply_to())); |
|||
try { |
|||
m.from(update(m.from())); |
|||
} |
|||
catch (out_of_range&) { } |
|||
|
|||
return m; |
|||
} |
|||
try { |
|||
m.recv_by(update(m.recv_by())); |
|||
} |
|||
catch (out_of_range&) { } |
|||
|
|||
m.to(update(m.to())); |
|||
m.cc(update(m.cc())); |
|||
m.reply_to(update(m.reply_to())); |
|||
|
|||
return m; |
|||
} |
|||
|
|||
} // namespace PythonAdapter
|
|||
} // namespace pEp {
|
|||
|
@ -1,168 +1,173 @@ |
|||
// This file is under GNU Affero General Public License 3.0
|
|||
// see LICENSE.txt
|
|||
|
|||
|
|||
// Engine
|
|||
#include <pEp/pEpEngine.h> |
|||
#include <pEp/message_api.h> |
|||
#include <pEp/sync_api.h> |
|||
#include <pEp/sync_codec.h> |
|||
#include <pEp/distribution_codec.h> |
|||
|
|||
// local
|
|||
#include "message_api.hh" |
|||
#include "basic_api.hh" |
|||
|
|||
namespace pEp { |
|||
namespace PythonAdapter { |
|||
Message encrypt_message(Message src, boost::python::list extra, int enc_format, |
|||
int flags) |
|||
{ |
|||
Identity _from = src.from(); |
|||
if (_from.address() == "") |
|||
throw invalid_argument("encrypt_message: src.from_.address empty"); |
|||
if (_from.username() == "") |
|||
throw invalid_argument("encrypt_message: src.from_.username empty"); |
|||
|
|||
if (_from.user_id() == "") |
|||
src.from().user_id(_from.address()); |
|||
|
|||
stringlist_t *_extra = to_stringlist(extra); |
|||
PEP_enc_format _enc_format = (PEP_enc_format) enc_format; |
|||
PEP_encrypt_flags_t _flags = (PEP_encrypt_flags_t) flags; |
|||
message *_dst = NULL; |
|||
|
|||
message *_src = src; |
|||
PEP_STATUS status = encrypt_message(pEp::Adapter::session(), _src, _extra, &_dst, |
|||
_enc_format, _flags); |
|||
free_stringlist(_extra); |
|||
_throw_status(status); |
|||
|
|||
if (!_dst || _dst == _src) |
|||
return Message(_src); |
|||
|
|||
return Message(_dst); |
|||
} |
|||
|
|||
boost::python::tuple decrypt_message(Message src, int flags) |
|||
{ |
|||
message *_dst = NULL; |
|||
stringlist_t *_keylist = NULL; |
|||
PEP_rating _rating = PEP_rating_undefined; |
|||
PEP_decrypt_flags_t _flags = (PEP_decrypt_flags_t) flags; |
|||
message *_src = src; |
|||
|
|||
PEP_STATUS status = ::decrypt_message(pEp::Adapter::session(), _src, &_dst, &_keylist, |
|||
&_rating, &_flags); |
|||
_throw_status(status); |
|||
|
|||
boost::python::list keylist; |
|||
if (_keylist) { |
|||
keylist = from_stringlist(_keylist); |
|||
free_stringlist(_keylist); |
|||
} |
|||
|
|||
Message dst = _dst ? Message(_dst) : Message(src); |
|||
return boost::python::make_tuple(dst, keylist, _rating, _flags); |
|||
} |
|||
|
|||
PEP_color _color(int rating) |
|||
{ |
|||
return ::color_from_rating((PEP_rating) rating); |
|||
} |
|||
|
|||
boost::python::tuple sync_decode(object buffer) |
|||
{ |
|||
Py_buffer src; |
|||
int result = PyObject_GetBuffer(buffer.ptr(), &src, PyBUF_CONTIG_RO); |
|||
if (result) |
|||
throw invalid_argument("need a contiguous buffer to read"); |
|||
|
|||
char *dst = NULL; |
|||
PEP_STATUS status = PER_to_XER_Sync_msg((char *) src.buf, src.len, &dst); |
|||
PyBuffer_Release(&src); |
|||
_throw_status(status); |
|||
|
|||
string _dst(dst); |
|||
free(dst); |
|||
return boost::python::make_tuple(_dst, 0); |
|||
} |
|||
|
|||
static boost::python::tuple sync_encode(string text) |
|||
{ |
|||
char *data = NULL; |
|||
size_t size = 0; |
|||
PEP_STATUS status = XER_to_PER_Sync_msg(text.c_str(), &data, &size); |
|||
_throw_status(status); |
|||
|
|||
PyObject *ba = PyBytes_FromStringAndSize(data, size); |
|||
free(data); |
|||
if (!ba) |
|||
throw bad_alloc(); |
|||
|
|||
return boost::python::make_tuple(object(handle<>(ba)), 0); |
|||
} |
|||
|
|||
boost::python::tuple Distribution_decode(object buffer) |
|||
{ |
|||
Py_buffer src; |
|||
int result = PyObject_GetBuffer(buffer.ptr(), &src, PyBUF_CONTIG_RO); |
|||
if (result) |
|||
throw invalid_argument("need a contiguous buffer to read"); |
|||
|
|||
char *dst = NULL; |
|||
PEP_STATUS status = PER_to_XER_Distribution_msg((char *) src.buf, src.len, &dst); |
|||
PyBuffer_Release(&src); |
|||
_throw_status(status); |
|||
|
|||
string _dst(dst); |
|||
free(dst); |
|||
return boost::python::make_tuple(_dst, 0); |
|||
} |
|||
|
|||
static boost::python::tuple Distribution_encode(string text) |
|||
{ |
|||
char *data = NULL; |
|||
size_t size = 0; |
|||
PEP_STATUS status = XER_to_PER_Distribution_msg(text.c_str(), &data, &size); |
|||
_throw_status(status); |
|||
|
|||
PyObject *ba = PyBytes_FromStringAndSize(data, size); |
|||
free(data); |
|||
if (!ba) |
|||
throw bad_alloc(); |
|||
|
|||
return boost::python::make_tuple(object(handle<>(ba)), 0); |
|||
} |
|||
|
|||
object sync_search(string name) |
|||
{ |
|||
if (name != "pep.sync") { |
|||
return object(); |
|||
} |
|||
else { |
|||
object codecs = import("codecs"); |
|||
object CodecInfo = codecs.attr("CodecInfo"); |
|||
|
|||
object _sync_decode = make_function(sync_decode); |
|||
object _sync_encode = make_function(sync_encode); |
|||
|
|||
return call< object >(CodecInfo.ptr(), _sync_encode, _sync_decode); |
|||
} |
|||
} |
|||
|
|||
object distribution_search(string name) |
|||
{ |
|||
if (name != "pep.distribution") { |
|||
return object(); |
|||
} |
|||
else { |
|||
object codecs = import("codecs"); |
|||
object CodecInfo = codecs.attr("CodecInfo"); |
|||
|
|||
object _distribution_decode = make_function(Distribution_decode); |
|||
object _distribution_encode = make_function(Distribution_encode); |
|||
|
|||
return call< object >(CodecInfo.ptr(), _distribution_encode, _distribution_decode); |
|||
} |
|||
} |
|||
namespace PythonAdapter { |
|||
using namespace std; |
|||
using namespace boost::python; |
|||
|
|||
Message encrypt_message(Message src, boost::python::list extra, int enc_format, int flags) |
|||
{ |
|||
Identity _from = src.from(); |
|||
if (_from.address() == "") |
|||
throw invalid_argument("encrypt_message: src.from_.address empty"); |
|||
if (_from.username() == "") |
|||
throw invalid_argument("encrypt_message: src.from_.username empty"); |
|||
|
|||
if (_from.user_id() == "") |
|||
src.from().user_id(_from.address()); |
|||
|
|||
stringlist_t *_extra = to_stringlist(extra); |
|||
PEP_enc_format _enc_format = (PEP_enc_format) enc_format; |
|||
PEP_encrypt_flags_t _flags = (PEP_encrypt_flags_t) flags; |
|||
message *_dst = NULL; |
|||
|
|||
message *_src = src; |
|||
PEP_STATUS status = encrypt_message(pEp::Adapter::session(), _src, _extra, &_dst, |
|||
_enc_format, _flags); |
|||
free_stringlist(_extra); |
|||
_throw_status(status); |
|||
|
|||
if (!_dst || _dst == _src) |
|||
return Message(_src); |
|||
|
|||
return Message(_dst); |
|||
} |
|||
|
|||
boost::python::tuple decrypt_message(Message src, int flags) |
|||
{ |
|||
message *_dst = NULL; |
|||
stringlist_t *_keylist = NULL; |
|||
PEP_rating _rating = PEP_rating_undefined; |
|||
PEP_decrypt_flags_t _flags = (PEP_decrypt_flags_t) flags; |
|||
message *_src = src; |
|||
|
|||
PEP_STATUS status = ::decrypt_message(pEp::Adapter::session(), _src, &_dst, &_keylist, |
|||
&_rating, &_flags); |
|||
_throw_status(status); |
|||
|
|||
boost::python::list keylist; |
|||
if (_keylist) { |
|||
keylist = from_stringlist(_keylist); |
|||
free_stringlist(_keylist); |
|||
} |
|||
|
|||
Message dst = _dst ? Message(_dst) : Message(src); |
|||
return boost::python::make_tuple(dst, keylist, _rating, _flags); |
|||
} |
|||
|
|||
PEP_color _color(int rating) |
|||
{ |
|||
return ::color_from_rating((PEP_rating) rating); |
|||
} |
|||
|
|||
boost::python::tuple sync_decode(object buffer) |
|||
{ |
|||
Py_buffer src; |
|||
int result = PyObject_GetBuffer(buffer.ptr(), &src, PyBUF_CONTIG_RO); |
|||
if (result) |
|||
throw invalid_argument("need a contiguous buffer to read"); |
|||
|
|||
char *dst = NULL; |
|||
PEP_STATUS status = PER_to_XER_Sync_msg((char *) src.buf, src.len, &dst); |
|||
PyBuffer_Release(&src); |
|||
_throw_status(status); |
|||
|
|||
string _dst(dst); |
|||
free(dst); |
|||
return boost::python::make_tuple(_dst, 0); |
|||
} |
|||
|
|||
static boost::python::tuple sync_encode(string text) |
|||
{ |
|||
char *data = NULL; |
|||
size_t size = 0; |
|||
PEP_STATUS status = XER_to_PER_Sync_msg(text.c_str(), &data, &size); |
|||
_throw_status(status); |
|||
|
|||
PyObject *ba = PyBytes_FromStringAndSize(data, size); |
|||
free(data); |
|||
if (!ba) |
|||
throw bad_alloc(); |
|||
|
|||
return boost::python::make_tuple(object(handle<>(ba)), 0); |
|||
} |
|||
|
|||
boost::python::tuple Distribution_decode(object buffer) |
|||
{ |
|||
Py_buffer src; |
|||
int result = PyObject_GetBuffer(buffer.ptr(), &src, PyBUF_CONTIG_RO); |
|||
if (result) |
|||
throw invalid_argument("need a contiguous buffer to read"); |
|||
|
|||
char *dst = NULL; |
|||
PEP_STATUS status = PER_to_XER_Distribution_msg((char *) src.buf, src.len, &dst); |
|||
PyBuffer_Release(&src); |
|||
_throw_status(status); |
|||
|
|||
string _dst(dst); |
|||
free(dst); |
|||
return boost::python::make_tuple(_dst, 0); |
|||
} |
|||
|
|||
static boost::python::tuple Distribution_encode(string text) |
|||
{ |
|||
char *data = NULL; |
|||
size_t size = 0; |
|||
PEP_STATUS status = XER_to_PER_Distribution_msg(text.c_str(), &data, &size); |
|||
_throw_status(status); |
|||
|
|||
PyObject *ba = PyBytes_FromStringAndSize(data, size); |
|||
free(data); |
|||
if (!ba) |
|||
throw bad_alloc(); |
|||
|
|||
return boost::python::make_tuple(object(handle<>(ba)), 0); |
|||
} |
|||
|
|||
object sync_search(string name) |
|||
{ |
|||
if (name != "pep.sync") { |
|||
return object(); |
|||
} |
|||
else { |
|||
object codecs = import("codecs"); |
|||
object CodecInfo = codecs.attr("CodecInfo"); |
|||
|
|||
object _sync_decode = make_function(sync_decode); |
|||
object _sync_encode = make_function(sync_encode); |
|||
|
|||
return call< object >(CodecInfo.ptr(), _sync_encode, _sync_decode); |
|||
} |
|||
} |
|||
|
|||
object distribution_search(string name) |
|||
{ |
|||
if (name != "pep.distribution") { |
|||
return object(); |
|||
} |
|||
else { |
|||
object codecs = import("codecs"); |
|||
object CodecInfo = codecs.attr("CodecInfo"); |
|||
|
|||
object _distribution_decode = make_function(Distribution_decode); |
|||
object _distribution_encode = make_function(Distribution_encode); |
|||
|
|||
return call< object >(CodecInfo.ptr(), _distribution_encode, _distribution_decode); |
|||
} |
|||
} |
|||
|
|||
} // namespace PythonAdapter
|
|||
} // namespace pEp {
|
|||
|
@ -1,21 +1,26 @@ |
|||
#pragma once |
|||
|
|||
// Engine
|
|||
#include <pEp/pEpEngine.h> |
|||
|
|||
// local
|
|||
#include "message.hh" |
|||
|
|||
namespace pEp { |
|||
namespace PythonAdapter { |
|||
extern string device_name; |
|||
void config_passive_mode(bool enable); |
|||
void config_unencrypted_subject(bool enable); |
|||
void key_reset_user(string user_id, string fpr); |
|||
void key_reset_all_own_keys(); |
|||
void _throw_status(PEP_STATUS status); |
|||
void messageToSend(Message msg); |
|||
PEP_STATUS _messageToSend(::message *msg); |
|||
PEP_STATUS _ensure_passphrase(PEP_SESSION session, const char *fpr); |
|||
// void do_sync_protocol();
|
|||
// extern Adapter adapter;
|
|||
} |
|||
} |
|||
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); |
|||
void messageToSend(Message msg); |
|||
PEP_STATUS _messageToSend(::message *msg); |
|||
PEP_STATUS _ensure_passphrase(PEP_SESSION session, const char *fpr); |
|||
// void do_sync_protocol();
|
|||
// extern Adapter adapter;
|
|||
|
|||
} // namespace PythonAdapter
|
|||
} // namespace pEp {
|
|||
|
|||
|
@ -1,180 +1,184 @@ |
|||
// This file is under GNU Affero General Public License 3.0
|
|||
// see LICENSE.txt
|
|||
|
|||
// System
|
|||
#include <cstdlib> |
|||
#include <boost/python.hpp> |
|||
#include <boost/locale.hpp> |
|||
#include <cstdlib> |
|||
|
|||
// local
|
|||
#include "str_attr.hh" |
|||
|
|||
namespace pEp { |
|||
namespace utility { |
|||
using namespace std; |
|||
using namespace boost::locale; |
|||
namespace PythonAdapter { |
|||
using namespace std; |
|||
using namespace boost::python; |
|||
using namespace boost::locale; |
|||
|
|||
object repr(object s) |
|||
{ |
|||
return s.attr("__repr__")(); |
|||
} |
|||
|
|||
object repr(object s) |
|||
{ |
|||
return s.attr("__repr__")(); |
|||
} |
|||
string repr(string s) |
|||
{ |
|||
str _s = s.c_str(); |
|||
object _r = _s.attr("__repr__")(); |
|||
string r = extract< string >(_r); |
|||
return r; |
|||
} |
|||
|
|||
string repr(string s) |
|||
{ |
|||
str _s = s.c_str(); |
|||
object _r = _s.attr("__repr__")(); |
|||
string r = extract< string >(_r); |
|||
return r; |
|||
} |
|||
string str_attr(char *&str) |
|||
{ |
|||
if (!str) |
|||
return string(""); |
|||
return string(str); |
|||
} |
|||
|
|||
string str_attr(char *&str) |
|||
{ |
|||
if (!str) |
|||
return string(""); |
|||
return string(str); |
|||
} |
|||
void str_attr(char *&str, string value) |
|||
{ |
|||
string normalized = normalize(value, norm_nfc); |
|||
free(str); |
|||
str = strdup(normalized.c_str()); |
|||
if (!str) |
|||
throw bad_alloc(); |
|||
} |
|||
|
|||
void str_attr(char *&str, string value) |
|||
{ |
|||
string normalized = normalize(value, norm_nfc); |
|||
free(str); |
|||
str = strdup(normalized.c_str()); |
|||
if (!str) |
|||
throw bad_alloc(); |
|||
} |
|||
time_t timestamp_attr(timestamp *&ts) |
|||
{ |
|||
if (!ts) |
|||
return 0; |
|||
|
|||
time_t timestamp_attr(timestamp *&ts) |
|||
{ |
|||
if (!ts) |
|||
return 0; |
|||
return timegm(ts); |
|||
} |
|||
|
|||
return timegm(ts); |
|||
} |
|||
void timestamp_attr(timestamp *&ts, time_t value) |
|||
{ |
|||
free_timestamp(ts); |
|||
ts = new_timestamp(value); |
|||
} |
|||
|
|||
void timestamp_attr(timestamp *&ts, time_t value) |
|||
{ |
|||
free_timestamp(ts); |
|||
ts = new_timestamp(value); |
|||
} |
|||
boost::python::list strlist_attr(stringlist_t *&sl) |
|||
{ |
|||
boost::python::list result; |
|||
|
|||
boost::python::list strlist_attr(stringlist_t *&sl) |
|||
{ |
|||
boost::python::list result; |
|||
for (stringlist_t *_sl = sl; _sl && _sl->value; _sl = _sl->next) { |
|||
string s(_sl->value); |
|||
result.append(object(s)); |
|||
} |
|||
|
|||
for (stringlist_t *_sl = sl; _sl && _sl->value; _sl = _sl->next) { |
|||
string s(_sl->value); |
|||
result.append(object(s)); |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
return result; |
|||
void strlist_attr(stringlist_t *&sl, boost::python::list value) |
|||
{ |
|||
stringlist_t *_sl = new_stringlist(NULL); |
|||
if (!_sl) |
|||
throw bad_alloc(); |
|||
|
|||
stringlist_t *_s = _sl; |
|||
for (int i=0; i<len(value); i++) { |
|||
extract< string > extract_string(value[i]); |
|||
if (!extract_string.check()) { |
|||
free_stringlist(_sl); |
|||
} |
|||
|
|||
void strlist_attr(stringlist_t *&sl, boost::python::list value) |
|||
{ |
|||
stringlist_t *_sl = new_stringlist(NULL); |
|||
if (!_sl) |
|||
throw bad_alloc(); |
|||
|
|||
stringlist_t *_s = _sl; |
|||
for (int i=0; i<len(value); i++) { |
|||
extract< string > extract_string(value[i]); |
|||
if (!extract_string.check()) { |
|||
free_stringlist(_sl); |
|||
} |
|||
string s = extract_string(); |
|||
s = normalize(s, norm_nfc); |
|||
_s = stringlist_add(_s, s.c_str()); |
|||
if (!_s) { |
|||
free_stringlist(_sl); |
|||
throw bad_alloc(); |
|||
} |
|||
} |
|||
|
|||
free_stringlist(sl); |
|||
sl = _sl; |
|||
string s = extract_string(); |
|||
s = normalize(s, norm_nfc); |
|||
_s = stringlist_add(_s, s.c_str()); |
|||
if (!_s) { |
|||
free_stringlist(_sl); |
|||
throw bad_alloc(); |
|||
} |
|||
} |
|||
|
|||
dict strdict_attr(stringpair_list_t *&spl) |
|||
{ |
|||
dict result; |
|||
free_stringlist(sl); |
|||
sl = _sl; |
|||
} |
|||
|
|||
for (stringpair_list_t *_spl = spl; _spl && _spl->value; _spl = |
|||
_spl->next) { |
|||
stringpair_t *p = _spl->value; |
|||
if (p->key && p->value) { |
|||
string key(p->key); |
|||
string value(p->value); |
|||
dict strdict_attr(stringpair_list_t *&spl) |
|||
{ |
|||
dict result; |
|||
|
|||
result[key] = value; |
|||
} |
|||
} |
|||
for (stringpair_list_t *_spl = spl; _spl && _spl->value; _spl = |
|||
_spl->next) { |
|||
stringpair_t *p = _spl->value; |
|||
if (p->key && p->value) { |
|||
string key(p->key); |
|||
string value(p->value); |
|||
|
|||
return result; |
|||
result[key] = value; |
|||
} |
|||
} |
|||
|
|||
void strdict_attr(stringpair_list_t *&spl, dict value) |
|||
{ |
|||
stringpair_list_t *_spl = new_stringpair_list(NULL); |
|||
if (!_spl) |
|||
throw bad_alloc(); |
|||
|
|||
stringpair_list_t *_s = _spl; |
|||
for (int i=0; i<len(value); i++) { |
|||
extract< string > extract_key(value.keys()[i]); |
|||
extract< string > extract_value(value.values()[i]); |
|||
|
|||
if (!(extract_key.check() && extract_value.check())) |
|||
free_stringpair_list(_spl); |
|||
|
|||
string key = extract_key(); |
|||
key = normalize(key, norm_nfc); |
|||
string _value = extract_value(); |
|||
_value = normalize(_value, norm_nfc); |
|||
stringpair_t *pair = new_stringpair(key.c_str(), _value.c_str()); |
|||
if (!pair) { |
|||
free_stringpair_list(_spl); |
|||
throw bad_alloc(); |
|||
} |
|||
_s = stringpair_list_add(_s, pair); |
|||
if (!_s) { |
|||
free_stringpair_list(_spl); |
|||
throw bad_alloc(); |
|||
} |
|||
} |
|||
|
|||
free_stringpair_list(spl); |
|||
spl = _spl; |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
stringlist_t *to_stringlist(boost::python::list l) |
|||
{ |
|||
stringlist_t *result = new_stringlist(NULL); |
|||
if (!result) |
|||
throw bad_alloc(); |
|||
|
|||
stringlist_t *_s = result; |
|||
for (int i=0; i<len(l); i++) { |
|||
extract< string > extract_string(l[i]); |
|||
if (!extract_string.check()) |
|||
free_stringlist(result); |
|||
string s = extract_string(); |
|||
_s = stringlist_add(_s, s.c_str()); |
|||
if (!_s) { |
|||
free_stringlist(result); |
|||
throw bad_alloc(); |
|||
} |
|||
} |
|||
|
|||
return result; |
|||
void strdict_attr(stringpair_list_t *&spl, dict value) |
|||
{ |
|||
stringpair_list_t *_spl = new_stringpair_list(NULL); |
|||
if (!_spl) |
|||
throw bad_alloc(); |
|||
|
|||
stringpair_list_t *_s = _spl; |
|||
for (int i=0; i<len(value); i++) { |
|||
extract< string > extract_key(value.keys()[i]); |
|||
extract< string > extract_value(value.values()[i]); |
|||
|
|||
if (!(extract_key.check() && extract_value.check())) |
|||
free_stringpair_list(_spl); |
|||
|
|||
string key = extract_key(); |
|||
key = normalize(key, norm_nfc); |
|||
string _value = extract_value(); |
|||
_value = normalize(_value, norm_nfc); |
|||
stringpair_t *pair = new_stringpair(key.c_str(), _value.c_str()); |
|||
if (!pair) { |
|||
free_stringpair_list(_spl); |
|||
throw bad_alloc(); |
|||
} |
|||
_s = stringpair_list_add(_s, pair); |
|||
if (!_s) { |
|||
free_stringpair_list(_spl); |
|||
throw bad_alloc(); |
|||
} |
|||
} |
|||
|
|||
boost::python::list from_stringlist(const stringlist_t *sl) |
|||
{ |
|||
boost::python::list result; |
|||
for (const stringlist_t *_sl = sl; _sl && _sl->value; _sl = _sl->next) { |
|||
string s = _sl->value; |
|||
result.append(s); |
|||
} |
|||
return result; |
|||
free_stringpair_list(spl); |
|||
spl = _spl; |
|||
} |
|||
|
|||
stringlist_t *to_stringlist(boost::python::list l) |
|||
{ |
|||
stringlist_t *result = new_stringlist(NULL); |
|||
if (!result) |
|||
throw bad_alloc(); |
|||
|
|||
stringlist_t *_s = result; |
|||
for (int i=0; i<len(l); i++) { |
|||
extract< string > extract_string(l[i]); |
|||
if (!extract_string.check()) |
|||
free_stringlist(result); |
|||
string s = extract_string(); |
|||
_s = stringlist_add(_s, s.c_str()); |
|||
if (!_s) { |
|||
free_stringlist(result); |
|||
throw bad_alloc(); |
|||
} |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
boost::python::list from_stringlist(const stringlist_t *sl) |
|||
{ |
|||
boost::python::list result; |
|||
for (const stringlist_t *_sl = sl; _sl && _sl->value; _sl = _sl->next) { |
|||
string s = _sl->value; |
|||
result.append(s); |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
} // namespace PythonAdapter
|
|||
} // namespace pEp {
|
|||
|
|||
|
@ -1,124 +1,129 @@ |
|||
// This file is under GNU Affero General Public License 3.0
|
|||
// see LICENSE.txt
|
|||
|
|||
// System
|
|||
#include <cassert> |
|||
|
|||
// local
|
|||
#include "user_interface.hh" |
|||
|
|||
namespace pEp { |
|||
namespace PythonAdapter { |
|||
UserInterface *UserInterface::_ui = nullptr; |
|||
|
|||
UserInterface::UserInterface() |
|||
{ |
|||
if (_ui) |
|||
throw runtime_error("only one UserInterface thread allowed"); |
|||
_ui = this; |
|||
} |
|||
namespace PythonAdapter { |
|||
|
|||
UserInterface::~UserInterface() |
|||
{ |
|||
_ui = nullptr; |
|||
} |
|||
UserInterface *UserInterface::_ui = nullptr; |
|||
|
|||
UserInterface_callback::UserInterface_callback(PyObject *self) : |
|||
UserInterface(), _self(self) |
|||
{ |
|||
// adapter.ui_object(self);
|
|||
PEP_STATUS status = ::register_sync_callbacks(pEp::Adapter::session(), |
|||
(void *) this, _notifyHandshake, retrieve_next_sync_event); |
|||
assert(status == PEP_STATUS_OK); |
|||
if (status) |
|||
_throw_status(status); |
|||
} |
|||
UserInterface::UserInterface() |
|||
{ |
|||
if (_ui) |
|||
throw runtime_error("only one UserInterface thread allowed"); |
|||
_ui = this; |
|||
} |
|||
|
|||
UserInterface_callback::~UserInterface_callback() |
|||
{ |
|||
::unregister_sync_callbacks(pEp::Adapter::session()); |
|||
} |
|||
UserInterface::~UserInterface() |
|||
{ |
|||
_ui = nullptr; |
|||
} |
|||
|
|||
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(pEp::Adapter::session(), |
|||
(void *) this, _notifyHandshake, retrieve_next_sync_event); |
|||
assert(status == PEP_STATUS_OK); |
|||
if (status) |
|||
_throw_status(status); |
|||
} |
|||
|
|||
auto that = dynamic_cast< UserInterface_callback * >(_ui); |
|||
that->notifyHandshake(Identity(me), Identity(partner), signal); |
|||
UserInterface_callback::~UserInterface_callback() |
|||
{ |
|||
::unregister_sync_callbacks(pEp::Adapter::session()); |
|||
} |
|||
|
|||
return PEP_STATUS_OK; |
|||
} |
|||
PEP_STATUS UserInterface::_notifyHandshake( |
|||
pEp_identity *me, pEp_identity *partner, |
|||
sync_handshake_signal signal |
|||
) |
|||
{ |
|||
if (!(me && partner)) |
|||
return PEP_ILLEGAL_VALUE; |
|||
|
|||
void UserInterface::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(); |
|||
auto that = dynamic_cast< UserInterface_callback * >(_ui); |
|||
that->notifyHandshake(Identity(me), Identity(partner), signal); |
|||
|
|||
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; |
|||
} |
|||
} |
|||
return PEP_STATUS_OK; |
|||
} |
|||
|
|||
void UserInterface::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(); |
|||
|
|||
PEP_STATUS status = ::deliverHandshakeResult(pEp::Adapter::session(), |
|||
(sync_handshake_result) result, shared_identities); |
|||
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_status(status); |
|||
throw ex; |
|||
} |
|||
} |
|||
|
|||
PEP_rating UserInterface::get_key_rating_for_user(string user_id, string fpr) |
|||
{ |
|||
PEP_rating result; |
|||
PEP_STATUS status = |
|||
::get_key_rating_for_user(pEp::Adapter::session(), |
|||
user_id.c_str(), fpr.c_str(), &result); |
|||
_throw_status(status); |
|||
return result; |
|||
} |
|||
PEP_STATUS status = ::deliverHandshakeResult(pEp::Adapter::session(), |
|||
(sync_handshake_result) result, shared_identities); |
|||
free_identity_list(shared_identities); |
|||
_throw_status(status); |
|||
} |
|||
|
|||
// SYNC_EVENT UserInterface::retrieve_next_sync_event(void *management, unsigned threshold)
|
|||
// {
|
|||
// time_t started = time(nullptr);
|
|||
// bool timeout = false;
|
|||
PEP_rating UserInterface::get_key_rating_for_user(string user_id, string fpr) |
|||
{ |
|||
PEP_rating result; |
|||
PEP_STATUS status = |
|||
::get_key_rating_for_user(pEp::Adapter::session(), |
|||
user_id.c_str(), fpr.c_str(), &result); |
|||
_throw_status(status); |
|||
return result; |
|||
} |
|||
|
|||
//SYNC_EVENT UserInterface::retrieve_next_sync_event(void *management, unsigned threshold)
|
|||
//{
|
|||
// time_t started = time(nullptr);
|
|||
// bool timeout = false;
|
|||
//
|
|||
// while (adapter.queue().empty()) {
|
|||
// int i = 0;
|
|||
// ++i;
|
|||
// if (i > 10) {
|
|||
// if (time(nullptr) > started + threshold) {
|
|||
// timeout = true;
|
|||
// break;
|
|||
// }
|
|||
// i = 0;
|
|||
// }
|
|||
// nanosleep((const struct timespec[]){{0, 100000000L}}, NULL);
|
|||
// while (adapter.queue().empty()) {
|
|||
// int i = 0;
|
|||
// ++i;
|
|||
// if (i > 10) {
|
|||
// if (time(nullptr) > started + threshold) {
|
|||
// timeout = true;
|
|||
// break;
|
|||
// }
|
|||
// i = 0;
|
|||
// }
|
|||
// nanosleep((const struct timespec[]){{0, 100000000L}}, NULL);
|
|||
// }
|
|||
//
|
|||
// if (timeout)
|
|||
// return new_sync_timeout_event();
|
|||
// if (timeout)
|
|||
// return new_sync_timeout_event();
|
|||
//
|
|||
// return adapter.queue().pop_front();
|
|||
// }
|
|||
// return adapter.queue().pop_front();
|
|||
//}
|
|||
|
|||
void UserInterface_callback::notifyHandshake( |
|||
Identity me, Identity partner, sync_handshake_signal signal) |
|||
{ |
|||
call_method< void >(_self, "notifyHandshake", me, partner, signal); |
|||
} |
|||
} |
|||
void UserInterface_callback::notifyHandshake( |
|||
Identity me, Identity partner, sync_handshake_signal signal) |
|||
{ |
|||
call_method< void >(_self, "notifyHandshake", me, partner, signal); |
|||
} |
|||
|
|||
} // namespace PythonAdapter
|
|||
} // namespace pEp {
|
|||
|
|||
|
Loading…
Reference in new issue