Beispiel #1
0
void tgprpl_chat_join (PurpleConnection *gc, GHashTable *data) {
  debug ("tgprpl_chat_join()");
  g_return_if_fail(data);
  
  // auto joins will cause chat joins at a time when the dialogue list is not ready, remember
  // those chats and join them once the dialogue list is fetched
  if (! gc_get_data (gc)->dialogues_ready) {
    g_return_if_fail (data);
    const char *id = g_hash_table_lookup (data, "id");
    if (id) {
      debug ("attempting to join chat %s while not ready, queue up for later", id);
      gc_get_data (gc)->pending_joins = g_list_append (gc_get_data (gc)->pending_joins, g_strdup (id));
    }
    return;
  }

  // join existing chat by id when the user clicks on a chat in the buddy list
  void *value = g_hash_table_lookup (data, "id");
  if (value && atoi (value)) {
    tgl_peer_id_t cid = TGL_MK_CHAT(atoi (value));
    tgl_peer_t *P = tgl_peer_get (gc_get_tls (gc), cid);
    if (P) {
      debug ("joining chat by id %d ...", tgl_get_peer_id (cid));
      tgl_do_get_chat_info (gc_get_tls (gc), cid, FALSE, tgp_chat_on_loaded_chat_full_joining, NULL);
    } else {
      warning ("Cannot join chat %d, peer not found...", tgl_get_peer_id (cid));
      purple_serv_got_join_chat_failed (gc, data);
    }
    return;
  }
  
  // join chat by invite link provided in the chat join window
  const char *link = g_hash_table_lookup (data, "link");
  if (str_not_empty (link)) {
    tgl_do_import_chat_link (gc_get_tls (gc), link, (int)strlen (link), tgp_notify_on_error_gw, NULL);
    return;
  }
  
  // if a chat with this name doesn't exist yet, prompt to create one
  const char *subject = g_hash_table_lookup (data, "subject");
  if (str_not_empty (subject)) {
    tgl_peer_t *P = tgl_peer_get_by_name (gc_get_tls (gc), subject);
    
    // handle joining chats by print_names as used by the Adium plugin
    if (P && tgl_get_peer_type (P->id) == TGL_PEER_CHAT) {
      debug ("joining chat by subject %s ...", subject);
      
      tgl_do_get_chat_info (gc_get_tls (gc), P->id, FALSE, tgp_chat_on_loaded_chat_full_joining, NULL);
      return;
    }
    
    // user creates a new chat by providing its subject the chat join window
    request_create_chat (gc_get_tls (gc), subject);
  }
}
Beispiel #2
0
void
tw_do_get_chat_info (struct tgl_state* TLS, tgl_peer_id_t id, tw_callback_get_chat_info callback, void* callback_extra)
{
	callback_data* data = (callback_data*) malloc (sizeof (callback_data));
	assert (data);
	data->callback = callback;
	data->data = callback_extra;
	tgl_do_get_chat_info (TLS, id, 0, tw_get_chat_info_cb, data);
}
Beispiel #3
0
void tgprpl_chat_join (PurpleConnection * gc, GHashTable *data) {
  debug ("tgprpl_chat_join()");
  connection_data *conn = purple_connection_get_protocol_data (gc);
  
  // join existing chat by id when the user clicks on a chat in the buddy list
  void *value = g_hash_table_lookup (data, "id");
  if (value && atoi (value)) {
    tgl_peer_id_t cid = TGL_MK_CHAT(atoi (value));
    tgl_peer_t *P = tgl_peer_get (conn->TLS, cid);
    if (P) {
      debug ("joining chat by id %d ...", tgl_get_peer_id (cid));
      tgl_do_get_chat_info (conn->TLS, cid, FALSE, tgp_chat_on_loaded_chat_full_joining, NULL);
    } else {
      warning ("Cannot join chat %d, peer not found...", tgl_get_peer_id (cid));
      purple_serv_got_join_chat_failed (gc, data);
    }
    return;
  }
  
  // join chat by invite link provided in the chat join window
  const char *link = g_hash_table_lookup (data, "link");
  if (str_not_empty (link)) {
    tgl_do_import_chat_link (conn->TLS, link, (int)strlen (link), tgp_notify_on_error_gw, NULL);
    return;
  }
  
  // if a chat with this name doesn't exist yet, prompt to create one
  const char *subject = g_hash_table_lookup (data, "subject");
  if (str_not_empty (subject)) {
    tgl_peer_t *P = tgl_peer_get_by_name (conn->TLS, subject);
    
    // handle joining chats by print_names as used by the Adium plugin
    if (P && tgl_get_peer_type (P->id) == TGL_PEER_CHAT) {
      debug ("joining chat by subject %s ...", subject);
      
      tgl_do_get_chat_info (conn->TLS, P->id, FALSE, tgp_chat_on_loaded_chat_full_joining, NULL);
      return;
    }
    
    // user creates a new chat by providing its subject the chat join window
    request_create_chat (conn->TLS, subject);
  }
}
static void tgprpl_chat_join (PurpleConnection * gc, GHashTable * data) {
  debug ("tgprpl_chat_join()\n");
  
  telegram_conn *conn = purple_connection_get_protocol_data (gc);
  const char *groupname = g_hash_table_lookup (data, "subject");
  
  char *id = g_hash_table_lookup(data, "id");
  if (!id) {
    warning ("Got no chat id, aborting...\n");
    return;
  }
  if (!purple_find_chat(gc, atoi(id))) {
    tgl_do_get_chat_info (conn->TLS, TGL_MK_CHAT(atoi(id)), 0, on_chat_get_info, 0);
  } else {
    serv_got_joined_chat(conn->gc, atoi(id), groupname);
  }
}
Beispiel #5
0
void py_do_all (void) {
    int p = 0;
    while (p < pos) {
        assert (p + 2 <= pos);

        enum py_query_type f = (long)py_ptr[p ++];
        PyObject *args = (PyObject *)py_ptr[p ++];

        const char *str, *str1, *str2, *str3;

        Py_ssize_t i;
        tgl_user_id_t *ids;

        int len, len1, len2, len3;
        int limit, offset;
        long msg_id = 0;
        PyObject *pyObj1 = NULL;
        PyObject *pyObj2 = NULL;
        PyObject *cb_extra = NULL;

        PyObject *peer = NULL;
        PyObject *peer1 = NULL;

        switch (f) {
        case pq_contact_list:
            if(PyArg_ParseTuple(args, "|O", &cb_extra))
                tgl_do_update_contact_list (TLS, py_contact_list_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_dialog_list:
            if(PyArg_ParseTuple(args, "|O", &cb_extra))
                tgl_do_get_dialog_list (TLS, 100, 0, py_dialog_list_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_msg:
            if(PyArg_ParseTuple(args, "O!s#|O", &tgl_PeerType, &peer, &str, &len, &cb_extra))
                tgl_do_send_message (TLS, PY_PEER_ID(peer), str, len, 0, py_msg_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_send_typing:
            if(PyArg_ParseTuple(args, "O!|O", &tgl_PeerType, &peer, &cb_extra))
                tgl_do_send_typing (TLS, PY_PEER_ID(peer), tgl_typing_typing, py_empty_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_send_typing_abort:
            if(PyArg_ParseTuple(args, "O!|O", &tgl_PeerType, &peer, &cb_extra))
                tgl_do_send_typing (TLS, PY_PEER_ID(peer), tgl_typing_cancel, py_empty_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_rename_chat:
            if(PyArg_ParseTuple(args, "O!s#|O", &tgl_PeerType, &peer, &str, &len, &cb_extra))
                tgl_do_rename_chat (TLS, PY_PEER_ID(peer), str, len, py_empty_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_send_photo:
            if(PyArg_ParseTuple(args, "O!s|O", &tgl_PeerType, &peer, &str, &cb_extra))
                tgl_do_send_document (TLS, PY_PEER_ID(peer), str, NULL, 0, TGL_SEND_MSG_FLAG_DOCUMENT_PHOTO, py_msg_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_send_video:
            if(PyArg_ParseTuple(args, "O!s|O", &tgl_PeerType, &peer, &str, &cb_extra))
                tgl_do_send_document (TLS, PY_PEER_ID(peer), str, NULL, 0, TGL_SEND_MSG_FLAG_DOCUMENT_VIDEO, py_msg_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_send_audio:
            if(PyArg_ParseTuple(args, "O!s|O", &tgl_PeerType, &peer, &str, &cb_extra))
                tgl_do_send_document (TLS, PY_PEER_ID(peer), str, NULL, 0, TGL_SEND_MSG_FLAG_DOCUMENT_AUDIO, py_msg_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_send_document:
            if(PyArg_ParseTuple(args, "O!s|O", &tgl_PeerType, &peer, &str, &cb_extra))
                tgl_do_send_document (TLS, PY_PEER_ID(peer), str, NULL, 0, 0, py_msg_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_send_file:
            if(PyArg_ParseTuple(args, "O!s|O", &tgl_PeerType, &peer, &str, &cb_extra))
                tgl_do_send_document (TLS, PY_PEER_ID(peer), str, NULL, 0, TGL_SEND_MSG_FLAG_DOCUMENT_AUTO, py_msg_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_send_text:
            if(PyArg_ParseTuple(args, "O!s|O", &tgl_PeerType, &peer, &str, &cb_extra))
                tgl_do_send_text (TLS, PY_PEER_ID(peer), str, 0, py_msg_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_chat_set_photo:
            if(PyArg_ParseTuple(args, "O!s|O", &tgl_PeerType, &peer, &str, &cb_extra))
                tgl_do_set_chat_photo (TLS, PY_PEER_ID(peer), str, py_empty_cb, cb_extra);
            else
                PyErr_Print();
            break;
        /*  case pq_load_photo:
            case pq_load_video:
            case pq_load_audio:
            case pq_load_document:
              M = py_ptr[p + 1];
              if (!M || (M->media.type != tgl_message_media_photo && M->media.type != tgl_message_media_photo_encr && M->media.type != tgl_message_media_document && M->media.type != tgl_message_media_document_encr)) {
                py_file_cb (TLS, py_ptr[p], 0, 0);
              } else {
                , limit, offse, limit, offsettif (M->media.type == tgl_message_media_photo) {
                  tgl_do_load_photo (TLS, &M->media.photo, py_file_cb, py_ptr[p]);
                } else if (M->media.type == tgl_message_media_document) {
                  tgl_do_load_document (TLS, &M->media.document, py_file_cb, py_ptr[p]);
                } else {
                  tgl_do_load_encr_document (TLS, &M->media.encr_document, py_file_cb, py_ptr[p]);
                }
              }
              break;
            case pq_load_video_thumb:
            case pq_load_document_thumb:
              M = py_ptr[p + 1];
              if (!M || (M->media.type != tgl_message_media_document)) {
                py_file_cb (TLS, py_ptr[p], 0, 0);
              } else {
                tgl_do_load_document_thumb (TLS, &M->media.document, py_file_cb, py_ptr[p]);
              }
              break;
        */
        case pq_fwd:
            if(PyArg_ParseTuple(args, "O!l|O", &tgl_PeerType, &peer, &msg_id, &cb_extra))
                tgl_do_forward_message (TLS, PY_PEER_ID(peer), msg_id, 0, py_msg_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_fwd_media:
            if(PyArg_ParseTuple(args, "O!l|O", &tgl_PeerType, &peer, &msg_id, &cb_extra))
                tgl_do_forward_media (TLS, PY_PEER_ID(peer), msg_id, 0, py_msg_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_chat_info:
            if(PyArg_ParseTuple(args, "O!|O", &tgl_PeerType, &peer, &cb_extra))
                tgl_do_get_chat_info (TLS, PY_PEER_ID(peer), 0, py_chat_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_user_info:
            if(PyArg_ParseTuple(args, "O!|O", &tgl_PeerType, &peer, &cb_extra))
                tgl_do_get_user_info (TLS, PY_PEER_ID(peer), 0, py_user_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_history:
            if(PyArg_ParseTuple(args, "O!ii|O", &tgl_PeerType, &peer, &offset, &limit, &cb_extra))
                tgl_do_get_history (TLS, PY_PEER_ID(peer), offset, limit, 0, py_msg_list_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_chat_add_user:
            if(PyArg_ParseTuple(args, "O!O!|O", &tgl_PeerType, &peer, &tgl_PeerType, &peer1, &cb_extra))
                tgl_do_add_user_to_chat (TLS, PY_PEER_ID(peer), PY_PEER_ID(peer1), 100, py_empty_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_chat_del_user:
            if(PyArg_ParseTuple(args, "O!O!|O", &tgl_PeerType, &peer, &tgl_PeerType, &peer1, &cb_extra))
                tgl_do_del_user_from_chat (TLS, PY_PEER_ID(peer), PY_PEER_ID(peer1), py_empty_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_add_contact:
            if(PyArg_ParseTuple(args, "s#s#s#|O", &str1, &len1, &str2, &len2, &str3, &len3, &cb_extra))
                tgl_do_add_contact (TLS, str1, len1, str2, len2, str3, len3, 0, py_contact_list_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_del_contact:
            if(PyArg_ParseTuple(args, "O!|O", &tgl_PeerType, &peer, &cb_extra))
                tgl_do_del_contact (TLS, PY_PEER_ID(peer), py_empty_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_rename_contact:
            if(PyArg_ParseTuple(args, "s#s#s#|O", &str1, &len1, &str2, &len2, &str3, &len3, &cb_extra))
                tgl_do_add_contact (TLS, str1, len1, str2, len2, str3, len3, 1, py_contact_list_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_search:
            if(PyArg_ParseTuple(args, "O!s#|O", &tgl_PeerType, &peer, &str, &len, &cb_extra))
                tgl_do_msg_search (TLS, PY_PEER_ID(peer), 0, 0, 40, 0, str, len, py_msg_list_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_global_search:
            if(PyArg_ParseTuple(args, "s#|O", &str, &len, &cb_extra))
                tgl_do_msg_search (TLS, tgl_set_peer_id (TGL_PEER_UNKNOWN, 0), 0, 0, 40, 0, str, len, py_msg_list_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_mark_read:
            if(PyArg_ParseTuple(args, "O!|O", &tgl_PeerType, &peer, &cb_extra))
                tgl_do_mark_read (TLS, PY_PEER_ID(peer), py_empty_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_set_profile_photo:
            if(PyArg_ParseTuple(args, "s|O", &str, &cb_extra))
                tgl_do_set_profile_photo (TLS, str, py_empty_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_set_profile_name:
            if(PyArg_ParseTuple(args, "s#s#|O", &str1, &len1, &str2, &len2, &cb_extra))
                tgl_do_set_profile_name (TLS, str1, len1, str2, len2, py_user_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_create_secret_chat:
            if(PyArg_ParseTuple(args, "O!|O", &tgl_PeerType, &peer, &cb_extra))
                tgl_do_create_secret_chat (TLS, PY_PEER_ID(peer), py_secret_chat_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_create_group_chat:
            if(PyArg_ParseTuple(args, "O!s#|O", &PyList_Type, &pyObj1, &str, &len, &cb_extra)) {
                if(PyList_GET_SIZE(pyObj1) > 2) {
                    ids = (tgl_user_id_t *)malloc(PyList_GET_SIZE(pyObj1) * sizeof(tgl_user_id_t));
                    for(i = 0; i < PyList_GET_SIZE(pyObj1); i++) {
                        peer = PyList_GetItem(pyObj1, i);
                        *(ids+i) = PY_PEER_ID(peer);
                    }
                    tgl_do_create_group_chat (TLS, PyList_GET_SIZE(pyObj1), ids, str, len, py_empty_cb, cb_extra);

                    tfree(ids, PyList_GET_SIZE(pyObj1) * sizeof(tgl_user_id_t));
                } else {
                    logprintf("create_group_chat: Argument 1 must be a list of at least 3 peers");
                }
            }
            Py_XDECREF(pyObj1);
            break;
        case pq_delete_msg:
        case pq_restore_msg:
            if(PyArg_ParseTuple(args, "l|O", &msg_id, &cb_extra))
                tgl_do_delete_msg (TLS, msg_id, py_empty_cb, cb_extra);
            else
                PyErr_Print();
            break;
        /*
            case pq_accept_secret_chat:
              tgl_do_accept_encr_chat_request (TLS, py_ptr[p + 1], py_secret_chat_cb, py_ptr[p]);
              break;
        */
        case pq_send_contact:
            if(PyArg_ParseTuple(args, "O!s#s#s#|O",  &tgl_PeerType, &peer, &str1, &len1, &str2, &len2,
                                &str3, &len3, &cb_extra))
                tgl_do_send_contact (TLS, PY_PEER_ID(peer), str1, len1, str2, len2, str3, len3, 0, py_msg_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_status_online:
            if(PyArg_ParseTuple(args, "|O", &cb_extra))
                tgl_do_update_status (TLS, 1, py_empty_cb, cb_extra);
            else
                PyErr_Print();
            break;
        case pq_status_offline:
            if(PyArg_ParseTuple(args, "|O", &cb_extra))
                tgl_do_update_status (TLS, 0, py_empty_cb, cb_extra);
            else
                PyErr_Print();
            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);
            else
                PyErr_Print();
            break;
        case pq_send_location:
            if(PyArg_ParseTuple(args, "O!O!O!|O", &tgl_PeerType, &peer, &PyFloat_Type, &pyObj1, &PyFloat_Type, &pyObj2, &cb_extra)) {
                tgl_do_send_location (TLS, PY_PEER_ID(peer),
                                      PyFloat_AsDouble(pyObj1), PyFloat_AsDouble(pyObj2), 0, py_msg_cb, cb_extra);
                Py_XDECREF(pyObj1);
                Py_XDECREF(pyObj2);
            } else
                PyErr_Print();
            break;
        default:
            assert (0);
        }

        // Increment reference on cb_extra as it is passed on to the callback to use
        Py_XINCREF(cb_extra);

        // Clean up any arg variables we could have used.
        //Py_XDECREF(args); // TODO: this is going negative ref and causing segfaults
        Py_XDECREF(peer);
        Py_XDECREF(peer1);

    }
    pos = 0;
}
Beispiel #6
0
void tgp_msg_recv (struct tgl_state *TLS, struct tgl_message *M) {
  connection_data *conn = TLS->ev_base;
  if (M->flags & (TGLMF_EMPTY | TGLMF_DELETED)) {
    return;
  }
  if (!(M->flags & TGLMF_CREATED)) {
    return;
  }
  if (!(M->flags | TGLMF_UNREAD) && M->date != 0 && M->date < tgp_msg_oldest_relevant_ts (TLS)) {
    debug ("Message from %d on %d too old, ignored.", tgl_get_peer_id (M->from_id), M->date);
    return;
  }
  
  struct tgp_msg_loading *C = tgp_msg_loading_init (M);
  
  if (! (M->flags & TGLMF_SERVICE)) {
    
    // handle all messages that need to load content before they can be displayed
    if (M->media.type != tgl_message_media_none) {
      switch (M->media.type) {
        case tgl_message_media_photo: {
          
          // include the "bad photo" check from telegram-cli interface.c:3287 to avoid crashes when fetching history
          // TODO: find out the reason for this behavior
          if (M->media.photo) {
            ++ C->pending;
            tgl_do_load_photo (TLS, M->media.photo, tgp_msg_on_loaded_document, C);
          }
          break;
        }
          
        // documents that are stickers or images will be displayed just like regular photo messages
        // and need to be lodaed beforehand
        case tgl_message_media_document:
        case tgl_message_media_video:
        case tgl_message_media_audio:
          if (M->media.document->flags & TGLDF_STICKER || M->media.document->flags & TGLDF_IMAGE) {
            ++ C->pending;
            tgl_do_load_document (TLS, M->media.document, tgp_msg_on_loaded_document, C);
          }
          break;
        case tgl_message_media_document_encr:
          if (M->media.encr_document->flags & TGLDF_STICKER || M->media.encr_document->flags & TGLDF_IMAGE) {
            ++ C->pending;
            tgl_do_load_encr_document (TLS, M->media.encr_document, tgp_msg_on_loaded_document, C);
          }
          break;
          
        case tgl_message_media_geo:
          // TODO: load geo thumbnail
          break;
          
        default: // prevent Clang warnings ...
          break;
      }
    }
  }
  
  if (tgl_get_peer_type (M->to_id) == TGL_PEER_CHAT) {
    
    tgl_peer_t *P = tgl_peer_get (TLS, M->to_id);
    g_warn_if_fail(P);
    if (P && ! P->chat.user_list_size) {
      // To display a chat the full name of every single user is needed, but the updates received from the server only
      // contain the names of users mentioned in the events. In order to display a messages we always need to fetch the
      // full chat info first. If the user list is empty, this means that we still haven't fetched the full chat information.
      
      // assure that there is only one chat info request for every
      // chat to avoid causing FLOOD_WAIT_X errors that will lead to delays or dropped messages
      gpointer to_ptr = GINT_TO_POINTER(tgl_get_peer_id (M->to_id));
      
      if (! g_hash_table_lookup (conn->pending_chat_info, to_ptr)) {
        ++ C->pending;
        
        tgl_do_get_chat_info (TLS, M->to_id, FALSE, tgp_msg_on_loaded_chat_full, C);
        g_hash_table_replace (conn->pending_chat_info, to_ptr, to_ptr);
      }
    }
  }
  
  g_queue_push_tail (conn->new_messages, C);
  tgp_msg_process_in_ready (TLS);
}