1
0
mirror of https://github.com/rkd77/elinks.git synced 2025-01-03 14:57:44 -05:00

[scripting] python scripting with Python3.

Only utf-8 encoding is supported.
This commit is contained in:
Witold Filipczyk 2019-11-11 13:33:37 +01:00
parent e8addcb561
commit b3e01b3298
19 changed files with 221 additions and 223 deletions

View File

@ -824,7 +824,7 @@ AC_ARG_WITH(python, [[ --with-python[=DIR] enable Python support]],
EL_SAVE_FLAGS EL_SAVE_FLAGS
cf_result=no cf_result=no
AC_MSG_CHECKING([for Python]) AC_MSG_CHECKING([for Python3])
if test "$enable_python" = "yes"; then if test "$enable_python" = "yes"; then
AC_MSG_RESULT(yes); AC_MSG_RESULT(yes);
@ -835,13 +835,13 @@ if test "$enable_python" = "yes"; then
PYTHON_PATH="$PATH" PYTHON_PATH="$PATH"
fi fi
AC_PATH_PROG(PYTHON, python, no, $PYTHON_PATH) AC_PATH_PROG(PYTHON3, python3, no, $PYTHON_PATH)
if test "$PYTHON" != no; then if test "$PYTHON3" != no; then
cf_result="yes"; cf_result="yes";
PYTHON_CFLAGS="`$PYTHON -c 'from distutils import sysconfig; print "-I%s -I%s" % (sysconfig.get_python_inc(), sysconfig.get_python_inc(plat_specific=True))'`" PYTHON_CFLAGS="`$PYTHON3 -c 'from distutils import sysconfig; print("-I%s -I%s" % (sysconfig.get_python_inc(), sysconfig.get_python_inc(plat_specific=True)))'`"
PYTHON_LIBS="`$PYTHON -c 'from distutils import sysconfig; var = sysconfig.get_config_var; print "%s %s %s -L%s -lpython%s" % (var("LINKFORSHARED"), var("LIBS"), var("SYSLIBS"), var("LIBPL"), var("VERSION"))'`" PYTHON_LIBS="`$PYTHON3 -c 'from distutils import sysconfig; var = sysconfig.get_config_var; print("%s %s %s -L%s -lpython%s" % (var("LINKFORSHARED"), var("LIBS"), var("SYSLIBS"), var("LIBPL"), var("VERSION")))'`"
LIBS="$PYTHON_LIBS $LIBS" LIBS="$PYTHON_LIBS $LIBS"
CPPFLAGS="$CPPFLAGS $PYTHON_CFLAGS" CPPFLAGS="$CPPFLAGS $PYTHON_CFLAGS"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <Python.h>]], [[Py_Initialize();]])],[cf_result=yes],[cf_result=no]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <Python.h>]], [[Py_Initialize();]])],[cf_result=yes],[cf_result=no])
@ -849,7 +849,7 @@ if test "$enable_python" = "yes"; then
if test "$cf_result" != "yes"; then if test "$cf_result" != "yes"; then
EL_RESTORE_FLAGS EL_RESTORE_FLAGS
else else
EL_CONFIG(CONFIG_SCRIPTING_PYTHON, [Python]) EL_CONFIG(CONFIG_SCRIPTING_PYTHON, [Python3])
AC_SUBST(PYTHON_LIBS) AC_SUBST(PYTHON_LIBS)
AC_SUBST(PYTHON_CFLAGS) AC_SUBST(PYTHON_CFLAGS)
CPPFLAGS="$CPPFLAGS_X" CPPFLAGS="$CPPFLAGS_X"
@ -864,9 +864,9 @@ EOF
fi fi
else else
if test -n "$withval" && test "x$withval" != xno; then if test -n "$withval" && test "x$withval" != xno; then
AC_MSG_ERROR([Python not found]) AC_MSG_ERROR([Python3 not found])
else else
AC_MSG_WARN([Python support disabled]) AC_MSG_WARN([Python3 support disabled])
fi fi
fi fi
else else

View File

