Fetch chats and refactor libtelegram api

This commit is contained in:
mjentsch 2014-07-11 19:57:32 +02:00
parent f78adc8b96
commit 7fad1403ec
6 changed files with 136 additions and 83 deletions

19
loop.c
View file

@ -629,25 +629,6 @@ void network_export_registration()
fflush (stderr);
}
/**
* Fetch all unknown messages of the current session
*/
void session_get_difference()
{
do_get_difference();
net_loop (0, dgot);
}
extern int contacts_got;
int cupdate_got() {
return contacts_got;
}
void session_update_contact_list()
{
do_update_contact_list();
net_loop(0, cupdate_got);
}
int start_loop (char* code, char* auth_mode) {
logprintf("Calling start_loop()\n");
logprintf("auth_state %i\n", auth_state);

View file

@ -48,6 +48,7 @@
#include "msglog.h"
#include "mtproto-client.h"
#include "mtproto-common.h"
#include "structures.h"
// telegram-purple includes
#include "loop.h"
@ -77,8 +78,7 @@ void tg_cli_log_cb(const char* format, va_list ap)
}
void on_new_message(struct message *M);
void user_allocated_handler(peer_t *user);
void chat_allocated_handler(peer_t *chat);
void peer_allocated_handler(peer_t *user);
/**
* Returns the base icon name for the given buddy and account.
@ -227,22 +227,25 @@ static void tgprpl_login(PurpleAccount * acct)
purple_blist_add_group(tggroup, NULL);
}
purple_debug_info(PLUGIN_ID, "Fetching Network Info\n");
on_update_new_message(on_new_message);
on_user_allocated(user_allocated_handler);
on_chat_allocated(chat_allocated_handler);
on_peer_allocated(peer_allocated_handler);
// get all current contacts
purple_debug_info(PLUGIN_ID, "Fetching all current contacts...\n");
session_update_contact_list();
do_update_contact_list();
purple_debug_info(PLUGIN_ID, "Fetching all current chats...\n");
do_get_dialog_list();
// get new messages
session_get_difference();
purple_debug_info(PLUGIN_ID, "Fetching new messages...\n");
do_get_difference();
flush_queries();
// Our protocol data, that will be delivered to us
// through purple connection
telegram_conn *conn = g_new0(telegram_conn, 1);
conn->gc = gc;
conn->gc = gc;
conn->account = acct;
purple_connection_set_protocol_data(gc, conn);
@ -258,30 +261,113 @@ void on_new_message(struct message *M)
g_free(who);
}
void user_allocated_handler(peer_t *user)
{
gchar *name = g_strdup_printf("%d", get_peer_id(user->id));
// TODO: this should probably be freed again somwhere
char *alias = malloc(BUDDYNAME_MAX_LENGTH);
if (user_get_alias(user, alias, BUDDYNAME_MAX_LENGTH) < 0) {
purple_debug_info(PLUGIN_ID, "Buddyalias of (%d) too long, not adding to buddy list.\n",
get_peer_id(user->id));
return;
/*
* Search chats in hash table
*
* TODO: There has to be an easier way to do this
*/
static PurpleChat *blist_find_chat_by_hasht_cond(PurpleConnection *gc, int (*fn)(GHashTable *hasht, void *data), void *data)
{
PurpleAccount *account = purple_connection_get_account(gc);
PurpleBlistNode *node = purple_blist_get_root();
GHashTable *hasht;
while (node) {
if (PURPLE_BLIST_NODE_IS_CHAT(node)) {
PurpleChat *ch = PURPLE_CHAT(node);
if (purple_chat_get_account(ch) == account) {
hasht = purple_chat_get_components(ch);
if (fn(hasht, data))
return ch;
}
}
node = purple_blist_node_next(node, FALSE);
}
PurpleBuddy *buddy = purple_find_buddy(_pa, name);
if (!buddy) {
purple_debug_info(PLUGIN_ID, "Adding %s to buddy list ", name);
buddy = purple_buddy_new(_pa, name, alias);
purple_blist_add_buddy(buddy, NULL, tggroup, NULL);
}
purple_buddy_set_protocol_data(buddy, (gpointer)&user->id);
g_free(name);
return NULL;
}
static int hasht_cmp_id(GHashTable *hasht, void *data)
{
return !strcmp(g_hash_table_lookup(hasht, "id"), *((char **)data));
}
static PurpleChat *blist_find_chat_by_id(PurpleConnection *gc, const char *id)
{
return blist_find_chat_by_hasht_cond(gc, hasht_cmp_id, &id);
}
void chat_allocated_handler(peer_t *chat)
void peer_allocated_handler(peer_t *user)
{
purple_debug_info(PLUGIN_ID, "Chat Allocated: %s\n", chat->print_name);
gchar *name = g_strdup_printf("%d", get_peer_id(user->id));
logprintf("Allocated peer: %s\n", name);
switch (user->id.type) {
case PEER_USER: {
logprintf("Peer type: user.\n");
// TODO: this should probably be freed again somwhere
char *alias = malloc(BUDDYNAME_MAX_LENGTH);
if (user_get_alias(user, alias, BUDDYNAME_MAX_LENGTH) < 0) {
purple_debug_info(PLUGIN_ID, "Buddyalias of (%d) too long, not adding to buddy list.\n",
get_peer_id(user->id));
return;
}
PurpleBuddy *buddy = purple_find_buddy(_pa, name);
if (!buddy) {
purple_debug_info(PLUGIN_ID, "Adding %s to buddy list\n", name);
buddy = purple_buddy_new(_pa, name, alias);
purple_blist_add_buddy(buddy, NULL, tggroup, NULL);
}
purple_buddy_set_protocol_data(buddy, (gpointer)&user->id);
g_free(name);
}
break;
case PEER_CHAT: {
logprintf("Peer type: chat.\n");
PurpleChat *ch = blist_find_chat_by_id(_gc, name);
if (!ch) {
gchar *admin = g_strdup_printf("%d", user->chat.admin_id);
GHashTable *htable = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
g_hash_table_insert(htable, g_strdup("subject"), user->chat.title);
g_hash_table_insert(htable, g_strdup("id"), name);
g_hash_table_insert(htable, g_strdup("owner"), admin);
logprintf("Adding chat to blist: %s (%s, %s)\n", user->chat.title, name, admin);
ch = purple_chat_new(_pa, user->chat.title, htable);
purple_blist_add_chat(ch, NULL, NULL);
}
GHashTable *gh = purple_chat_get_components(ch);
//char const *id = g_hash_table_lookup(gh, "id");
char const *owner = g_hash_table_lookup(gh, "owner");
PurpleConversation *conv = purple_find_chat(_gc, atoi(name));
purple_conv_chat_clear_users(purple_conversation_get_chat_data(conv));
if (conv) {
struct chat_user *usr = user->chat.user_list;
int size = user->chat.user_list_size;
int i;
for (i = 0; i < size; i++) {
struct chat_user *cu = (usr + i);
// TODO: Inviter ID
// peer_id_t u = MK_USER (cu->user_id);
// peer_t *uchat = user_chat_get(u);
const char *cuname = g_strdup_printf("%d", cu->user_id);
logprintf("Adding user %s to chat %s\n", cuname, name);
purple_conv_chat_add_user(purple_conversation_get_chat_data(conv), cuname, "",
PURPLE_CBFLAGS_NONE | (!strcmp(owner, cuname) ? PURPLE_CBFLAGS_FOUNDER : 0), FALSE);
}
}
}
break;
case PEER_GEO_CHAT:
logprintf("Peer type: geo-chat.\n");
break;
case PEER_ENCR_CHAT:
logprintf("Peer type: encrypted chat.\n");
break;
case PEER_UNKNOWN:
logprintf("Peer type: unknown.\n");
break;
}
}
/**

View file

@ -2639,11 +2639,13 @@ int get_difference_on_answer (struct query *q UU) {
}
assert (fetch_int () == CODE_vector);
n = fetch_int ();
logprintf("Found %d chats\n", n);
for (i = 0; i < n; i++) {
fetch_alloc_chat ();
}
assert (fetch_int () == CODE_vector);
n = fetch_int ();
logprintf("Found %d users\n", n);
for (i = 0; i < n; i++) {
fetch_alloc_user ();
}

View file

@ -1527,6 +1527,7 @@ static int id_cmp (struct message *M1, struct message *M2) {
}
struct user *fetch_alloc_user (void) {
logprintf("fetch_alloc_user()\n");
int send_event = 0;
int data[2];
prefetch_data (data, 8);
@ -1542,12 +1543,13 @@ struct user *fetch_alloc_user (void) {
}
fetch_user (&U->user);
if (send_event) {
event_user_allocated(U);
event_peer_allocated(U);
}
return &U->user;
}
struct secret_chat *fetch_alloc_encrypted_chat (void) {
logprintf("fetch_alloc_encrypted_chat()\n");
int data[2];
prefetch_data (data, 8);
peer_t *U = user_chat_get (MK_ENCR_CHAT (data[1]));
@ -1560,6 +1562,7 @@ struct secret_chat *fetch_alloc_encrypted_chat (void) {
Peers[peer_num ++] = U;
}
fetch_encrypted_chat (&U->encr_chat);
event_peer_allocated(U);
return &U->encr_chat;
}
@ -1806,6 +1809,7 @@ void message_del_peer (struct message *M) {
}
struct message *fetch_alloc_message (void) {
logprintf("fetch_alloc_message()\n");
int data[2];
prefetch_data (data, 8);
struct message *M = message_get (data[1]);
@ -1821,6 +1825,7 @@ struct message *fetch_alloc_message (void) {
}
struct message *fetch_alloc_geo_message (void) {
logprintf("fetch_alloc_geo_message()\n");
struct message *M = talloc (sizeof (*M));
fetch_geo_message (M);
struct message *M1 = tree_lookup_message (message_tree, M);
@ -1844,6 +1849,7 @@ struct message *fetch_alloc_geo_message (void) {
}
struct message *fetch_alloc_encrypted_message (void) {
logprintf("fetch_alloc_encrypted_message()\n");
int data[3];
prefetch_data (data, 12);
struct message *M = message_get (*(long long *)(data + 1));
@ -1891,12 +1897,13 @@ struct message *fetch_alloc_message_short_chat (void) {
}
struct chat *fetch_alloc_chat (void) {
int send_event = 0;
logprintf("fetch_alloc_chat()\n");
int data[2];
prefetch_data (data, 8);
peer_t *U = user_chat_get (MK_CHAT (data[1]));
logprintf("id %d\n", U->id.id);
logprintf("type %d\n", U->id.type);
if (!U) {
send_event = 1;
chats_allocated ++;
U = talloc0 (sizeof (*U));
U->id = MK_CHAT (data[1]);
@ -1905,9 +1912,7 @@ struct chat *fetch_alloc_chat (void) {
Peers[peer_num ++] = U;
}
fetch_chat (&U->chat);
if (send_event) {
event_chat_allocated(U);
}
event_peer_allocated(U);
return &U->chat;
}

View file

@ -21,30 +21,15 @@ void event_update_new_message(struct message *M) {
}
/*
* User allocated
* Peer allocated
*/
void (*on_user_allocated_handler)(peer_t *user);
void on_user_allocated(void (*handler)(peer_t *user)) {
on_user_allocated_handler = handler;
void (*on_peer_allocated_handler)(peer_t *peer);
void on_peer_allocated(void (*handler)(peer_t *peer)) {
on_peer_allocated_handler = handler;
}
void event_user_allocated(peer_t *user) {
if (on_user_allocated_handler) {
on_user_allocated_handler(user);
}
}
/*
* Chat allocated
*/
void (*on_chat_allocated_handler)(peer_t *chat);
void on_chat_allocated(void (*handler)(peer_t *chat))
{
on_chat_allocated_handler = handler;
}
void event_chat_allocated(peer_t *chat)
{
if (on_chat_allocated_handler) {
on_chat_allocated_handler(chat);
void event_peer_allocated(peer_t *peer) {
if (on_peer_allocated_handler) {
on_peer_allocated_handler(peer);
}
}

View file

@ -2,7 +2,7 @@
* libtelegram
* ===========
*
* Telegram library based on the telegram cli application by vysheng (see https://github.com/vysheng/tg)
* Telegram library based on the telegram cli application, that was originally made by vysheng (see https://github.com/vysheng/tg)
*/
#define MAX_DC_NUM 9
@ -140,20 +140,14 @@ void on_update_chat_participants();
/*
* Load known users and chats on connect
*/
void on_user_allocated();
void on_user_allocated(void (*handler)(peer_t *user));
void event_user_allocated(peer_t *user);
void on_chat_allocated(void (*handler)(peer_t *chat));
void event_chat_allocated(peer_t *chat);
void on_peer_allocated(void (*handler)(peer_t *peer));
void event_peer_allocated(peer_t *peer);
// template
//void on_blarg(void (*on_msg)(struct message *M));
//void event_blarg(struct message *M);
void on_chat_allocated();
/**
* Set a function to use as a handle to read from a network resource
* instead of the regular socket read function