From 0a1a3a9d7ac45f7bfa8a0dfc5fba0bc880207dbc Mon Sep 17 00:00:00 2001 From: Vincent Castellano Date: Thu, 4 Jun 2015 21:04:54 -0700 Subject: [PATCH 01/11] Look for python3.2mu, specifically in Debian 7 --- ax_python.m4 | 3 ++ configure | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/ax_python.m4 b/ax_python.m4 index 9702193..0f5829d 100644 --- a/ax_python.m4 +++ b/ax_python.m4 @@ -64,6 +64,9 @@ if test x$ax_python_bin != x; then if test x$ax_python_lib == xno; then AC_CHECK_LIB(${ax_python_bin}m, main, ax_python_lib=${ax_python_bin}m, ax_python_lib=no) fi + if test x$ax_python_lib == xno; then + AC_CHECK_LIB(${ax_python_bin}mu, main, ax_python_lib=${ax_python_bin}mu, ax_python_lib=no) + fi if test x$ax_python_lib != xno; then ax_python_header=`$ax_python_bin -c "from distutils.sysconfig import *; print(get_config_var('CONFINCLUDEPY'))"` if test x$ax_python_header != x; then diff --git a/configure b/configure index 93723f5..02941e3 100755 --- a/configure +++ b/configure @@ -6069,6 +6069,46 @@ else ax_python_lib=no fi + fi + if test x$ax_python_lib == xno; then + as_ac_Lib=`$as_echo "ac_cv_lib_${ax_python_bin}mu''_main" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -l${ax_python_bin}mu" >&5 +$as_echo_n "checking for main in -l${ax_python_bin}mu... " >&6; } +if eval \${$as_ac_Lib+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-l${ax_python_bin}mu $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$as_ac_Lib=yes" +else + eval "$as_ac_Lib=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +eval ac_res=\$$as_ac_Lib + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : + ax_python_lib=${ax_python_bin}mu +else + ax_python_lib=no +fi + fi if test x$ax_python_lib != xno; then ax_python_header=`$ax_python_bin -c "from distutils.sysconfig import *; print(get_config_var('CONFINCLUDEPY'))"` @@ -6262,6 +6302,46 @@ else ax_python_lib=no fi + fi + if test x$ax_python_lib == xno; then + as_ac_Lib=`$as_echo "ac_cv_lib_${ax_python_bin}mu''_main" | $as_tr_sh` +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -l${ax_python_bin}mu" >&5 +$as_echo_n "checking for main in -l${ax_python_bin}mu... " >&6; } +if eval \${$as_ac_Lib+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-l${ax_python_bin}mu $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + +int +main () +{ +return main (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + eval "$as_ac_Lib=yes" +else + eval "$as_ac_Lib=no" +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +eval ac_res=\$$as_ac_Lib + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +if eval test \"x\$"$as_ac_Lib"\" = x"yes"; then : + ax_python_lib=${ax_python_bin}mu +else + ax_python_lib=no +fi + fi if test x$ax_python_lib != xno; then ax_python_header=`$ax_python_bin -c "from distutils.sysconfig import *; print(get_config_var('CONFINCLUDEPY'))"` From af9f7b6cfadc95be8b26f7f7901a847e1fed01c0 Mon Sep 17 00:00:00 2001 From: Vincent Castellano Date: Thu, 4 Jun 2015 21:25:49 -0700 Subject: [PATCH 02/11] Use a simple version of repr for Python < 2.7.9 This is due to a bug http://bugs.python.org/issue22023 This addresses https://github.com/vysheng/tg/issues/587 --- python-types.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/python-types.c b/python-types.c index 6d4413c..d909587 100644 --- a/python-types.c +++ b/python-types.c @@ -19,7 +19,6 @@ #include "python-tg.h" extern struct tgl_state *TLS; - // TGL Python Exceptions extern PyObject *TglError; extern PyObject *PeerError; @@ -944,7 +943,10 @@ tgl_Peer_repr(tgl_Peer *self) switch(self->peer->id.type) { case TGL_PEER_USER: - ret = PyUnicode_FromFormat("", +#if PY_VERSION_HEX < 0x02070900 + ret = PyUnicode_FromFormat("", self->peer->id.id); +#else + ret = PyUnicode_FromFormat("", self->peer->id.id, PyObject_GetAttrString((PyObject*)self, "username"), PyObject_GetAttrString((PyObject*)self, "name"), @@ -952,6 +954,7 @@ tgl_Peer_repr(tgl_Peer *self) PyObject_GetAttrString((PyObject*)self, "last_name"), PyObject_GetAttrString((PyObject*)self, "phone") ); +#endif break; case TGL_PEER_CHAT: ret = PyUnicode_FromFormat("", @@ -1423,7 +1426,9 @@ static PyObject * tgl_Msg_repr(tgl_Msg *self) { PyObject *ret; - +#if PY_VERSION_HEX < 0x02070900 + ret = PyUnicode_FromFormat("", self->msg->id); +#else ret = PyUnicode_FromFormat("", self->msg->id, self->msg->flags, @@ -1441,7 +1446,7 @@ tgl_Msg_repr(tgl_Msg *self) PyObject_GetAttrString((PyObject*)self, "reply_id"), PyObject_GetAttrString((PyObject*)self, "reply") ); - +#endif return ret; } From 495d33e92a8d0ff686aa6296ec605ea7a3bffcbc Mon Sep 17 00:00:00 2001 From: Vincent Castellano Date: Thu, 4 Jun 2015 22:38:14 -0700 Subject: [PATCH 03/11] Add support for tgl.import_chat_link(str) Also fix bug with tgl.extf --- python-tg.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/python-tg.c b/python-tg.c index b206b3f..adf509b 100644 --- a/python-tg.c +++ b/python-tg.c @@ -467,7 +467,8 @@ enum py_query_type { pq_status_online, pq_status_offline, pq_send_location, - pq_extf + pq_extf, + pq_import_chat_link }; void py_empty_cb (struct tgl_state *TLSR, void *cb_extra, int success) { @@ -1062,7 +1063,13 @@ void py_do_all (void) { break; case pq_extf: if(PyArg_ParseTuple(args, "s#|O", &str, &len, &cb_extra)) - tgl_do_send_extf (TLS, str, len, py_str_cb, &cb_extra); + tgl_do_send_extf (TLS, str, len, py_str_cb, cb_extra); + else + PyErr_Print(); + break; + case pq_import_chat_link: + if(PyArg_ParseTuple(args, "s#|O", &str, &len, &cb_extra)) + tgl_do_import_chat_link (TLS, str, len, py_empty_cb, cb_extra); else PyErr_Print(); break; @@ -1146,6 +1153,7 @@ PyObject* py_status_online(PyObject *self, PyObject *args) { return push_py_func PyObject* py_status_offline(PyObject *self, PyObject *args) { return push_py_func(pq_status_offline, args); } 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); } +PyObject* py_import_chat_link(PyObject *self, PyObject *args) { return push_py_func(pq_import_chat_link, args); } extern int safe_quit; extern int exit_code; @@ -1232,6 +1240,7 @@ static PyMethodDef py_tgl_methods[] = { {"status_offline", py_status_offline, METH_VARARGS, ""}, {"send_location", py_send_location, METH_VARARGS, ""}, {"ext_function", py_extf, METH_VARARGS, ""}, + {"import_chat_link", py_import_chat_link, METH_VARARGS, ""}, {"set_on_binlog_replay_end", set_py_binlog_end, METH_VARARGS, ""}, {"set_on_get_difference_end", set_py_diff_end, METH_VARARGS, ""}, {"set_on_our_id", set_py_our_id, METH_VARARGS, ""}, From c13880e07c5fd3df1e0a520d3aa2d6d03e87fb80 Mon Sep 17 00:00:00 2001 From: Vincent Castellano Date: Thu, 4 Jun 2015 23:37:21 -0700 Subject: [PATCH 04/11] Adding new documentation --- README-PY.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 README-PY.md diff --git a/README-PY.md b/README-PY.md new file mode 100644 index 0000000..7c5c1e2 --- /dev/null +++ b/README-PY.md @@ -0,0 +1,9 @@ +Python Bindings Notes +====================== + +The python integration is written with Python 2/3 in mind, however, there is a bias to Python 3. Because of this, there are a few caveats: +- I am only testing against Python 2.7, and have no intention to support/test < 2.7 but am more than happy to accept PRs for fixes as long as it does not break 2.7/3 +- repr/print of native types is dumbed down for < 2.7.9, I highly recommend using this version or new. (This is due to a [bug](http://bugs.python.org/issue22023) in python) + +# TGL Module Level Fuctions + From f1ea76b9bbfeeef1aaa948e10eb244097224a1fc Mon Sep 17 00:00:00 2001 From: Vincent Castellano Date: Fri, 5 Jun 2015 01:20:18 -0700 Subject: [PATCH 05/11] First pass at improved documentation. --- README-PY.md | 117 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 114 insertions(+), 3 deletions(-) diff --git a/README-PY.md b/README-PY.md index 7c5c1e2..34391a8 100644 --- a/README-PY.md +++ b/README-PY.md @@ -1,9 +1,120 @@ -Python Bindings Notes -====================== +Python Bindings +==================== +All of the functions and methods are executed in the network loop of tg, ***NOT IMMEDIATELY***. What this means is all calls should be considered async, and so there is an optional callback parameter for every function/method as the last parameter. For many uses, you won't care about the return value, so you can leave out the callback. Note there are a few cases where the callback is considered mandatory when the function is considered an information query and has no functionality without returned data. These will explicitly have the callback in the parameter list and will be noted in the description. +Version Notes +===================== The python integration is written with Python 2/3 in mind, however, there is a bias to Python 3. Because of this, there are a few caveats: - I am only testing against Python 2.7, and have no intention to support/test < 2.7 but am more than happy to accept PRs for fixes as long as it does not break 2.7/3 - repr/print of native types is dumbed down for < 2.7.9, I highly recommend using this version or new. (This is due to a [bug](http://bugs.python.org/issue22023) in python) -# TGL Module Level Fuctions +TGL Callbacks +============= +Assign python fuctions to the following tgl attributes to set callbacks from TG. + +| Callback | Description | +|--------- | ---------------------| +|`tgl.on_binlog_replay_end()` | This is called when replay of old events end. Any updates prior this call were already received by this client some time ago.| +|`tgl.on_get_difference_end()`| This is called after first get_difference call. So we received all updates after last client execute.| +|`tgl.on_our_id(our_id)`|Informs about id of currently logged in user.| +|`tgl.on_msg_receive(msg)`| This is called when we receive new `tgl.Msg` object (*may be called before on_binlog_replay_end, than it is old msg*).| +|`tgl.on_user_update(peer, what_changed)`|updated info about user. peer is a `tgl.Peer` object representing the user, and what_changed is array of strings.| +|`tgl.on_chat_update(peer, what_changed)`|updated info about chat. peer is a `tgl.Peer` object representing the chat, and what_changed is array of strings.| +|`tgl.on_secret_chat_update(peer, what_changed)`|updated info about secret chat. peer is a `tgl.Peer` object representing the secret chat, and what_changed is array of strings.| + +Python Callback Signatures +========================= +As mentioned, all methods and functions have callbacks. The following are the different signatures that may be required (*The description of the method will mention which is used*) + +| Type | Signature | Description | +|----- | ------------------ | ------------| +|empty_cb|`(success)`|This just indicated the success of the call. All other callback types have this as well.| +|contact_list_cb|`(success, peer_list)`|`peer_list` is a list of `tgl.Peer` objects| +|dialog_list_cb|`(success, dialog_list)`|`dialog_list` is a list of dicts, with keys: 'peer': `tgl.Peer`, 'message': `tgl.Msg`| +|msg_cb|`(success, msg)`|`msg` is a `tgl.Msg`| +|msg_list_cb|`(success, msg_list)`|`msg_list` is a list of `tgl.Msg` objects| +|file_cb|`(success, file_path)`|`file_path` is a string with an absolute path| +|chat_cb|`(success, peer)`|`peer` is a `tgl.Peer` that will have the type of `tgl.PEER_CHAT`| +|peer_cb|`(success, peer)`|`peer` is a `tgl.Peer`| +|secret_chat_cb|`(success, peer)`|`peer` is a `tgl.Peer` that will have the type of `tgl.PEER_ENCR_CHAT`| +|user_cb|`(success, peer)`|`peer` is a `tgl.Peer` that will have the type of `tgl.PEER_USER`| +|str_cb|`(success, string)`|`string` is a simple string| + +TGL Module Level Fuctions +========================= +All of these functions are accessed by importing the `tgl` module. + +| Function | Description | Callback Type | +|--------- | ---------------------| ------------- | +|`tgl.get_contact_list (callback)`|Retrieve peers stored in the contact list. *requires callback*|`contact_list_cb`| +|`tgl.get_dialog_list (callback)`|Get a list of current conversations with the `tgl.Peer` and the most recent `tgl.Msg`. *requires callback*|`dialog_list_cb`| +|`tgl.add_contact (phone, first_name, last_name)`|Adds contact to contact list, last name is optional|`contact_list_cb`| +|`tgl.del_contact (peer)`|Removes contact from contact list|`empty_cb`| +|`tgl.rename_contact (phone, first_name, last_name) `|Renaming a contact means sending the first/last name with the same phone number of an existing contact|`contact_list_cb`| +|`tgl.msg_global_search (text, callback)`|Get all messages that match the search text. *requires callback*|`msg_list_cb`| +|`tgl.set_profile_photo (file_path)`|Sets avatar to image found at `file_path`, no checking on the file.|`empty_cb`| +|`tgl.create_secret_chat (user)`|Creates secret chat with user, callback recommended to get new peer for the secret chat.|`secret_chat_cb`| +|`tgl.create_group_chat (peer_list, name)`|`peer_list` contains users to create group with, must be more than 1 peer.|`empty_cb`| +|`tgl.restore_msg (msg_id)`|Restore a deleted message by message id.|`empty_cb`| +|`tgl.status_online ()`|Sets status as online|`empty_cb`| +|`tgl.status_offline ()`|Sets status as offline|`empty_cb`| +|`tgl.import_chat_link (link)`|Join channel using the `link`.|`empty_cb`| + +Peer +==== +## Attributes +| Attribute | Description | +|---------- | ---------------------| +## Methods +| Method | Description | Callback Type | +|------- | ---------------------| ------------- | +|`peer.rename_chat (new_name)`||`empty_cb`| +|`peer.chat_set_photo (file)`|Sets avatar for the group to image found at `file_path`, no checking on the file. The calling peer must be of type `tgl.PEER_CHAT`.|`msg_cb`| +|`peer.send_typing ()`|Tell peer that you are typing.|`empty_cb`| +|`peer.send_typing_abort ()`|Tell peer you are done typing.|`empty_cb`| +|`peer.send_msg (text, reply=msg_id, preview=bool)`|Sends message to peer. Optional keyword arguments: reply is the message id we are replying to, preview is a boolean that forces URL preview on or off.|`msg_cb`| +|`peer.fwd_msg (msg_id)`|Forwards msg with message id to peer.|`msg_cb`| +|`peer.fwd_media (msg_id)`|Forwards media with message id to peer.|`msg_cb`| +|`peer.send_photo (file)`|Send media to peer using `file`. No checking is done on the contents of the file.|`msg_cb`| +|`peer.send_video (file)`|Send media to peer using `file`. No checking is done on the contents of the file.|`msg_cb`| +|`peer.send_audio (file)`|Send media to peer using `file`. No checking is done on the contents of the file.|`msg_cb`| +|`peer.send_document (file)`|Send media to peer using `file`. No checking is done on the contents of the file.|`msg_cb`| +|`peer.send_text (file)`|Send media to peer using `file`. No checking is done on the contents of the file.|`msg_cb`| +|`peer.send_location (latitude, longitude)`|Sends location media message to peer, `longitude` and `latitude` should be specified as double.|`msg_cb`| +|`peer.chat_add_user (user)`|Adds `user`(`tgl.Peer`) to the group. The calling peer must be of type `tgl.PEER_CHAT`|`empty_cb`| +|`peer.chat_del_user (user)`|Removes `user`(`tgl.Peer`) from the group. The calling peer must be of type `tgl.PEER_CHAT`|`empty_cb`| +|`peer.mark_read ()`|Marks the dialog with the peer as read. This cannot be done on message level.|`empty_cb`| +|`peer.msg_search (text, callback)`|Get all messages that match the search text with the peer. *requires callback*|`msg_list_cb`| +|`peer.get_history (offset, limit, callback)`|Get all messages with the peer. `offset` specifies what message to start at, and `limit` specifies how many messages to retrieve. See example below for one method to get the entire history. *requires callback*|`msg_list_cb`| +|`peer.info ()`|Gets peer info.|`peer_cb`| + +Example usage for `peer.get_history`: +``` +from functools import partial +history = [] +# Get all the history, 100 msgs at a time +peer.get_history(0, 100, partial(history_callback, 100, peer)) + +def history_callback(msg_count, peer, success, msgs) + history.extend(msgs) + if len(msgs) == msg_count: + peer.get_history(len(history), msg_count, partial(history_callback, msg_count, peer)) +``` + +Msg +==== +## Attributes +| Attribute | Description | +|---------- | ---------------------| +## Methods +| Method | Description | Callback Type | +|------- | ---------------------| ------------- | +|`msg.load_photo(callback)`|Saves the media and returns the path to the file in the callback. *requires callback*|`file_cb`| +|`msg.load_video(callback)`|Saves the media and returns the path to the file in the callback. *requires callback*|`file_cb`| +|`msg.load_video_thumb(callback)`|Saves the media and returns the path to the file in the callback. *requires callback*|`file_cb`| +|`msg.load_audio(callback)`|Saves the media and returns the path to the file in the callback. *requires callback*|`file_cb`| +|`msg.load_document(callback)`|Saves the media and returns the path to the file in the callback. *requires callback*|`file_cb`| +|`msg.load_document_thumb(callback)`|Saves the media and returns the path to the file in the callback. *requires callback*|`file_cb`| +|`msg.delete_msg ()`|Deletes the message from the local history|`empty_cb`| + From b979de81edf662a56c78acb093e95c8c9a731f81 Mon Sep 17 00:00:00 2001 From: Vincent Castellano Date: Fri, 5 Jun 2015 01:49:35 -0700 Subject: [PATCH 06/11] Adding class attributes. --- README-PY.md | 62 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/README-PY.md b/README-PY.md index 34391a8..4aa97a6 100644 --- a/README-PY.md +++ b/README-PY.md @@ -63,8 +63,20 @@ All of these functions are accessed by importing the `tgl` module. Peer ==== ## Attributes -| Attribute | Description | -|---------- | ---------------------| +| Attribute | Type | Description | +|---------- | ---- | ----------------------| +|`id`|`int`|Telegram peer id| +|`type`|`int`|Peer type, you can compare this with `tgl.PEER_CHAT`, `tgl.PEER_USER`, or `tgl.PEER_ENCR_CHAT`| +|`type_name`|`string`|Text representation of the type of the peer, `'chat'`, `'user'`, or `'secret_chat'`| +|`name`|`string`|Returns the tg print version of the name. Usually `FirstName_LastName` for user, and the chatname with spaces replaced with `_`| +|`user_id`|`int`|Used in secret chats, since a secret chat has it's own id, this is the id of the user at the endpoint.| +|`user_list`|`peer_list`|Only used in `tgl.PEER_CHAT` peers, contains list of users. This currently does not work, it is not populating properly.| +|`user_status`|`dict`|Only used in `tgl.PEER_USER` peers. Dictionary with the current status, keys: 'online': `bool`, 'when': `datetime`| +|`phone`|`string`|Only used in `tgl.PEER_USER` peers. Phone number, only available if user is on contact list.| +|`username`|`string`|Only used in `tgl.PEER_USER` peers. Will be `None` if username is not set.| +|`first_name`|`string`|Only used in `tgl.PEER_USER` peers.| +|`last_name`|`string`|Only used in `tgl.PEER_USER` peers.| + ## Methods | Method | Description | Callback Type | |------- | ---------------------| ------------- | @@ -104,8 +116,50 @@ def history_callback(msg_count, peer, success, msgs) Msg ==== ## Attributes -| Attribute | Description | -|---------- | ---------------------| +| Attribute | Type | Description | +|---------- | ---- | ----------------------| +|`id`|`int`|Message id| +|`flags`|`int`|tgl flags, see source code for tgl for various possible flags. This is a bitfield in an int.| +|`mention`|`bool`|`True` if you are @mentioned.| +|`out`|`bool`|`True` if you sent this message.| +|`unread`|`bool`|`True` if you have not marked this as read.| +|`service`|`bool`|`True` if the message is a service messages, see tgl.Msg.action for the type.| +|`src`|`tgl.Peer`|Peer who sent the message| +|`dest`|`tgl.Peer`|Peer who the message was sent too. In a group, this will be the chat peer. Otherwise it will be you.| +|`text`|`string`|Text contents of the message. This may be `None` if it's media without caption.| +|`media`|`dict`|Dictionary that varies based on the media type.| +|`date`|`datetime`|When the message was sent.| +|`fwd_src`|`tgl.Peer`|The user that sent the forwarded message.| +|`fwd_date`|`datetime`|When the forwarded message was originally sent.| +|`reply`|`tgl.Msg`|Message that this message is replying to.| +|`reply_id`|`int`|Message id that this message is replying to.| +|`action`|`int`|Action enum for the message if `msg.service == True`. See all the possible values below| + +## Action Type Constants +- tgl.ACTION_NONE +- tgl.ACTION_GEO_CHAT_CREATE +- tgl.ACTION_GEO_CHAT_CHECKIN +- tgl.ACTION_CHAT_CREATE +- tgl.ACTION_CHAT_EDIT_TITLE +- tgl.ACTION_CHAT_EDIT_PHOTO +- tgl.ACTION_CHAT_DELETE_PHOTO +- tgl.ACTION_CHAT_ADD_USER +- tgl.ACTION_CHAT_ADD_USER_BY_LINK +- tgl.ACTION_CHAT_DELETE_USER +- tgl.ACTION_SET_MESSAGE_TTL +- tgl.ACTION_READ_MESSAGES +- tgl.ACTION_DELETE_MESSAGES +- tgl.ACTION_SCREENSHOT_MESSAGES +- tgl.ACTION_FLUSH_HISTORY +- tgl.ACTION_RESEND +- tgl.ACTION_NOTIFY_LAYER +- tgl.ACTION_TYPING +- tgl.ACTION_NOOP +- tgl.ACTION_COMMIT_KEY +- tgl.ACTION_ABORT_KEY +- tgl.ACTION_REQUEST_KEY +- tgl.ACTION_ACCEPT_KEY + ## Methods | Method | Description | Callback Type | |------- | ---------------------| ------------- | From 45aa6bf35d410721adab8cf984d77346659dc6db Mon Sep 17 00:00:00 2001 From: Vincent Castellano Date: Fri, 5 Jun 2015 01:52:49 -0700 Subject: [PATCH 07/11] Add save_exit to tgl functions. --- README-PY.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README-PY.md b/README-PY.md index 4aa97a6..5ba54a7 100644 --- a/README-PY.md +++ b/README-PY.md @@ -59,6 +59,7 @@ All of these functions are accessed by importing the `tgl` module. |`tgl.status_online ()`|Sets status as online|`empty_cb`| |`tgl.status_offline ()`|Sets status as offline|`empty_cb`| |`tgl.import_chat_link (link)`|Join channel using the `link`.|`empty_cb`| +|`tgl.safe_exit (exit_status)`|Exception to the rule about callbacks, none is accepted. Causes the bot to quit after cleaning up. `exit_status` is an optional parameter with the exit status (On glibc, this must be 0-255)|NONE| Peer ==== @@ -170,5 +171,3 @@ Msg |`msg.load_document(callback)`|Saves the media and returns the path to the file in the callback. *requires callback*|`file_cb`| |`msg.load_document_thumb(callback)`|Saves the media and returns the path to the file in the callback. *requires callback*|`file_cb`| |`msg.delete_msg ()`|Deletes the message from the local history|`empty_cb`| - - From c170e98bf74f92861ca1f6187960442beda30766 Mon Sep 17 00:00:00 2001 From: Vincent Castellano Date: Fri, 5 Jun 2015 01:54:07 -0700 Subject: [PATCH 08/11] Remove old docs. --- README-PY | 95 ------------------------------------------------------- 1 file changed, 95 deletions(-) delete mode 100644 README-PY diff --git a/README-PY b/README-PY deleted file mode 100644 index ae4467b..0000000 --- a/README-PY +++ /dev/null @@ -1,95 +0,0 @@ -To use python with client you should write python script. You can specify it from config ("python_script" option) or from command_line [-Z]. - -You should set the following callbacks in your script: - tgl.on_binlog_replay_end() - it is called when replay of old events end. Any updates prior this call were already received by this client - some time ago. - - tgl.on_get_difference_end() - it is called after first get_difference call. So we received all updates after last client execute. - - tgl.on_our_id(our_id) - Informs about id of currently logged in user. - - tgl.on_msg_receive(msg) - it is called when we receive new msg (!! may be called before on_binlog_replay_end, than it is old msg). - - tgl.on_user_update(peer, what_changed) - updated info about user. what_changed is array of strings. - tgl.on_chat_update(peer, what_changed) - updated info about user. what_changed is array of strings. - tgl.on_secret_chat_update(peer, what_changed) - updated info about user. what_changed is array of strings. - - - -Also, you can call several functions. Each this function last two arguments, are callback, which is a python function implementing the callback from the function. -These functions may return false immidiately if something is bad with args, or return true and call cb_function in future. -The callback function should have one arguments: first success (True or False), and the rest depends on the call. -Functions that require a peer type other than what is passed will raise tgl.PeerError. - - -Function_list (arguments are listed aside from callback, import tgl for access) : - tgl.get_contact_list () - tgl.get_dialog_list () - - tgl.rename_chat (peer, new_name) - tgl.chat_set_photo (peer, file) - - tgl.send_typing (peer) - tgl.send_typing_abort (peer) - - tgl.send_msg (peer, text) - tgl.fwd_msg (peer, msg) - - tgl.send_photo (peer, file) - tgl.send_video (peer, file) - tgl.send_audio (peer, file) - tgl.send_document (peer, file) - tgl.send_text (peer, file) - - tgl.load_photo(msg) - tgl.load_video(msg) - tgl.load_video_thumb(msg) - tgl.load_audio(msg) - tgl.load_document(msg) - tgl.load_document_thumb(msg) - - tgl.info (peer) - - tgl.get_history (peer, limit) - - tgl.chat_add_user (peer, user) - tgl.chat_del_user (peer, user) - - tgl.add_contact (phone, first_name, last_name) - tgl.rename_contact (phone, first_name, last_name) - - tgl.msg_search (peer, text) - tgl.msg_global_search (text) - - tgl.mark_read (peer) - - tgl.set_profile_photo (file) - - tgl.create_secret_chat (user) - tgl.create_group_chat (peer, name) - - tgl.delete_msg (msg) - tgl.restore_msg (msg_id) - - tgl.status_online () - tgl.status_offline () - - tgl.send_location (peer, latitude, longitude) - -Additionally, the tgl.Peer object has the following direct methods: - peer.rename_chat(new_name) - peer.chat_set_photo(file) - peer.send_typing() - peer.send_typing_abort() - peer.send_msg(text) - peer.send_photo(file) - peer.send_video(file) - peer.send_document(file) - peer.send_text(file) - peer.info() - peer.history(limit, offset) - peer.add_user(peer) - peer.del_user(peer) - peer.search(text) - peer.mark_read() - peer.send_location(latitude, longitude) From c31a7ef5249ab0e6ed7badd9fb7ac16f6e287fc1 Mon Sep 17 00:00:00 2001 From: Vincent Castellano Date: Fri, 5 Jun 2015 02:05:24 -0700 Subject: [PATCH 09/11] Adding doc for how to run script. --- README-PY.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README-PY.md b/README-PY.md index 5ba54a7..e8e01c1 100644 --- a/README-PY.md +++ b/README-PY.md @@ -2,6 +2,8 @@ Python Bindings ==================== All of the functions and methods are executed in the network loop of tg, ***NOT IMMEDIATELY***. What this means is all calls should be considered async, and so there is an optional callback parameter for every function/method as the last parameter. For many uses, you won't care about the return value, so you can leave out the callback. Note there are a few cases where the callback is considered mandatory when the function is considered an information query and has no functionality without returned data. These will explicitly have the callback in the parameter list and will be noted in the description. +You can specify the python script from config ("python_script" option) or from command_line [-Z]. + Version Notes ===================== The python integration is written with Python 2/3 in mind, however, there is a bias to Python 3. Because of this, there are a few caveats: From 5285cf2bd2bbd9094d44524277f2c7430e644c3e Mon Sep 17 00:00:00 2001 From: Vincent Castellano Date: Fri, 5 Jun 2015 02:16:42 -0700 Subject: [PATCH 10/11] Grammar fixes. --- README-PY.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README-PY.md b/README-PY.md index e8e01c1..09ae1bb 100644 --- a/README-PY.md +++ b/README-PY.md @@ -8,7 +8,7 @@ Version Notes ===================== The python integration is written with Python 2/3 in mind, however, there is a bias to Python 3. Because of this, there are a few caveats: - I am only testing against Python 2.7, and have no intention to support/test < 2.7 but am more than happy to accept PRs for fixes as long as it does not break 2.7/3 -- repr/print of native types is dumbed down for < 2.7.9, I highly recommend using this version or new. (This is due to a [bug](http://bugs.python.org/issue22023) in python) +- repr/print of native types is dumbed down for < 2.7.9, I highly recommend using this version or newer. (This is due to a [bug](http://bugs.python.org/issue22023) in python) TGL Callbacks ============= @@ -61,7 +61,7 @@ All of these functions are accessed by importing the `tgl` module. |`tgl.status_online ()`|Sets status as online|`empty_cb`| |`tgl.status_offline ()`|Sets status as offline|`empty_cb`| |`tgl.import_chat_link (link)`|Join channel using the `link`.|`empty_cb`| -|`tgl.safe_exit (exit_status)`|Exception to the rule about callbacks, none is accepted. Causes the bot to quit after cleaning up. `exit_status` is an optional parameter with the exit status (On glibc, this must be 0-255)|NONE| +|`tgl.safe_exit (exit_status)`|Exception to the rule about callbacks, no callback parameter is accepted. Causes the bot to quit after cleaning up. `exit_status` is an optional parameter with the exit status (On glibc, this must be 0-255)|NONE| Peer ==== From 4c5f9b797ac5d1710bb0b225518eded9f0b458ac Mon Sep 17 00:00:00 2001 From: Vincent Castellano Date: Wed, 10 Jun 2015 00:28:01 -0700 Subject: [PATCH 11/11] Add missing null check --- python-tg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python-tg.c b/python-tg.c index adf509b..a0e36fc 100644 --- a/python-tg.c +++ b/python-tg.c @@ -808,7 +808,7 @@ void py_do_all (void) { break; 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(pyObj1 && PyArg_ParseTuple(pyObj1, "ii", &preview, &reply_id)) { if(preview != -1) { if(preview) flags |= TGL_SEND_MSG_FLAG_ENABLE_PREVIEW;