@ -24,6 +24,7 @@ quit_hook() -- Clean up before ELinks exits.
""" """
import elinks import elinks
from importlib import reload
dumbprefixes = { dumbprefixes = {
"7th" : "http://7thguard.net/", "7th" : "http://7thguard.net/",
@ -96,10 +97,6 @@ def pre_format_html_hook(url, html):
elif url.startswith("https://www.mbank.com.pl/ib_navibar_3.asp"): elif url.startswith("https://www.mbank.com.pl/ib_navibar_3.asp"):
return html.replace('<td valign="top"><img', return html.replace('<td valign="top"><img',
'<tr><td valign="top"><img') '<tr><td valign="top"><img')
elif url.startswith("http://lp3.polskieradio.pl/"):
from lp3 import lp3
return lp3(html)
def proxy_for_hook(url): def proxy_for_hook(url):
"""Determine what proxy server to use for a given URL. """Determine what proxy server to use for a given URL.

View File

@ -1,11 +0,0 @@
import re
PATTERN = re.compile('<a href="javascript:void\(null\);" onclick="\s*play\(this,\'(http://lp3.polskieradio.pl/_files/mp3/.*mp3)\'\);\s*">')
def zamien(m):
return '<a href="' + m.group(1) + '">'
def lp3(html):
return PATTERN.sub(zamien, html)

View File

@ -4,6 +4,7 @@
#include "config.h" #include "config.h"
#endif #endif
#define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include <osdefs.h> #include <osdefs.h>
@ -67,13 +68,13 @@ alert_python_error(void)
* of strings into one Python string containing the entire error * of strings into one Python string containing the entire error
* message. Then get the contents of the Python string. * message. Then get the contents of the Python string.
*/ */
empty_string = PyString_FromString(""); empty_string = PyUnicode_FromString("");
if (!empty_string) goto end; if (!empty_string) goto end;
msg_string = PyObject_CallMethod(empty_string, "join", "O", msg_list); msg_string = PyObject_CallMethod(empty_string, "join", "O", msg_list);
if (!msg_string) goto end; if (!msg_string) goto end;
temp = (unsigned char *) PyString_AsString(msg_string); temp = (unsigned char *) PyUnicode_AsUTF8(msg_string);
if (temp) msg = temp; if (temp) msg = temp;
end: end:
@ -206,13 +207,13 @@ replace_showwarning(void)
warnings_module = PyImport_ImportModule("warnings"); warnings_module = PyImport_ImportModule("warnings");
if (!warnings_module) goto end; if (!warnings_module) goto end;
module_name = PyString_FromString("warnings"); module_name = PyUnicode_FromString("warnings");
if (!module_name) goto end; if (!module_name) goto end;
module_dict = PyModule_GetDict(warnings_module); module_dict = PyModule_GetDict(warnings_module);
if (!module_dict) goto end; if (!module_dict) goto end;
if (add_python_methods(module_dict, module_name, warning_methods) != 0) if (add_python_methods(module_dict, module_name, warning_methods) != 0)
goto end; goto end;
result = 0; result = 0;
@ -250,48 +251,152 @@ Other public objects:\n\
home -- A string containing the pathname of the ~/.elinks directory, or\n\ home -- A string containing the pathname of the ~/.elinks directory, or\n\
None if ELinks has no configuration directory.\n"); None if ELinks has no configuration directory.\n");
void static PyMethodDef python_methods[] = {
init_python(struct module *module) {"info_box", (PyCFunction)python_info_box,
METH_VARARGS | METH_KEYWORDS,
python_info_box_doc},
{"input_box", (PyCFunction)python_input_box,
METH_VARARGS | METH_KEYWORDS,
python_input_box_doc},
{"current_document", python_current_document,
METH_NOARGS,
python_current_document_doc},
{"current_header", python_current_header,
METH_NOARGS,
python_current_header_doc},
{"current_link_url", python_current_link_url,
METH_NOARGS,
python_current_link_url_doc},
{"current_title", python_current_title,
METH_NOARGS,
python_current_title_doc},
{"current_url", python_current_url,
METH_NOARGS,
python_current_url_doc},
{"bind_key", (PyCFunction)python_bind_key,
METH_VARARGS | METH_KEYWORDS,
python_bind_key_doc},
{"load", python_load,
METH_VARARGS,
python_load_doc},
{"menu", (PyCFunction)python_menu,
METH_VARARGS | METH_KEYWORDS,
python_menu_doc},
{"open", (PyCFunction)python_open,
METH_VARARGS | METH_KEYWORDS,
python_open_doc},
{NULL, NULL, 0, NULL}
};
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT,
"elinks", /* m_name */
module_doc, /* m_doc */
-1, /* m_size */
python_methods, /* m_methods */
NULL, /* m_reload */
NULL, /* m_traverse */
NULL, /* m_clear */
NULL, /* m_free */
};
static int
add_constant(PyObject *dict, const char *key, int value)
{
PyObject *constant = PyLong_FromLong(value);
int result;
if (!constant) return -1;
result = PyDict_SetItemString(dict, key, constant);
Py_DECREF(constant);
return result;
}
PyMODINIT_FUNC
PyInit_elinks(void)
{ {
PyObject *elinks_module, *module_dict, *module_name; PyObject *elinks_module, *module_dict, *module_name;
if (set_python_search_path() != 0) return; if (replace_showwarning() != 0) {
goto python_error;
}
Py_Initialize(); keybindings = PyDict_New();
if (!keybindings) {
goto python_error;
}
if (!hooks_module_exists()) return; elinks_module = PyModule_Create(&moduledef);
if (!elinks_module) {
if (replace_showwarning() != 0) goto python_error; goto python_error;
}
elinks_module = Py_InitModule3("elinks", NULL, module_doc);
if (!elinks_module) goto python_error;
/* If @elinks_home is NULL, Py_BuildValue() returns a None reference. */ /* If @elinks_home is NULL, Py_BuildValue() returns a None reference. */
if (PyModule_AddObject(elinks_module, "home", if (PyModule_AddObject(elinks_module, "home",
Py_BuildValue("s", elinks_home)) != 0) Py_BuildValue("s", elinks_home)) != 0) {
goto python_error; goto python_error;
}
python_elinks_err = PyErr_NewException("elinks.error", NULL, NULL); python_elinks_err = PyErr_NewException("elinks.error", NULL, NULL);
if (!python_elinks_err) goto python_error; if (!python_elinks_err) {
if (PyModule_AddObject(elinks_module, "error", python_elinks_err) != 0)
goto python_error; goto python_error;
}
if (PyModule_AddObject(elinks_module, "error", python_elinks_err) != 0) {
goto python_error;
}
module_dict = PyModule_GetDict(elinks_module); module_dict = PyModule_GetDict(elinks_module);
if (!module_dict) goto python_error; if (!module_dict) {
module_name = PyString_FromString("elinks");
if (!module_name) goto python_error;
if (python_init_dialogs_interface(module_dict, module_name) != 0
|| python_init_document_interface(module_dict, module_name) != 0
|| python_init_keybinding_interface(module_dict, module_name) != 0
|| python_init_load_interface(module_dict, module_name) != 0
|| python_init_menu_interface(module_dict, module_name) != 0
|| python_init_open_interface(module_dict, module_name) != 0)
goto python_error; goto python_error;
}
add_constant(module_dict, "MENU_LINK", PYTHON_MENU_LINK);
add_constant(module_dict, "MENU_TAB", PYTHON_MENU_TAB);
module_name = PyUnicode_FromString("elinks");
if (!module_name) {
goto python_error;
}
return elinks_module;
python_error:
alert_python_error();
return NULL;
}
void
init_python(struct module *module)
{
if (set_python_search_path() != 0) {
return;
}
PyImport_AppendInittab("elinks", PyInit_elinks);
Py_Initialize();
if (!hooks_module_exists()) {
return;
}
python_hooks = PyImport_ImportModule("hooks"); python_hooks = PyImport_ImportModule("hooks");
if (!python_hooks) goto python_error; if (!python_hooks) {
goto python_error;
}
return; return;
@ -335,3 +440,4 @@ add_python_methods(PyObject *dict, PyObject *name, PyMethodDef *methods)
} }
return 0; return 0;
} }

