python: Adapt to 'gpgme_op_interact'.
* lang/python/examples/inter-edit.py: Update example. * lang/python/gpgme.i (gpgme_edit_cb_t): Turn into 'gpgme_interact_cb_t'. * lang/python/helpers.c (_pyme_edit_cb): Turn into '_pyme_interact_cb_t'. * lang/python/private.h (_pyme_edit_cb): Likewise. * lang/python/pyme/constants/__init__.py: Replace numeric status codes with the keywords. * lang/python/pyme/constants/status.py: Likewise. * lang/python/pyme/core.py (Context.interact): New method. (Context.op_edit): Deprecate, update docstring, implement using Context.interact. * lang/python/tests/t-edit.py: Test both interfaces. Signed-off-by: Justus Winter <justus@g10code.com>
This commit is contained in:
parent
5259f9de46
commit
a458e7fe20
@ -23,13 +23,6 @@ del absolute_import, print_function, unicode_literals
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
import pyme
|
import pyme
|
||||||
import pyme.constants.status
|
|
||||||
|
|
||||||
# Get names for the status codes
|
|
||||||
status2str = {}
|
|
||||||
for name in dir(pyme.constants.status):
|
|
||||||
if not name.startswith('__') and name != "util":
|
|
||||||
status2str[getattr(pyme.constants.status, name)] = name
|
|
||||||
|
|
||||||
if len(sys.argv) != 2:
|
if len(sys.argv) != 2:
|
||||||
sys.exit("Usage: %s <Gpg key pattern>\n" % sys.argv[0])
|
sys.exit("Usage: %s <Gpg key pattern>\n" % sys.argv[0])
|
||||||
@ -46,11 +39,11 @@ with pyme.Context() as c:
|
|||||||
key = keys[0]
|
key = keys[0]
|
||||||
print("Editing key {} ({}):".format(key.uids[0].uid, key.subkeys[0].fpr))
|
print("Editing key {} ({}):".format(key.uids[0].uid, key.subkeys[0].fpr))
|
||||||
|
|
||||||
def edit_fnc(status, args):
|
def edit_fnc(keyword, args):
|
||||||
print("Status: {} ({}), args: {} > ".format(
|
print("Status: {} ({}), args: {} > ".format(
|
||||||
status2str[status], status, args), end='', flush=True)
|
keyword, status, args), end='', flush=True)
|
||||||
|
|
||||||
if not 'GET' in status2str[status]:
|
if not 'GET' in keyword:
|
||||||
# no prompt
|
# no prompt
|
||||||
print()
|
print()
|
||||||
return None
|
return None
|
||||||
@ -60,4 +53,4 @@ with pyme.Context() as c:
|
|||||||
except EOFError:
|
except EOFError:
|
||||||
return "quit"
|
return "quit"
|
||||||
|
|
||||||
c.op_edit(key, edit_fnc, None, sys.stdout)
|
c.interact(key, edit_fnc, sink=sys.stdout)
|
||||||
|
@ -476,15 +476,15 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Include mapper for edit callbacks
|
/* Include mapper for interact callbacks. */
|
||||||
%typemap(in) (gpgme_edit_cb_t fnc, void *fnc_value) {
|
%typemap(in) (gpgme_interact_cb_t fnc, void *fnc_value) {
|
||||||
if (! PyTuple_Check($input))
|
if (! PyTuple_Check($input))
|
||||||
return PyErr_Format(PyExc_TypeError, "edit callback must be a tuple");
|
return PyErr_Format(PyExc_TypeError, "interact callback must be a tuple");
|
||||||
if (PyTuple_Size($input) != 2 && PyTuple_Size($input) != 3)
|
if (PyTuple_Size($input) != 2 && PyTuple_Size($input) != 3)
|
||||||
return PyErr_Format(PyExc_TypeError,
|
return PyErr_Format(PyExc_TypeError,
|
||||||
"edit callback must be a tuple of size 2 or 3");
|
"interact callback must be a tuple of size 2 or 3");
|
||||||
|
|
||||||
$1 = (gpgme_edit_cb_t) _pyme_edit_cb;
|
$1 = (gpgme_interact_cb_t) _pyme_interact_cb;
|
||||||
$2 = $input;
|
$2 = $input;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -656,11 +656,16 @@ pyme_set_status_cb(PyObject *self, PyObject *cb) {
|
|||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return Py_None;
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Edit callbacks. */
|
|
||||||
gpgme_error_t _pyme_edit_cb(void *opaque, gpgme_status_code_t status,
|
/* Interact callbacks. */
|
||||||
const char *args, int fd) {
|
gpgme_error_t
|
||||||
|
_pyme_interact_cb(void *opaque, const char *keyword,
|
||||||
|
const char *args, int fd)
|
||||||
|
{
|
||||||
PyObject *func = NULL, *dataarg = NULL, *pyargs = NULL, *retval = NULL;
|
PyObject *func = NULL, *dataarg = NULL, *pyargs = NULL, *retval = NULL;
|
||||||
|
PyObject *py_keyword;
|
||||||
PyObject *pyopaque = (PyObject *) opaque;
|
PyObject *pyopaque = (PyObject *) opaque;
|
||||||
gpgme_error_t err_status = 0;
|
gpgme_error_t err_status = 0;
|
||||||
PyObject *self = NULL;
|
PyObject *self = NULL;
|
||||||
@ -678,7 +683,15 @@ gpgme_error_t _pyme_edit_cb(void *opaque, gpgme_status_code_t status,
|
|||||||
pyargs = PyTuple_New(2);
|
pyargs = PyTuple_New(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyTuple_SetItem(pyargs, 0, PyLong_FromLong((long) status));
|
if (keyword)
|
||||||
|
py_keyword = PyUnicode_FromString(keyword);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
py_keyword = Py_None;
|
||||||
|
}
|
||||||
|
|
||||||
|
PyTuple_SetItem(pyargs, 0, py_keyword);
|
||||||
PyTuple_SetItem(pyargs, 1, PyUnicode_FromString(args));
|
PyTuple_SetItem(pyargs, 1, PyUnicode_FromString(args));
|
||||||
if (dataarg) {
|
if (dataarg) {
|
||||||
Py_INCREF(dataarg); /* Because GetItem doesn't give a ref but SetItem taketh away */
|
Py_INCREF(dataarg); /* Because GetItem doesn't give a ref but SetItem taketh away */
|
||||||
@ -726,7 +739,9 @@ gpgme_error_t _pyme_edit_cb(void *opaque, gpgme_status_code_t status,
|
|||||||
Py_XDECREF(retval);
|
Py_XDECREF(retval);
|
||||||
return err_status;
|
return err_status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Data callbacks. */
|
/* Data callbacks. */
|
||||||
|
|
||||||
/* Read up to SIZE bytes into buffer BUFFER from the data object with
|
/* Read up to SIZE bytes into buffer BUFFER from the data object with
|
||||||
|
@ -34,9 +34,8 @@ PyObject *_pyme_obj2gpgme_data_t(PyObject *input, int argnum,
|
|||||||
|
|
||||||
PyObject *_pyme_wrap_result(PyObject *fragile, const char *classname);
|
PyObject *_pyme_wrap_result(PyObject *fragile, const char *classname);
|
||||||
|
|
||||||
gpgme_error_t _pyme_edit_cb(void *opaque, gpgme_status_code_t status,
|
gpgme_error_t _pyme_interact_cb(void *opaque, const char *keyword,
|
||||||
const char *args, int fd);
|
const char *args, int fd);
|
||||||
|
|
||||||
gpgme_error_t _pyme_assuan_data_cb (void *hook,
|
gpgme_error_t _pyme_assuan_data_cb (void *hook,
|
||||||
const void *data, size_t datalen);
|
const void *data, size_t datalen);
|
||||||
gpgme_error_t _pyme_assuan_inquire_cb (void *hook,
|
gpgme_error_t _pyme_assuan_inquire_cb (void *hook,
|
||||||
|
@ -7,3 +7,108 @@ util.process_constants('GPGME_', globals())
|
|||||||
|
|
||||||
__all__ = ['data', 'event', 'import', 'keylist', 'md', 'pk',
|
__all__ = ['data', 'event', 'import', 'keylist', 'md', 'pk',
|
||||||
'protocol', 'sig', 'sigsum', 'status', 'validity']
|
'protocol', 'sig', 'sigsum', 'status', 'validity']
|
||||||
|
|
||||||
|
# GPGME 1.7 replaced gpgme_op_edit with gpgme_op_interact. We
|
||||||
|
# implement pyme.Context.op_edit using gpgme_op_interact, so the
|
||||||
|
# callbacks will be called with string keywords instead of numeric
|
||||||
|
# status messages. Code that is using these constants will continue
|
||||||
|
# to work.
|
||||||
|
|
||||||
|
STATUS_ABORT = "ABORT"
|
||||||
|
STATUS_ALREADY_SIGNED = "ALREADY_SIGNED"
|
||||||
|
STATUS_ATTRIBUTE = "ATTRIBUTE"
|
||||||
|
STATUS_BACKUP_KEY_CREATED = "BACKUP_KEY_CREATED"
|
||||||
|
STATUS_BAD_PASSPHRASE = "BAD_PASSPHRASE"
|
||||||
|
STATUS_BADARMOR = "BADARMOR"
|
||||||
|
STATUS_BADMDC = "BADMDC"
|
||||||
|
STATUS_BADSIG = "BADSIG"
|
||||||
|
STATUS_BEGIN_DECRYPTION = "BEGIN_DECRYPTION"
|
||||||
|
STATUS_BEGIN_ENCRYPTION = "BEGIN_ENCRYPTION"
|
||||||
|
STATUS_BEGIN_SIGNING = "BEGIN_SIGNING"
|
||||||
|
STATUS_BEGIN_STREAM = "BEGIN_STREAM"
|
||||||
|
STATUS_CARDCTRL = "CARDCTRL"
|
||||||
|
STATUS_DECRYPTION_FAILED = "DECRYPTION_FAILED"
|
||||||
|
STATUS_DECRYPTION_INFO = "DECRYPTION_INFO"
|
||||||
|
STATUS_DECRYPTION_OKAY = "DECRYPTION_OKAY"
|
||||||
|
STATUS_DELETE_PROBLEM = "DELETE_PROBLEM"
|
||||||
|
STATUS_ENC_TO = "ENC_TO"
|
||||||
|
STATUS_END_DECRYPTION = "END_DECRYPTION"
|
||||||
|
STATUS_END_ENCRYPTION = "END_ENCRYPTION"
|
||||||
|
STATUS_END_STREAM = "END_STREAM"
|
||||||
|
STATUS_ENTER = "ENTER"
|
||||||
|
STATUS_ERRMDC = "ERRMDC"
|
||||||
|
STATUS_ERROR = "ERROR"
|
||||||
|
STATUS_ERRSIG = "ERRSIG"
|
||||||
|
STATUS_EXPKEYSIG = "EXPKEYSIG"
|
||||||
|
STATUS_EXPSIG = "EXPSIG"
|
||||||
|
STATUS_FAILURE = "FAILURE"
|
||||||
|
STATUS_FILE_DONE = "FILE_DONE"
|
||||||
|
STATUS_FILE_ERROR = "FILE_ERROR"
|
||||||
|
STATUS_FILE_START = "FILE_START"
|
||||||
|
STATUS_GET_BOOL = "GET_BOOL"
|
||||||
|
STATUS_GET_HIDDEN = "GET_HIDDEN"
|
||||||
|
STATUS_GET_LINE = "GET_LINE"
|
||||||
|
STATUS_GOOD_PASSPHRASE = "GOOD_PASSPHRASE"
|
||||||
|
STATUS_GOODMDC = "GOODMDC"
|
||||||
|
STATUS_GOODSIG = "GOODSIG"
|
||||||
|
STATUS_GOT_IT = "GOT_IT"
|
||||||
|
STATUS_IMPORT_OK = "IMPORT_OK"
|
||||||
|
STATUS_IMPORT_PROBLEM = "IMPORT_PROBLEM"
|
||||||
|
STATUS_IMPORT_RES = "IMPORT_RES"
|
||||||
|
STATUS_IMPORTED = "IMPORTED"
|
||||||
|
STATUS_INQUIRE_MAXLEN = "INQUIRE_MAXLEN"
|
||||||
|
STATUS_INV_RECP = "INV_RECP"
|
||||||
|
STATUS_INV_SGNR = "INV_SGNR"
|
||||||
|
STATUS_KEY_CONSIDERED = "KEY_CONSIDERED"
|
||||||
|
STATUS_KEY_CREATED = "KEY_CREATED"
|
||||||
|
STATUS_KEY_NOT_CREATED = "KEY_NOT_CREATED"
|
||||||
|
STATUS_KEYEXPIRED = "KEYEXPIRED"
|
||||||
|
STATUS_KEYREVOKED = "KEYREVOKED"
|
||||||
|
STATUS_LEAVE = "LEAVE"
|
||||||
|
STATUS_MISSING_PASSPHRASE = "MISSING_PASSPHRASE"
|
||||||
|
STATUS_MOUNTPOINT = "MOUNTPOINT"
|
||||||
|
STATUS_NEED_PASSPHRASE = "NEED_PASSPHRASE"
|
||||||
|
STATUS_NEED_PASSPHRASE_PIN = "NEED_PASSPHRASE_PIN"
|
||||||
|
STATUS_NEED_PASSPHRASE_SYM = "NEED_PASSPHRASE_SYM"
|
||||||
|
STATUS_NEWSIG = "NEWSIG"
|
||||||
|
STATUS_NO_PUBKEY = "NO_PUBKEY"
|
||||||
|
STATUS_NO_RECP = "NO_RECP"
|
||||||
|
STATUS_NO_SECKEY = "NO_SECKEY"
|
||||||
|
STATUS_NO_SGNR = "NO_SGNR"
|
||||||
|
STATUS_NODATA = "NODATA"
|
||||||
|
STATUS_NOTATION_DATA = "NOTATION_DATA"
|
||||||
|
STATUS_NOTATION_FLAGS = "NOTATION_FLAGS"
|
||||||
|
STATUS_NOTATION_NAME = "NOTATION_NAME"
|
||||||
|
STATUS_PINENTRY_LAUNCHED = "PINENTRY_LAUNCHED"
|
||||||
|
STATUS_PKA_TRUST_BAD = "PKA_TRUST_BAD"
|
||||||
|
STATUS_PKA_TRUST_GOOD = "PKA_TRUST_GOOD"
|
||||||
|
STATUS_PLAINTEXT = "PLAINTEXT"
|
||||||
|
STATUS_PLAINTEXT_LENGTH = "PLAINTEXT_LENGTH"
|
||||||
|
STATUS_POLICY_URL = "POLICY_URL"
|
||||||
|
STATUS_PROGRESS = "PROGRESS"
|
||||||
|
STATUS_REVKEYSIG = "REVKEYSIG"
|
||||||
|
STATUS_RSA_OR_IDEA = "RSA_OR_IDEA"
|
||||||
|
STATUS_SC_OP_FAILURE = "SC_OP_FAILURE"
|
||||||
|
STATUS_SC_OP_SUCCESS = "SC_OP_SUCCESS"
|
||||||
|
STATUS_SESSION_KEY = "SESSION_KEY"
|
||||||
|
STATUS_SHM_GET = "SHM_GET"
|
||||||
|
STATUS_SHM_GET_BOOL = "SHM_GET_BOOL"
|
||||||
|
STATUS_SHM_GET_HIDDEN = "SHM_GET_HIDDEN"
|
||||||
|
STATUS_SHM_INFO = "SHM_INFO"
|
||||||
|
STATUS_SIG_CREATED = "SIG_CREATED"
|
||||||
|
STATUS_SIG_ID = "SIG_ID"
|
||||||
|
STATUS_SIG_SUBPACKET = "SIG_SUBPACKET"
|
||||||
|
STATUS_SIGEXPIRED = "SIGEXPIRED"
|
||||||
|
STATUS_SUCCESS = "SUCCESS"
|
||||||
|
STATUS_TOFU_STATS = "TOFU_STATS"
|
||||||
|
STATUS_TOFU_STATS_LONG = "TOFU_STATS_LONG"
|
||||||
|
STATUS_TOFU_USER = "TOFU_USER"
|
||||||
|
STATUS_TRUNCATED = "TRUNCATED"
|
||||||
|
STATUS_TRUST_FULLY = "TRUST_FULLY"
|
||||||
|
STATUS_TRUST_MARGINAL = "TRUST_MARGINAL"
|
||||||
|
STATUS_TRUST_NEVER = "TRUST_NEVER"
|
||||||
|
STATUS_TRUST_ULTIMATE = "TRUST_ULTIMATE"
|
||||||
|
STATUS_TRUST_UNDEFINED = "TRUST_UNDEFINED"
|
||||||
|
STATUS_UNEXPECTED = "UNEXPECTED"
|
||||||
|
STATUS_USERID_HINT = "USERID_HINT"
|
||||||
|
STATUS_VALIDSIG = "VALIDSIG"
|
||||||
|
@ -18,5 +18,107 @@
|
|||||||
from __future__ import absolute_import, print_function, unicode_literals
|
from __future__ import absolute_import, print_function, unicode_literals
|
||||||
del absolute_import, print_function, unicode_literals
|
del absolute_import, print_function, unicode_literals
|
||||||
|
|
||||||
from pyme import util
|
# GPGME 1.7 replaced gpgme_op_edit with gpgme_op_interact. We
|
||||||
util.process_constants('GPGME_STATUS_', globals())
|
# implement pyme.Context.op_edit using gpgme_op_interact, so the
|
||||||
|
# callbacks will be called with string keywords instead of numeric
|
||||||
|
# status messages. Code that is using these constants will continue
|
||||||
|
# to work.
|
||||||
|
|
||||||
|
ABORT = "ABORT"
|
||||||
|
ALREADY_SIGNED = "ALREADY_SIGNED"
|
||||||
|
ATTRIBUTE = "ATTRIBUTE"
|
||||||
|
BACKUP_KEY_CREATED = "BACKUP_KEY_CREATED"
|
||||||
|
BAD_PASSPHRASE = "BAD_PASSPHRASE"
|
||||||
|
BADARMOR = "BADARMOR"
|
||||||
|
BADMDC = "BADMDC"
|
||||||
|
BADSIG = "BADSIG"
|
||||||
|
BEGIN_DECRYPTION = "BEGIN_DECRYPTION"
|
||||||
|
BEGIN_ENCRYPTION = "BEGIN_ENCRYPTION"
|
||||||
|
BEGIN_SIGNING = "BEGIN_SIGNING"
|
||||||
|
BEGIN_STREAM = "BEGIN_STREAM"
|
||||||
|
CARDCTRL = "CARDCTRL"
|
||||||
|
DECRYPTION_FAILED = "DECRYPTION_FAILED"
|
||||||
|
DECRYPTION_INFO = "DECRYPTION_INFO"
|
||||||
|
DECRYPTION_OKAY = "DECRYPTION_OKAY"
|
||||||
|
DELETE_PROBLEM = "DELETE_PROBLEM"
|
||||||
|
ENC_TO = "ENC_TO"
|
||||||
|
END_DECRYPTION = "END_DECRYPTION"
|
||||||
|
END_ENCRYPTION = "END_ENCRYPTION"
|
||||||
|
END_STREAM = "END_STREAM"
|
||||||
|
ENTER = "ENTER"
|
||||||
|
ERRMDC = "ERRMDC"
|
||||||
|
ERROR = "ERROR"
|
||||||
|
ERRSIG = "ERRSIG"
|
||||||
|
EXPKEYSIG = "EXPKEYSIG"
|
||||||
|
EXPSIG = "EXPSIG"
|
||||||
|
FAILURE = "FAILURE"
|
||||||
|
FILE_DONE = "FILE_DONE"
|
||||||
|
FILE_ERROR = "FILE_ERROR"
|
||||||
|
FILE_START = "FILE_START"
|
||||||
|
GET_BOOL = "GET_BOOL"
|
||||||
|
GET_HIDDEN = "GET_HIDDEN"
|
||||||
|
GET_LINE = "GET_LINE"
|
||||||
|
GOOD_PASSPHRASE = "GOOD_PASSPHRASE"
|
||||||
|
GOODMDC = "GOODMDC"
|
||||||
|
GOODSIG = "GOODSIG"
|
||||||
|
GOT_IT = "GOT_IT"
|
||||||
|
IMPORT_OK = "IMPORT_OK"
|
||||||
|
IMPORT_PROBLEM = "IMPORT_PROBLEM"
|
||||||
|
IMPORT_RES = "IMPORT_RES"
|
||||||
|
IMPORTED = "IMPORTED"
|
||||||
|
INQUIRE_MAXLEN = "INQUIRE_MAXLEN"
|
||||||
|
INV_RECP = "INV_RECP"
|
||||||
|
INV_SGNR = "INV_SGNR"
|
||||||
|
KEY_CONSIDERED = "KEY_CONSIDERED"
|
||||||
|
KEY_CREATED = "KEY_CREATED"
|
||||||
|
KEY_NOT_CREATED = "KEY_NOT_CREATED"
|
||||||
|
KEYEXPIRED = "KEYEXPIRED"
|
||||||
|
KEYREVOKED = "KEYREVOKED"
|
||||||
|
LEAVE = "LEAVE"
|
||||||
|
MISSING_PASSPHRASE = "MISSING_PASSPHRASE"
|
||||||
|
MOUNTPOINT = "MOUNTPOINT"
|
||||||
|
NEED_PASSPHRASE = "NEED_PASSPHRASE"
|
||||||
|
NEED_PASSPHRASE_PIN = "NEED_PASSPHRASE_PIN"
|
||||||
|
NEED_PASSPHRASE_SYM = "NEED_PASSPHRASE_SYM"
|
||||||
|
NEWSIG = "NEWSIG"
|
||||||
|
NO_PUBKEY = "NO_PUBKEY"
|
||||||
|
NO_RECP = "NO_RECP"
|
||||||
|
NO_SECKEY = "NO_SECKEY"
|
||||||
|
NO_SGNR = "NO_SGNR"
|
||||||
|
NODATA = "NODATA"
|
||||||
|
NOTATION_DATA = "NOTATION_DATA"
|
||||||
|
NOTATION_FLAGS = "NOTATION_FLAGS"
|
||||||
|
NOTATION_NAME = "NOTATION_NAME"
|
||||||
|
PINENTRY_LAUNCHED = "PINENTRY_LAUNCHED"
|
||||||
|
PKA_TRUST_BAD = "PKA_TRUST_BAD"
|
||||||
|
PKA_TRUST_GOOD = "PKA_TRUST_GOOD"
|
||||||
|
PLAINTEXT = "PLAINTEXT"
|
||||||
|
PLAINTEXT_LENGTH = "PLAINTEXT_LENGTH"
|
||||||
|
POLICY_URL = "POLICY_URL"
|
||||||
|
PROGRESS = "PROGRESS"
|
||||||
|
REVKEYSIG = "REVKEYSIG"
|
||||||
|
RSA_OR_IDEA = "RSA_OR_IDEA"
|
||||||
|
SC_OP_FAILURE = "SC_OP_FAILURE"
|
||||||
|
SC_OP_SUCCESS = "SC_OP_SUCCESS"
|
||||||
|
SESSION_KEY = "SESSION_KEY"
|
||||||
|
SHM_GET = "SHM_GET"
|
||||||
|
SHM_GET_BOOL = "SHM_GET_BOOL"
|
||||||
|
SHM_GET_HIDDEN = "SHM_GET_HIDDEN"
|
||||||
|
SHM_INFO = "SHM_INFO"
|
||||||
|
SIG_CREATED = "SIG_CREATED"
|
||||||
|
SIG_ID = "SIG_ID"
|
||||||
|
SIG_SUBPACKET = "SIG_SUBPACKET"
|
||||||
|
SIGEXPIRED = "SIGEXPIRED"
|
||||||
|
SUCCESS = "SUCCESS"
|
||||||
|
TOFU_STATS = "TOFU_STATS"
|
||||||
|
TOFU_STATS_LONG = "TOFU_STATS_LONG"
|
||||||
|
TOFU_USER = "TOFU_USER"
|
||||||
|
TRUNCATED = "TRUNCATED"
|
||||||
|
TRUST_FULLY = "TRUST_FULLY"
|
||||||
|
TRUST_MARGINAL = "TRUST_MARGINAL"
|
||||||
|
TRUST_NEVER = "TRUST_NEVER"
|
||||||
|
TRUST_ULTIMATE = "TRUST_ULTIMATE"
|
||||||
|
TRUST_UNDEFINED = "TRUST_UNDEFINED"
|
||||||
|
UNEXPECTED = "UNEXPECTED"
|
||||||
|
USERID_HINT = "USERID_HINT"
|
||||||
|
VALIDSIG = "VALIDSIG"
|
||||||
|
@ -29,6 +29,7 @@ del absolute_import, print_function, unicode_literals
|
|||||||
|
|
||||||
import re
|
import re
|
||||||
import os
|
import os
|
||||||
|
import warnings
|
||||||
import weakref
|
import weakref
|
||||||
from . import gpgme
|
from . import gpgme
|
||||||
from .errors import errorcheck, GPGMEError
|
from .errors import errorcheck, GPGMEError
|
||||||
@ -536,6 +537,39 @@ class Context(GpgmeWrapper):
|
|||||||
|
|
||||||
return GPGMEError(status) if status != 0 else None
|
return GPGMEError(status) if status != 0 else None
|
||||||
|
|
||||||
|
def interact(self, key, func, sink=None, flags=0, fnc_value=None):
|
||||||
|
"""Interact with the engine
|
||||||
|
|
||||||
|
This method can be used to edit keys and cards interactively.
|
||||||
|
KEY is the key to edit, FUNC is called repeatedly with two
|
||||||
|
unicode arguments, 'keyword' and 'args'. See the GPGME manual
|
||||||
|
for details.
|
||||||
|
|
||||||
|
Keyword arguments:
|
||||||
|
sink -- if given, additional output is written here
|
||||||
|
flags -- use constants.INTERACT_CARD to edit a card
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
GPGMEError -- as signaled by the underlying library
|
||||||
|
|
||||||
|
"""
|
||||||
|
if key == None:
|
||||||
|
raise ValueError("First argument cannot be None")
|
||||||
|
|
||||||
|
if sink == None:
|
||||||
|
sink = Data()
|
||||||
|
|
||||||
|
if fnc_value:
|
||||||
|
opaquedata = (weakref.ref(self), func, fnc_value)
|
||||||
|
else:
|
||||||
|
opaquedata = (weakref.ref(self), func)
|
||||||
|
|
||||||
|
result = gpgme.gpgme_op_interact(self.wrapped, key, flags,
|
||||||
|
opaquedata, sink)
|
||||||
|
if self._callback_excinfo:
|
||||||
|
gpgme.pyme_raise_callback_exception(self)
|
||||||
|
errorcheck(result)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def signers(self):
|
def signers(self):
|
||||||
"""Keys used for signing"""
|
"""Keys used for signing"""
|
||||||
@ -793,18 +827,21 @@ class Context(GpgmeWrapper):
|
|||||||
errorcheck(status)
|
errorcheck(status)
|
||||||
|
|
||||||
def op_edit(self, key, func, fnc_value, out):
|
def op_edit(self, key, func, fnc_value, out):
|
||||||
"""Start key editing using supplied callback function"""
|
"""Start key editing using supplied callback function
|
||||||
if key == None:
|
|
||||||
raise ValueError("op_edit: First argument cannot be None")
|
Note: This interface is deprecated and will be removed with
|
||||||
if fnc_value:
|
GPGME 1.8. Please use .interact instead. Furthermore, we
|
||||||
opaquedata = (weakref.ref(self), func, fnc_value)
|
implement this using gpgme_op_interact, so callbacks will get
|
||||||
else:
|
called with string keywords instead of numeric status
|
||||||
opaquedata = (weakref.ref(self), func)
|
messages. Code that is using constants.STATUS_X or
|
||||||
|
constants.status.X will continue to work, whereas code using
|
||||||
|
magic numbers will break as a result.
|
||||||
|
|
||||||
|
"""
|
||||||
|
warnings.warn("Call to deprecated method op_edit.",
|
||||||
|
category=DeprecationWarning)
|
||||||
|
return self.interact(key, func, sink=out, fnc_value=fnc_value)
|
||||||
|
|
||||||
result = gpgme.gpgme_op_edit(self.wrapped, key, opaquedata, out)
|
|
||||||
if self._callback_excinfo:
|
|
||||||
gpgme.pyme_raise_callback_exception(self)
|
|
||||||
errorcheck(result)
|
|
||||||
|
|
||||||
class Data(GpgmeWrapper):
|
class Data(GpgmeWrapper):
|
||||||
"""Data buffer
|
"""Data buffer
|
||||||
|
@ -33,7 +33,7 @@ class KeyEditor(object):
|
|||||||
self.done = False
|
self.done = False
|
||||||
self.verbose = int(os.environ.get('verbose', 0)) > 1
|
self.verbose = int(os.environ.get('verbose', 0)) > 1
|
||||||
|
|
||||||
def edit_fnc(self, status, args, out):
|
def edit_fnc(self, status, args, out=None):
|
||||||
if args == "keyedit.prompt":
|
if args == "keyedit.prompt":
|
||||||
result = self.steps[self.step]
|
result = self.steps[self.step]
|
||||||
self.step += 1
|
self.step += 1
|
||||||
@ -57,8 +57,15 @@ c = core.Context()
|
|||||||
c.set_pinentry_mode(constants.PINENTRY_MODE_LOOPBACK)
|
c.set_pinentry_mode(constants.PINENTRY_MODE_LOOPBACK)
|
||||||
c.set_passphrase_cb(lambda *args: "abc")
|
c.set_passphrase_cb(lambda *args: "abc")
|
||||||
c.set_armor(True)
|
c.set_armor(True)
|
||||||
sink = core.Data()
|
|
||||||
|
|
||||||
|
# The deprecated interface.
|
||||||
|
editor = KeyEditor()
|
||||||
|
c.interact(c.get_key("A0FF4590BB6122EDEF6E3C542D727CC768697734", False),
|
||||||
|
editor.edit_fnc)
|
||||||
|
assert editor.done
|
||||||
|
|
||||||
|
# The deprecated interface.
|
||||||
|
sink = core.Data()
|
||||||
editor = KeyEditor()
|
editor = KeyEditor()
|
||||||
c.op_edit(c.get_key("A0FF4590BB6122EDEF6E3C542D727CC768697734", False),
|
c.op_edit(c.get_key("A0FF4590BB6122EDEF6E3C542D727CC768697734", False),
|
||||||
editor.edit_fnc, sink, sink)
|
editor.edit_fnc, sink, sink)
|
||||||
|
Loading…
Reference in New Issue
Block a user