diff --git a/python-tg.c b/python-tg.c index 5a1a9ad..b216390 100644 --- a/python-tg.c +++ b/python-tg.c @@ -24,7 +24,6 @@ #ifdef USE_PYTHON #include "python-tg.h" -#include "python-types.h" #endif #include @@ -74,6 +73,11 @@ // Python Imports #include "datetime.h" +// Custom Types +#include "python-types.h" + + + //#include "interface.h" //#include "auto/constants.h" #include @@ -269,7 +273,7 @@ PyObject* get_update_types (unsigned flags) { PyObject* get_peer (tgl_peer_id_t id, tgl_peer_t *P) { PyObject *peer; - +/* peer = PyDict_New(); if(peer == NULL) assert(0); // TODO handle python exception; @@ -320,7 +324,9 @@ PyObject* get_peer (tgl_peer_id_t id, tgl_peer_t *P) { } PyDict_SetItemString (peer, "peer", peer_obj); } +*/ + peer = tgl_Peer_FromTglPeer(P); return peer; } diff --git a/python-types.h b/python-types.h index 25dea90..8092416 100644 --- a/python-types.h +++ b/python-types.h @@ -3,6 +3,9 @@ #include #include +#include +#include +#include #include #include #include "structmember.h" @@ -20,26 +23,28 @@ tgl_Peer_dealloc(tgl_Peer* self) { switch(self->peer.id.type) { case TGL_PEER_USER: - if (self->peer.first_name) tfree_str(self->peer.first_name); - if (self->peer.last_name) tfree_str(self->peer.last_name); - if (self->peer.print_name) tfree_str(self->peer.print_name); - if (self->peer.phone) tfree_str(self->peer.phone); - if (self->peer.real_first_name) tfree_str(self->peer.real_first_name); - if (self->peer.real_last_name) tfree_str(self->peer.real_last_name); - if (self->peer.status.ev) { tgl_remove_status_expire (TLS, &self->peer); } - tgls_free_photo (TLS, self->peer.photo); + if (self->peer.user.first_name) tfree_str(self->peer.user.first_name); + if (self->peer.user.last_name) tfree_str(self->peer.user.last_name); + if (self->peer.user.print_name) tfree_str(self->peer.user.print_name); + if (self->peer.user.phone) tfree_str(self->peer.user.phone); + if (self->peer.user.real_first_name) tfree_str(self->peer.user.real_first_name); + if (self->peer.user.real_last_name) tfree_str(self->peer.user.real_last_name); + if (self->peer.user.status.ev) { tgl_remove_status_expire (TLS, &self->peer.user); } + tgls_free_photo (TLS, self->peer.user.photo); break; case TGL_PEER_CHAT: - if (self->peer.title) tfree_str(self->peer.title); - if (self->peer.print_title) tfree_str(self->peer.print_title); - if (self->peer.user_list) tfree(self->peer.user_list, self->peer.user_list_size * sizeof(tgl_chat_user)); - tgls_free_photo (TLS, self->peer.photo); + if (self->peer.chat.title) tfree_str(self->peer.chat.title); + if (self->peer.chat.print_title) tfree_str(self->peer.chat.print_title); + if (self->peer.chat.user_list) + tfree(self->peer.chat.user_list, self->peer.chat.user_list_size * sizeof(struct tgl_chat_user)); + tgls_free_photo (TLS, self->peer.chat.photo); break; case TGL_PEER_ENCR_CHAT: - if (self->peer.print_name) tfree_str(self->peer.print_name); - if (self->peer.g_key) tfree (self->peer.g_key, 256); + if (self->peer.encr_chat.print_name) tfree_str(self->peer.encr_chat.print_name); + if (self->peer.encr_chat.g_key) tfree (self->peer.encr_chat.g_key, 256); break; default: + PyErr_SetString(PyExc_TypeError, "peer.type not supported!"); } Py_TYPE(self)->tp_free((PyObject*)self); @@ -59,6 +64,8 @@ tgl_Peer_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return (PyObject *)self; } + + static int tgl_Peer_init(tgl_Peer *self, PyObject *args, PyObject *kwds) { @@ -73,13 +80,25 @@ tgl_Peer_init(tgl_Peer *self, PyObject *args, PyObject *kwds) } static PyObject * -tgl_Peer_get_name (tgl_Peer *self, void *closure) +tgl_Peer_getname (tgl_Peer *self, void *closure) { PyObject *ret; - if(self->peer.id.type == TGL_PEER_CHAT) - ret = PyUnicode_FromString(self->peer.print_title); - else - ret = PyUnicode_FromString(self->peer.print_name); + + switch(self->peer.id.type) { + case TGL_PEER_USER: + ret = PyUnicode_FromString(self->peer.user.print_name); + break; + case TGL_PEER_CHAT: + ret = PyUnicode_FromString(self->peer.chat.print_title); + break; + case TGL_PEER_ENCR_CHAT: + ret = PyUnicode_FromString(self->peer.encr_chat.print_name); + break; + default: + PyErr_SetString(PyExc_TypeError, "peer.type not supported!"); + Py_RETURN_NONE; + } + Py_XINCREF(ret); return ret; @@ -91,13 +110,21 @@ tgl_Peer_getuser_id (tgl_Peer *self, void *closure) { PyObject *ret; - if(self->peer.id.type == TGL_PEER_CHAT) - { - PyErr_SetString(PyExc_TypeError, - "peer.type == TGL_PEER_CHAT has no user_id"); - Py_RETURN_NONE; - } else { - ret = PyLong_FromLong(self->peer.user_id); + switch(self->peer.id.type) { + case TGL_PEER_USER: + ret = PyLong_FromLong(self->peer.id.id); + break; + case TGL_PEER_CHAT: + PyErr_SetString(PyExc_TypeError, "peer.type == TGL_PEER_CHAT has no user_id"); + Py_RETURN_NONE; + + break; + case TGL_PEER_ENCR_CHAT: + ret = PyLong_FromLong(self->peer.encr_chat.user_id); + break; + default: + PyErr_SetString(PyExc_TypeError, "peer.type not supported!"); + Py_RETURN_NONE; } Py_XINCREF(ret); @@ -108,19 +135,27 @@ static PyObject * tgl_Peer_getuser_list (tgl_Peer *self, void *closure) { PyObject *ret, *peer; - tgl_chat_user *user_list; + int i; + struct tgl_chat_user *user_list; + struct tgl_user *user; - if(self->peer.id.type == TGL_PEER_CHAT) - { - ret = PyList_New(); - for(int i = 0; i < self->peer.user_list_size; i++) { - user_list = self->peer.userlist + i; - - } - } else { - PyErr_SetString(PyExc_TypeError, - "Only peer.type == TGL_PEER_CHAT has user_list"); - Py_RETURN_NONE; + switch(self->peer.id.type) { + case TGL_PEER_CHAT: + ret = PyList_New(0); + for(i = 0; i < self->peer.chat.user_list_size; i++) { + // TODO: Sort tgl_user objects, maybe offline mode is enoug? + user_list = self->peer.chat.user_list + i; + PyList_Append(ret, PyLong_FromLong(user_list->user_id)); + } + break; + case TGL_PEER_ENCR_CHAT: + case TGL_PEER_USER: + PyErr_SetString(PyExc_TypeError, "Only peer.type == TGL_PEER_CHAT has user_list"); + Py_RETURN_NONE; + break; + default: + PyErr_SetString(PyExc_TypeError, "peer.type not supported!"); + Py_RETURN_NONE; } Py_XINCREF(ret); @@ -128,69 +163,87 @@ tgl_Peer_getuser_list (tgl_Peer *self, void *closure) } static PyObject * -tgl_Peer_get (tgl_Peer *self, void *closure) +tgl_Peer_getuser_status(tgl_Peer *self, void *closure) { PyObject *ret; + switch(self->peer.id.type) { + case TGL_PEER_USER: + ret = PyDict_New(); + PyDict_SetItemString(ret, "online", self->peer.user.status.online? Py_True : Py_False); + PyDict_SetItemString(ret, "when", PyDateTime_FromTimestamp(Py_BuildValue("(O)", + PyLong_FromLong(self->peer.user.status.when)))); + + break; + case TGL_PEER_CHAT: + case TGL_PEER_ENCR_CHAT: + PyErr_SetString(PyExc_TypeError, "Only peer.type == TGL_PEER_USER has user_status"); + Py_RETURN_NONE; + break; + default: + PyErr_SetString(PyExc_TypeError, "peer.type not supported!"); + Py_RETURN_NONE; + } + Py_XINCREF(ret); return ret; } static PyObject * -tgl_Peer_get (tgl_Peer *self, void *closure) +tgl_Peer_getphone (tgl_Peer *self, void *closure) { PyObject *ret; + switch(self->peer.id.type) { + case TGL_PEER_USER: + ret = PyUnicode_FromString(self->peer.user.phone); + break; + case TGL_PEER_CHAT: + case TGL_PEER_ENCR_CHAT: + PyErr_SetString(PyExc_TypeError, "Only peer.type == TGL_PEER_USER has phone"); + Py_RETURN_NONE; + break; + default: + PyErr_SetString(PyExc_TypeError, "peer.type not supported!"); + Py_RETURN_NONE; + } + Py_XINCREF(ret); return ret; } static PyObject * -tgl_Peer_get (tgl_Peer *self, void *closure) +tgl_Peer_getusername (tgl_Peer *self, void *closure) { PyObject *ret; + switch(self->peer.id.type) { + case TGL_PEER_USER: + ret = PyUnicode_FromString(self->peer.user.username); + break; + case TGL_PEER_CHAT: + case TGL_PEER_ENCR_CHAT: + PyErr_SetString(PyExc_TypeError, "Only peer.type == TGL_PEER_USER has username"); + Py_RETURN_NONE; + break; + default: + PyErr_SetString(PyExc_TypeError, "peer.type not supported!"); + Py_RETURN_NONE; + } + Py_XINCREF(ret); return ret; } -static PyObject * -tgl_Peer_get (tgl_Peer *self, void *closure) -{ - PyObject *ret; - - Py_XINCREF(ret); - return ret; -} - -static PyObject * -tgl_Peer_get (tgl_Peer *self, void *closure) -{ - PyObject *ret; - - Py_XINCREF(ret); - return ret; -} - -static PyObject * -tgl_Peer_get (tgl_Peer *self, void *closure) -{ - PyObject *ret; - - Py_XINCREF(ret); - return ret; -} - -static PyObject * -tgl_Peer_get (tgl_Peer *self, void *closure) -{ - PyObject *ret; - - Py_XINCREF(ret); - return ret; -} - - +static PyGetSetDef tgl_Peer_getseters[] = { + {"name", (getter)tgl_Peer_getname, NULL, "", NULL}, + {"user_id", (getter)tgl_Peer_getuser_id, NULL, "", NULL}, + {"user_list", (getter)tgl_Peer_getuser_list, NULL, "", NULL}, + {"user_status", (getter)tgl_Peer_getuser_status, NULL, "", NULL}, + {"phone", (getter)tgl_Peer_getphone, NULL, "", NULL}, + {"username", (getter)tgl_Peer_getusername, NULL, "", NULL}, + {NULL} /* Sentinel */ +}; static PyMemberDef tgl_Peer_members[] = { {"type", T_INT, offsetof(tgl_Peer, peer.id.type), 0, "Peer Type"}, @@ -202,6 +255,7 @@ static PyObject * tgl_Peer_type_name(tgl_Peer* self) { PyObject *name; + switch(self->peer.id.type) { case TGL_PEER_USER: name = PyUnicode_FromString("user"); @@ -210,12 +264,11 @@ tgl_Peer_type_name(tgl_Peer* self) name = PyUnicode_FromString("chat"); break; case TGL_PEER_ENCR_CHAT: - name = PyUnicode_FromString("secret_chat"); + name = PyUnicode_FromString("encr_chat"); break; default: name = PyUnicode_FromString("unknown"); } - return name; } @@ -257,7 +310,7 @@ static PyTypeObject tgl_PeerType = { 0, /* tp_iternext */ tgl_Peer_methods, /* tp_methods */ tgl_Peer_members, /* tp_members */ - 0, /* tp_getset */ + tgl_Peer_getseters, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ @@ -268,4 +321,62 @@ static PyTypeObject tgl_PeerType = { tgl_Peer_new, /* tp_new */ }; + +static PyObject * +tgl_Peer_FromTglPeer(tgl_peer_t *peer) { + tgl_Peer *self = (tgl_Peer *) tgl_Peer_new((PyTypeObject *)&tgl_PeerType, Py_None, Py_None); + + memcpy(&self->peer, peer, sizeof(tgl_peer_t)); + + switch(self->peer.id.type) { + case TGL_PEER_USER: + // print_name + if(peer->user.print_name) { + self->peer.user.print_name = (char*)malloc(strlen(peer->user.print_name)); + memcpy(self->peer.user.print_name, peer->user.print_name, strlen(peer->user.print_name)); + } + // phone + if(peer->user.phone) { + self->peer.user.phone = (char*)malloc(strlen(peer->user.phone)); + memcpy(self->peer.user.phone, peer->user.phone, strlen(peer->user.phone)); + } + // username + if(peer->user.username) { + self->peer.user.username = (char*)malloc(strlen(peer->user.username)); + memcpy(self->peer.user.username, peer->user.username, strlen(peer->user.username)); + } + break; + case TGL_PEER_CHAT: + // print_title + if(peer->chat.print_title) { + self->peer.chat.print_title = (char*)malloc(strlen(peer->chat.print_title)); + memcpy(self->peer.chat.print_title, peer->chat.print_title, strlen(peer->chat.print_title)); + } + // user_list + if(peer->chat.user_list_size > 0) { + self->peer.chat.user_list = (struct tgl_chat_user*)malloc(self->peer.chat.user_list_size * + sizeof(struct tgl_chat_user)); + memcpy(self->peer.chat.user_list, peer->chat.user_list, + peer->chat.user_list_size * sizeof(struct tgl_chat_user)); + } + break; + case TGL_PEER_ENCR_CHAT: + // print_name + if(peer->encr_chat.print_name) { + self->peer.encr_chat.print_name = (char*)malloc(strlen(peer->encr_chat.print_name)); + memcpy(self->peer.encr_chat.print_name, peer->encr_chat.print_name, strlen(peer->encr_chat.print_name)); + } + // g_key + if(peer->encr_chat.g_key) { + self->peer.encr_chat.g_key = (unsigned char*)malloc(256); + memcpy(self->peer.encr_chat.g_key, peer->encr_chat.g_key, 256); + } + break; + default: + assert(0); + } + + return (PyObject *) self; +} + #endif diff --git a/tg-test.py b/tg-test.py index d0620cc..3b495a1 100644 --- a/tg-test.py +++ b/tg-test.py @@ -31,6 +31,13 @@ def history_cb(msg_list, ptype, pid, success, msgs): if len(msgs) == HISTORY_QUERY_SIZE: tgl.get_history(ptype, pid, len(msg_list), HISTORY_QUERY_SIZE, partial(history_cb, msg_list, ptype, pid)); +def on_msg_receive(msg): + if msg["out"] and not binlog_done: + return; + + print(msg["to"].user_id) + +""" def on_msg_receive(msg): if msg["out"] and not binlog_done: return; @@ -53,7 +60,7 @@ def on_msg_receive(msg): if text.startswith("!loadhistory"): msg_list = [] tgl.get_history_ext(ptype, pid, 0, HISTORY_QUERY_SIZE, partial(history_cb, msg_list, ptype, pid)); - +""" def on_secret_chat_update(peer, types): return "on_secret_chat_update"