View File

@ -21,6 +21,13 @@ typedef int Py_ssize_t;
struct module; struct module;
enum python_menu_type {
PYTHON_MENU_DEFAULT,
PYTHON_MENU_LINK,
PYTHON_MENU_TAB,
PYTHON_MENU_MAX
};
extern struct session *python_ses; extern struct session *python_ses;
extern PyObject *python_elinks_err; extern PyObject *python_elinks_err;

View File

@ -4,6 +4,7 @@
#include "config.h" #include "config.h"
#endif #endif
#define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include "elinks.h" #include "elinks.h"
@ -20,7 +21,7 @@
/* Python interface for displaying information to the user. */ /* Python interface for displaying information to the user. */
static char python_info_box_doc[] = char python_info_box_doc[] =
PYTHON_DOCSTRING("info_box(text[, title]) -> None\n\ PYTHON_DOCSTRING("info_box(text[, title]) -> None\n\
\n\ \n\
Display information to the user in a dialog box.\n\ Display information to the user in a dialog box.\n\
@ -36,7 +37,7 @@ Optional arguments:\n\
title -- A string containing a title for the dialog box. By default\n\ title -- A string containing a title for the dialog box. By default\n\
the string \"Info\" is used.\n"); the string \"Info\" is used.\n");
static PyObject * PyObject *
python_info_box(PyObject *self, PyObject *args, PyObject *kwargs) python_info_box(PyObject *self, PyObject *args, PyObject *kwargs)
{ {
/* [gettext_accelerator_context(python_info_box)] */ /* [gettext_accelerator_context(python_info_box)] */
@ -66,7 +67,7 @@ python_info_box(PyObject *self, PyObject *args, PyObject *kwargs)
*/ */
string_object = PyObject_Str(object); string_object = PyObject_Str(object);
if (!string_object) return NULL; if (!string_object) return NULL;
text = (unsigned char *) PyString_AS_STRING(string_object); text = (unsigned char *) PyUnicode_AsUTF8(string_object);
if (!text) { if (!text) {
Py_DECREF(string_object); Py_DECREF(string_object);
return NULL; return NULL;
@ -142,7 +143,7 @@ invoke_input_cancel_callback(void *data)
/* Python interface for getting input from the user. */ /* Python interface for getting input from the user. */
static char python_input_box_doc[] = char python_input_box_doc[] =
PYTHON_DOCSTRING( PYTHON_DOCSTRING(
"input_box(prompt, callback, title=\"User dialog\", initial=\"\") -> None\n\ "input_box(prompt, callback, title=\"User dialog\", initial=\"\") -> None\n\
\n\ \n\
@ -163,7 +164,7 @@ title -- A string containing a title for the dialog box. By default\n\
initial -- A string containing an initial value for the text entry\n\ initial -- A string containing an initial value for the text entry\n\
field. By default the entry field is initially empty.\n"); field. By default the entry field is initially empty.\n");
static PyObject * PyObject *
python_input_box(PyObject *self, PyObject *args, PyObject *kwargs) python_input_box(PyObject *self, PyObject *args, PyObject *kwargs)
{ {
unsigned char *prompt; unsigned char *prompt;
@ -229,21 +230,3 @@ free_prompt:
mem_error: mem_error:
return PyErr_NoMemory(); return PyErr_NoMemory();
} }
static PyMethodDef dialogs_methods[] = {
{"info_box", (PyCFunction) python_info_box,
METH_VARARGS | METH_KEYWORDS,
python_info_box_doc},
{"input_box", (PyCFunction) python_input_box,
METH_VARARGS | METH_KEYWORDS,
python_input_box_doc},
{NULL, NULL, 0, NULL}
};
int
python_init_dialogs_interface(PyObject *dict, PyObject *name)
{
return add_python_methods(dict, name, dialogs_methods);
}

View File

@ -3,6 +3,9 @@
#include <Python.h> #include <Python.h>
int python_init_dialogs_interface(PyObject *dict, PyObject *name); PyObject *python_info_box(PyObject *self, PyObject *args, PyObject *kwargs);
extern char python_info_box_doc[];
PyObject *python_input_box(PyObject *self, PyObject *args, PyObject *kwargs);
extern char python_input_box_doc[];
#endif #endif

View File

@ -4,6 +4,7 @@
#include "config.h" #include "config.h"
#endif #endif
#define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include "elinks.h" #include "elinks.h"
@ -16,12 +17,12 @@
/* Python interface to get the current document's body. */ /* Python interface to get the current document's body. */
static char python_current_document_doc[] = char python_current_document_doc[] =
PYTHON_DOCSTRING("current_document() -> string or None\n\ PYTHON_DOCSTRING("current_document() -> string or None\n\
\n\ \n\
If a document is being viewed, return its body; otherwise return None.\n"); If a document is being viewed, return its body; otherwise return None.\n");
static PyObject * PyObject *
python_current_document(PyObject *self, PyObject *args) python_current_document(PyObject *self, PyObject *args)
{ {
if (python_ses && python_ses->doc_view if (python_ses && python_ses->doc_view
@ -29,7 +30,7 @@ python_current_document(PyObject *self, PyObject *args)
struct cache_entry *cached = python_ses->doc_view->document->cached; struct cache_entry *cached = python_ses->doc_view->document->cached;
struct fragment *f = cached ? cached->frag.next : NULL; struct fragment *f = cached ? cached->frag.next : NULL;
if (f) return PyString_FromStringAndSize(f->data, f->length); if (f) return PyUnicode_FromStringAndSize(f->data, f->length);
} }
Py_INCREF(Py_None); Py_INCREF(Py_None);
@ -38,13 +39,13 @@ python_current_document(PyObject *self, PyObject *args)
/* Python interface to get the current document's header. */ /* Python interface to get the current document's header. */
static char python_current_header_doc[] = char python_current_header_doc[] =
PYTHON_DOCSTRING("current_header() -> string or None\n\ PYTHON_DOCSTRING("current_header() -> string or None\n\
\n\ \n\
If a document is being viewed and it has a header, return the header;\n\ If a document is being viewed and it has a header, return the header;\n\
otherwise return None.\n"); otherwise return None.\n");
static PyObject * PyObject *
python_current_header(PyObject *self, PyObject *args) python_current_header(PyObject *self, PyObject *args)
{ {
if (python_ses && python_ses->doc_view if (python_ses && python_ses->doc_view
@ -52,7 +53,7 @@ python_current_header(PyObject *self, PyObject *args)
struct cache_entry *cached = python_ses->doc_view->document->cached; struct cache_entry *cached = python_ses->doc_view->document->cached;
if (cached && cached->head) if (cached && cached->head)
return PyString_FromString(cached->head); return PyUnicode_FromString(cached->head);
} }
Py_INCREF(Py_None); Py_INCREF(Py_None);
@ -61,18 +62,18 @@ python_current_header(PyObject *self, PyObject *args)
/* Python interface to get the currently-selected link's URL. */ /* Python interface to get the currently-selected link's URL. */
static char python_current_link_url_doc[] = char python_current_link_url_doc[] =
PYTHON_DOCSTRING("current_link_url() -> string or None\n\ PYTHON_DOCSTRING("current_link_url() -> string or None\n\
\n\ \n\
If a link is selected, return its URL; otherwise return None.\n"); If a link is selected, return its URL; otherwise return None.\n");
static PyObject * PyObject *
python_current_link_url(PyObject *self, PyObject *args) python_current_link_url(PyObject *self, PyObject *args)
{ {
unsigned char url[MAX_STR_LEN]; unsigned char url[MAX_STR_LEN];
if (python_ses && get_current_link_url(python_ses, url, MAX_STR_LEN)) if (python_ses && get_current_link_url(python_ses, url, MAX_STR_LEN))
return PyString_FromString(url); return PyUnicode_FromString(url);
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
@ -80,18 +81,18 @@ python_current_link_url(PyObject *self, PyObject *args)
/* Python interface to get the current document's title. */ /* Python interface to get the current document's title. */
static char python_current_title_doc[] = char python_current_title_doc[] =
PYTHON_DOCSTRING("current_title() -> string or None\n\ PYTHON_DOCSTRING("current_title() -> string or None\n\
\n\ \n\
If a document is being viewed, return its title; otherwise return None.\n"); If a document is being viewed, return its title; otherwise return None.\n");
static PyObject * PyObject *
python_current_title(PyObject *self, PyObject *args) python_current_title(PyObject *self, PyObject *args)
{ {
unsigned char title[MAX_STR_LEN]; unsigned char title[MAX_STR_LEN];
if (python_ses && get_current_title(python_ses, title, MAX_STR_LEN)) if (python_ses && get_current_title(python_ses, title, MAX_STR_LEN))
return PyString_FromString(title); return PyUnicode_FromString(title);
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
@ -99,49 +100,19 @@ python_current_title(PyObject *self, PyObject *args)
/* Python interface to get the current document's URL. */ /* Python interface to get the current document's URL. */
static char python_current_url_doc[] = char python_current_url_doc[] =
PYTHON_DOCSTRING("current_url() -> string or None\n\ PYTHON_DOCSTRING("current_url() -> string or None\n\
\n\ \n\
If a document is being viewed, return its URL; otherwise return None.\n"); If a document is being viewed, return its URL; otherwise return None.\n");
static PyObject * PyObject *
python_current_url(PyObject *self, PyObject *args) python_current_url(PyObject *self, PyObject *args)
{ {
unsigned char url[MAX_STR_LEN]; unsigned char url[MAX_STR_LEN];
if (python_ses && get_current_url(python_ses, url, MAX_STR_LEN)) if (python_ses && get_current_url(python_ses, url, MAX_STR_LEN))
return PyString_FromString(url); return PyUnicode_FromString(url);
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
} }
static PyMethodDef document_methods[] = {
{"current_document", python_current_document,
METH_NOARGS,
python_current_document_doc},
{"current_header", python_current_header,
METH_NOARGS,
python_current_header_doc},
{"current_link_url", python_current_link_url,
METH_NOARGS,
python_current_link_url_doc},
{"current_title", python_current_title,
METH_NOARGS,
python_current_title_doc},
{"current_url", python_current_url,
METH_NOARGS,
python_current_url_doc},
{NULL, NULL, 0, NULL}
};
int
python_init_document_interface(PyObject *dict, PyObject *name)
{
return add_python_methods(dict, name, document_methods);
}

View File

@ -3,6 +3,15 @@
#include <Python.h> #include <Python.h>
int python_init_document_interface(PyObject *dict, PyObject *name); PyObject *python_current_document(PyObject *self, PyObject *args);
extern char python_current_document_doc[];
PyObject *python_current_header(PyObject *self, PyObject *args);
extern char python_current_header_doc[];
PyObject *python_current_link_url(PyObject *self, PyObject *args);
extern char python_current_link_url_doc[];
PyObject *python_current_title(PyObject *self, PyObject *args);
extern char python_current_title_doc[];
PyObject *python_current_url(PyObject *self, PyObject *args);
extern char python_current_url_doc[];
#endif #endif

View File

@ -4,6 +4,7 @@
#include "config.h" #include "config.h"
#endif #endif
#define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include <stdarg.h> #include <stdarg.h>
@ -32,9 +33,12 @@ replace_with_python_string(unsigned char **dest, PyObject *object)
{ {
unsigned char *str; unsigned char *str;
if (object == Py_None) return object; if (object == Py_None) {
return object;
}
str = (unsigned char *) PyUnicode_AsUTF8(object);
str = (unsigned char *) PyString_AsString(object);
if (!str) return NULL; if (!str) return NULL;
str = stracpy(str); str = stracpy(str);
@ -102,11 +106,13 @@ script_hook_pre_format_html(va_list ap, void *data)
if (!result) goto error; if (!result) goto error;
if (result != Py_None) { if (result != Py_None) {
unsigned char *str; const unsigned char *str;
Py_ssize_t len; Py_ssize_t len;
if (PyString_AsStringAndSize(result, (char **) &str, &len) != 0) str = PyUnicode_AsUTF8AndSize(result, &len);
if (!str) {
goto error; goto error;
}
/* This assumes the Py_ssize_t len is not too large to /* This assumes the Py_ssize_t len is not too large to
* fit in the off_t parameter of normalize_cache_entry(). * fit in the off_t parameter of normalize_cache_entry().

View File

@ -4,6 +4,7 @@
#include "config.h" #include "config.h"
#endif #endif
#define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include <stdarg.h> #include <stdarg.h>
@ -19,7 +20,7 @@
#include "util/error.h" #include "util/error.h"
#include "util/string.h" #include "util/string.h"
static PyObject *keybindings = NULL; PyObject *keybindings = NULL;
/* C wrapper that invokes Python callbacks for bind_key_to_event_name(). */ /* C wrapper that invokes Python callbacks for bind_key_to_event_name(). */
@ -58,7 +59,7 @@ keymap_is_valid(const unsigned char *keymap)
/* Python interface for binding keystrokes to callable objects. */ /* Python interface for binding keystrokes to callable objects. */
static char python_bind_key_doc[] = char python_bind_key_doc[] =
PYTHON_DOCSTRING("bind_key(keystroke, callback[, keymap]) -> None\n\ PYTHON_DOCSTRING("bind_key(keystroke, callback[, keymap]) -> None\n\
\n\ \n\
Bind a keystroke to a callable object.\n\ Bind a keystroke to a callable object.\n\
@ -76,7 +77,7 @@ keymap -- A string containing the name of a keymap. Valid keymap\n\
names can be found in the elinkskeys(5) man page. By\n\ names can be found in the elinkskeys(5) man page. By\n\
default the \"main\" keymap is used.\n"); default the \"main\" keymap is used.\n");
static PyObject * PyObject *
python_bind_key(PyObject *self, PyObject *args, PyObject *kwargs) python_bind_key(PyObject *self, PyObject *args, PyObject *kwargs)
{ {
const unsigned char *keystroke; const unsigned char *keystroke;
@ -174,23 +175,6 @@ rollback:
return NULL; return NULL;
} }
static PyMethodDef keybinding_methods[] = {
{"bind_key", (PyCFunction) python_bind_key,
METH_VARARGS | METH_KEYWORDS,
python_bind_key_doc},
{NULL, NULL, 0, NULL}
};
int
python_init_keybinding_interface(PyObject *dict, PyObject *name)
{
keybindings = PyDict_New();
if (!keybindings) return -1;
return add_python_methods(dict, name, keybinding_methods);
}
void void
python_done_keybinding_interface(void) python_done_keybinding_interface(void)
{ {

View File

@ -3,7 +3,9 @@
#include <Python.h> #include <Python.h>
int python_init_keybinding_interface(PyObject *dict, PyObject *name); extern PyObject *keybindings;
PyObject *python_bind_key(PyObject *self, PyObject *args, PyObject *kwargs);
extern char python_bind_key_doc[];
void python_done_keybinding_interface(void); void python_done_keybinding_interface(void);
#endif #endif

View File

@ -4,6 +4,7 @@
#include "config.h" #include "config.h"
#endif #endif
#define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include "elinks.h" #include "elinks.h"
@ -76,7 +77,7 @@ invoke_load_uri_callback(struct download *download, void *data)
/* Python interface for loading a document. */ /* Python interface for loading a document. */
static char python_load_doc[] = char python_load_doc[] =
PYTHON_DOCSTRING("load(url, callback) -> None\n\ PYTHON_DOCSTRING("load(url, callback) -> None\n\
\n\ \n\
Load a document into the ELinks cache and pass its contents to a\n\ Load a document into the ELinks cache and pass its contents to a\n\
@ -91,7 +92,7 @@ callback -- A callable object to be called after the document has\n\
if it has no header; the second will be a string representing\n\ if it has no header; the second will be a string representing\n\
the document's body, or None if it has no body.\n"); the document's body, or None if it has no body.\n");
static PyObject * PyObject *
python_load(PyObject *self, PyObject *args) python_load(PyObject *self, PyObject *args)
{ {
unsigned char *uristring; unsigned char *uristring;
@ -150,18 +151,3 @@ mem_error:
done_uri(uri); done_uri(uri);
return PyErr_NoMemory(); return PyErr_NoMemory();
} }
static PyMethodDef load_methods[] = {
{"load", python_load,
METH_VARARGS,
python_load_doc},
{NULL, NULL, 0, NULL}
};
int
python_init_load_interface(PyObject *dict, PyObject *name)
{
return add_python_methods(dict, name, load_methods);
}

View File

@ -3,6 +3,7 @@
#include <Python.h> #include <Python.h>
int python_init_load_interface(PyObject *dict, PyObject *name); PyObject *python_load(PyObject *self, PyObject *args);
extern char python_load_doc[];
#endif #endif

View File

@ -4,6 +4,7 @@
#include "config.h" #include "config.h"
#endif #endif
#define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include "elinks.h" #include "elinks.h"
@ -43,16 +44,9 @@ invoke_menu_callback(struct terminal *term, void *data, void *ses)
python_ses = saved_python_ses; python_ses = saved_python_ses;
} }
enum python_menu_type {
PYTHON_MENU_DEFAULT,
PYTHON_MENU_LINK,
PYTHON_MENU_TAB,
PYTHON_MENU_MAX
};
/* Python interface for displaying simple menus. */ /* Python interface for displaying simple menus. */
static char python_menu_doc[] = char python_menu_doc[] =
PYTHON_DOCSTRING("menu(items[, type]) -> None\n\ PYTHON_DOCSTRING("menu(items[, type]) -> None\n\
\n\ \n\
Display a menu.\n\ Display a menu.\n\
@ -74,7 +68,7 @@ type -- A constant specifying the type of menu to display. By default\n\
displayed in the same location as the ELinks link menu and is\n\ displayed in the same location as the ELinks link menu and is\n\
not displayed unless a link is currently selected.\n"); not displayed unless a link is currently selected.\n");
static PyObject * PyObject *
python_menu(PyObject *self, PyObject *args, PyObject *kwargs) python_menu(PyObject *self, PyObject *args, PyObject *kwargs)
{ {
PyObject *items; PyObject *items;
@ -165,7 +159,7 @@ python_menu(PyObject *self, PyObject *args, PyObject *kwargs)
Py_DECREF(tuple); Py_DECREF(tuple);
if (!name || !callback) goto error; if (!name || !callback) goto error;
contents = (unsigned char *) PyString_AsString(name); contents = (unsigned char *) PyUnicode_AsUTF8(name);
if (!contents) goto error; if (!contents) goto error;
contents = stracpy(contents); contents = stracpy(contents);
@ -210,33 +204,3 @@ error:
freeml(ml); freeml(ml);
return NULL; return NULL;
} }
static PyMethodDef menu_methods[] = {
{"menu", (PyCFunction) python_menu,
METH_VARARGS | METH_KEYWORDS,
python_menu_doc},
{NULL, NULL, 0, NULL}
};
static int
add_constant(PyObject *dict, const char *key, int value)
{
PyObject *constant = PyInt_FromLong(value);
int result;
if (!constant) return -1;
result = PyDict_SetItemString(dict, key, constant);
Py_DECREF(constant);
return result;
}
int
python_init_menu_interface(PyObject *dict, PyObject *name)
{
if (add_constant(dict, "MENU_LINK", PYTHON_MENU_LINK) != 0) return -1;
if (add_constant(dict, "MENU_TAB", PYTHON_MENU_TAB) != 0) return -1;
return add_python_methods(dict, name, menu_methods);
}

View File

@ -3,6 +3,7 @@
#include <Python.h> #include <Python.h>
int python_init_menu_interface(PyObject *dict, PyObject *name); PyObject *python_menu(PyObject *self, PyObject *args, PyObject *kwargs);
extern char python_menu_doc[];
#endif #endif

View File

@ -4,6 +4,7 @@
#include "config.h" #include "config.h"
#endif #endif
#define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include "elinks.h" #include "elinks.h"
@ -17,7 +18,7 @@
/* Python interface for viewing a document. */ /* Python interface for viewing a document. */
static char python_open_doc[] = char python_open_doc[] =
PYTHON_DOCSTRING("open(url, new_tab=False, background=False) -> None\n\ PYTHON_DOCSTRING("open(url, new_tab=False, background=False) -> None\n\
\n\ \n\
View a document in either the current tab or a new tab.\n\ View a document in either the current tab or a new tab.\n\
@ -36,7 +37,7 @@ background -- By default a new tab is opened in the foreground. If\n\
instead opened in the background. This argument is ignored\n\ instead opened in the background. This argument is ignored\n\
unless new_tab's value is True.\n"); unless new_tab's value is True.\n");
static PyObject * PyObject *
python_open(PyObject *self, PyObject *args, PyObject *kwargs) python_open(PyObject *self, PyObject *args, PyObject *kwargs)
{ {
unsigned char *url; unsigned char *url;
@ -76,17 +77,3 @@ python_open(PyObject *self, PyObject *args, PyObject *kwargs)
Py_INCREF(Py_None); Py_INCREF(Py_None);
return Py_None; return Py_None;
} }
static PyMethodDef open_methods[] = {
{"open", (PyCFunction) python_open,
METH_VARARGS | METH_KEYWORDS,
python_open_doc},
{NULL, NULL, 0, NULL}
};
int
python_init_open_interface(PyObject *dict, PyObject *name)
{
return add_python_methods(dict, name, open_methods);
}

View File

@ -3,6 +3,7 @@
#include <Python.h> #include <Python.h>
int python_init_open_interface(PyObject *dict, PyObject *name); PyObject *python_open(PyObject *self, PyObject *args, PyObject *kwargs);
extern char python_open_doc[];
#endif #endif

View File

@ -4,6 +4,7 @@
#include "config.h" #include "config.h"
#endif #endif
#define PY_SSIZE_T_CLEAN
#include <Python.h> #include <Python.h>
#include "elinks.h" #include "elinks.h"