From a06507d49ce6abc6ebe5c0afcde551d6db146b91 Mon Sep 17 00:00:00 2001 From: Vincent Castellano Date: Thu, 28 May 2015 11:42:21 -0700 Subject: [PATCH 1/7] Optionally ping the python script every time we do a loop update in tg. --- python-tg.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/python-tg.c b/python-tg.c index 475c76e..20b7aed 100644 --- a/python-tg.c +++ b/python-tg.c @@ -105,6 +105,7 @@ PyObject *_py_new_msg; PyObject *_py_secret_chat_update; PyObject *_py_user_update; PyObject *_py_chat_update; +PyObject *_py_on_loop; PyObject* get_peer (tgl_peer_id_t id, tgl_peer_t *P); @@ -390,6 +391,27 @@ void py_chat_update (struct tgl_chat *C, unsigned flags) { Py_XDECREF(result); } +void py_on_loop () { + if (!python_loaded) { return; } + + PyObject *result; + + if(_py_on_loop == NULL) { + logprintf("Callback not set for on_chat_update"); + return; + } + + result = PyEval_CallObject(_py_on_loop, Py_None); + + if(result == NULL) + PyErr_Print(); + else if(PyUnicode_Check(result)) + logprintf ("python: %s\n", PyBytes_AsString(PyUnicode_AsASCIIString(result))); + + Py_XDECREF(result); +} + + ////extern tgl_peer_t *Peers[]; ////extern int peer_num; // @@ -737,6 +759,10 @@ void py_str_cb (struct tgl_state *TLSR, void *cb_extra, int success, const char void py_do_all (void) { int p = 0; + + // ping the python thread that we're doing the loop + py_on_loop(); + while (p < pos) { assert (p + 2 <= pos); @@ -1116,6 +1142,7 @@ TGL_PYTHON_CALLBACK("on_msg_receive", _py_new_msg); TGL_PYTHON_CALLBACK("on_secret_chat_update", _py_secret_chat_update); TGL_PYTHON_CALLBACK("on_user_update", _py_user_update); TGL_PYTHON_CALLBACK("on_chat_update", _py_chat_update); +TGL_PYTHON_CALLBACK("on_loop", _py_on_loop); static PyMethodDef py_tgl_methods[] = { {"get_contact_list", py_contact_list, METH_VARARGS, "retrieve contact list"}, @@ -1169,6 +1196,7 @@ static PyMethodDef py_tgl_methods[] = { {"set_on_secret_chat_update", set_py_secret_chat_update, METH_VARARGS, ""}, {"set_on_user_update", set_py_user_update, METH_VARARGS, ""}, {"set_on_chat_update", set_py_chat_update, METH_VARARGS, ""}, + {"set_on_loop", set_py_on_loop, METH_VARARGS, ""}, { NULL, NULL, 0, NULL } }; From 13c22f3b063cb8356911a7beba056c026ed500f5 Mon Sep 17 00:00:00 2001 From: Vincent Castellano Date: Thu, 28 May 2015 11:46:33 -0700 Subject: [PATCH 2/7] Need to pass tuple to a method call --- python-tg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python-tg.c b/python-tg.c index 20b7aed..9a0eb73 100644 --- a/python-tg.c +++ b/python-tg.c @@ -401,7 +401,7 @@ void py_on_loop () { return; } - result = PyEval_CallObject(_py_on_loop, Py_None); + result = PyEval_CallObject(_py_on_loop, Py_BuildValue("()")); if(result == NULL) PyErr_Print(); From c2bb5346df0ec58858d057c9e8fbdc657df5b22d Mon Sep 17 00:00:00 2001 From: Vincent Castellano Date: Fri, 29 May 2015 20:06:25 -0700 Subject: [PATCH 3/7] Adding tgl.Peer comparisons, only eq/ne --- python-types.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/python-types.c b/python-types.c index 28fb9f5..5685390 100644 --- a/python-types.c +++ b/python-types.c @@ -969,6 +969,38 @@ tgl_Peer_repr(tgl_Peer *self) return ret; } +PyObject * +tgl_Peer_RichCompare(PyObject *self, PyObject *other, int cmp) +{ + PyObject *result = NULL; + + if(!PyObject_TypeCheck(other, &tgl_PeerType)) { + result = Py_False; + } else { + if(((tgl_Peer*)self)->peer == NULL || + ((tgl_Peer*)other)->peer == NULL) { + result = Py_False; // If either object is not properly instantiated, compare is false + } else { + switch (cmp) { + case Py_EQ: + result = ((tgl_Peer*)self)->peer->id.id == ((tgl_Peer*)other)->peer->id.id ? Py_True : Py_False; + break; + case Py_NE: + result = ((tgl_Peer*)self)->peer->id.id == ((tgl_Peer*)other)->peer->id.id ? Py_False : Py_True; + break; + case Py_LE: + case Py_GE: + case Py_GT: + case Py_LT: + default: + Py_RETURN_NOTIMPLEMENTED; + } + } + } + Py_XINCREF(result); + return result; +} + PyTypeObject tgl_PeerType = { PyVarObject_HEAD_INIT(NULL, 0) @@ -994,7 +1026,7 @@ PyTypeObject tgl_PeerType = { "tgl Peer", /* tp_doc */ 0, /* tp_traverse */ 0, /* tp_clear */ - 0, /* tp_richcompare */ + (richcmpfunc)tgl_Peer_RichCompare, /* tp_richcompare */ 0, /* tp_weaklistoffset */ 0, /* tp_iter */ 0, /* tp_iternext */ From cbe442b7c6bb7e73137ea80a687620ef20d51e0b Mon Sep 17 00:00:00 2001 From: Vincent Castellano Date: Fri, 29 May 2015 20:36:26 -0700 Subject: [PATCH 4/7] Add __hash__ to tgl.Peer. --- python-types.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/python-types.c b/python-types.c index 5685390..001abce 100644 --- a/python-types.c +++ b/python-types.c @@ -969,6 +969,12 @@ tgl_Peer_repr(tgl_Peer *self) return ret; } +int +tgl_Peer_hash(PyObject *self) +{ + return PyObject_Hash(PyObject_GetAttrString(self, "id")); +} + PyObject * tgl_Peer_RichCompare(PyObject *self, PyObject *other, int cmp) { @@ -1016,7 +1022,7 @@ PyTypeObject tgl_PeerType = { 0, /* tp_as_number */ 0, /* tp_as_sequence */ 0, /* tp_as_mapping */ - 0, /* tp_hash */ + (hashfunc)tgl_Peer_hash, /* tp_hash */ 0, /* tp_call */ 0, /* tp_str */ 0, /* tp_getattro */ From 63f64a8e70daa880452dc99d1b7a9cb9c9667e45 Mon Sep 17 00:00:00 2001 From: Vincent Castellano Date: Sun, 31 May 2015 20:21:38 -0700 Subject: [PATCH 5/7] Adding tgl.safe_exit() --- main.c | 10 ++++++++-- python-tg.c | 25 +++++++++++++++++-------- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/main.c b/main.c index 1db381c..e109b41 100644 --- a/main.c +++ b/main.c @@ -127,6 +127,7 @@ int ipv6_enabled; char *start_command; int disable_link_preview; int enable_json; +int exit_code; struct tgl_state *TLS; @@ -834,6 +835,7 @@ void sig_term_handler (int signum __attribute__ ((unused))) { } void do_halt (int error) { + int retval; if (daemonize) { return; } @@ -857,8 +859,12 @@ void do_halt (int error) { if (sfd > 0) { close (sfd); } - - exit (error ? EXIT_FAILURE : EXIT_SUCCESS); + + if(exit_code) + retval = exit_code; + else + retval = error ? EXIT_FAILURE : EXIT_SUCCESS; + exit (retval); } int main (int argc, char **argv) { diff --git a/python-tg.c b/python-tg.c index 9a0eb73..764bba5 100644 --- a/python-tg.c +++ b/python-tg.c @@ -1133,6 +1133,21 @@ PyObject* py_status_offline(PyObject *self, PyObject *args) { return push_py_fun PyObject* py_send_location(PyObject *self, PyObject *args) { return push_py_func(pq_send_location, args); } PyObject* py_extf(PyObject *self, PyObject *args) { return push_py_func(pq_extf, args); } +extern int safe_quit; +extern int exit_code; +PyObject* py_safe_quit(PyObject *self, PyObject *args) +{ + int exit_val = 0; + if(PyArg_ParseTuple(args, "|i", &exit_val)) { + safe_quit = 1; + exit_code = exit_val; + } else { + PyErr_Print(); + } + + Py_RETURN_NONE; +} + // Store callables for python functions TGL_PYTHON_CALLBACK("on_binlog_replay_end", _py_binlog_end); @@ -1197,6 +1212,8 @@ static PyMethodDef py_tgl_methods[] = { {"set_on_user_update", set_py_user_update, METH_VARARGS, ""}, {"set_on_chat_update", set_py_chat_update, METH_VARARGS, ""}, {"set_on_loop", set_py_on_loop, METH_VARARGS, ""}, + {"safe_quit", py_safe_quit, METH_VARARGS, ""}, + {"safe_exit", py_safe_quit, METH_VARARGS, ""}, // Alias to safe_quit for naming consistancy in python. { NULL, NULL, 0, NULL } }; @@ -1236,14 +1253,6 @@ MOD_INIT(tgl) return MOD_SUCCESS_VAL(m); } -/* -extern int safe_quit; -static int safe_quit_from_py() { - Py_Finalize(); - safe_quit = 1; - return 1; -} -*/ void py_init (const char *file) { if (!file) { return; } From 05c52fd4982c08e493b123e1299365e70c139f26 Mon Sep 17 00:00:00 2001 From: Vincent Castellano Date: Sun, 31 May 2015 21:13:28 -0700 Subject: [PATCH 6/7] Add global link preview method tgl.set_link_preview(bool) --- python-tg.c | 27 ++++++++++++++++++++++----- python-types.c | 2 +- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/python-tg.c b/python-tg.c index 764bba5..e1835fe 100644 --- a/python-tg.c +++ b/python-tg.c @@ -803,10 +803,12 @@ void py_do_all (void) { case pq_msg: if(PyArg_ParseTuple(args, "O!s#|OO", &tgl_PeerType, &peer, &str, &len, &cb_extra, &pyObj1)) { if(PyArg_ParseTuple(pyObj1, "ii", &preview, &reply_id)) { - if(preview) - flags |= TGL_SEND_MSG_FLAG_ENABLE_PREVIEW; - else - flags |= TGL_SEND_MSG_FLAG_DISABLE_PREVIEW; + if(preview != -1) { + if(preview) + flags |= TGL_SEND_MSG_FLAG_ENABLE_PREVIEW; + else + flags |= TGL_SEND_MSG_FLAG_DISABLE_PREVIEW; + } flags |= TGL_SEND_MSG_FLAG_REPLY (reply_id); } tgl_do_send_message (TLS, PY_PEER_ID(peer), str, len, flags, py_msg_cb, cb_extra); @@ -1135,7 +1137,7 @@ PyObject* py_extf(PyObject *self, PyObject *args) { return push_py_func(pq_extf, extern int safe_quit; extern int exit_code; -PyObject* py_safe_quit(PyObject *self, PyObject *args) +PyObject* py_safe_quit(PyObject *self, PyObject *args) { int exit_val = 0; if(PyArg_ParseTuple(args, "|i", &exit_val)) { @@ -1148,6 +1150,20 @@ PyObject* py_safe_quit(PyObject *self, PyObject *args) Py_RETURN_NONE; } +PyObject* py_set_preview(PyObject *self, PyObject *args) +{ + int preview = 0; + if(PyArg_ParseTuple(args, "p", &preview)) { + if(preview) + TLS->disable_link_preview = 0; + else + TLS->disable_link_preview = 1; + } else { + PyErr_Print(); + } + + Py_RETURN_NONE; +} // Store callables for python functions TGL_PYTHON_CALLBACK("on_binlog_replay_end", _py_binlog_end); @@ -1212,6 +1228,7 @@ static PyMethodDef py_tgl_methods[] = { {"set_on_user_update", set_py_user_update, METH_VARARGS, ""}, {"set_on_chat_update", set_py_chat_update, METH_VARARGS, ""}, {"set_on_loop", set_py_on_loop, METH_VARARGS, ""}, + {"set_link_preview", py_set_preview, METH_VARARGS, ""}, {"safe_quit", py_safe_quit, METH_VARARGS, ""}, {"safe_exit", py_safe_quit, METH_VARARGS, ""}, // Alias to safe_quit for naming consistancy in python. { NULL, NULL, 0, NULL } diff --git a/python-types.c b/python-types.c index 001abce..fdb9e2e 100644 --- a/python-types.c +++ b/python-types.c @@ -378,7 +378,7 @@ tgl_Peer_send_msg (tgl_Peer *self, PyObject *args, PyObject *kwargs) static char *kwlist[] = {"message", "callback", "preview", "reply", NULL}; char *message; - int preview = 1; + int preview = -1; int reply = 0; PyObject *callback = NULL; From f6b14f633c256afa9c29a605408e03823ab99dee Mon Sep 17 00:00:00 2001 From: Vincent Castellano Date: Sun, 31 May 2015 23:24:21 -0700 Subject: [PATCH 7/7] Py_RETURN_NOTIMPLEMENTED macro not available in 2.7 --- python-types.c | 2 +- tgl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python-types.c b/python-types.c index fdb9e2e..3dbdf4b 100644 --- a/python-types.c +++ b/python-types.c @@ -999,7 +999,7 @@ tgl_Peer_RichCompare(PyObject *self, PyObject *other, int cmp) case Py_GT: case Py_LT: default: - Py_RETURN_NOTIMPLEMENTED; + return Py_INCREF(Py_NotImplemented), Py_NotImplemented; } } } diff --git a/tgl b/tgl index 8754957..5a4e6b6 160000 --- a/tgl +++ b/tgl @@ -1 +1 @@ -Subproject commit 8754957b8467802f65fb8c133d3c46fd73295b49 +Subproject commit 5a4e6b61839796e543d63900bb96e6325a9d9474