diff --git a/telegram-purple.c b/telegram-purple.c index 4c5870f..f60249b 100644 --- a/telegram-purple.c +++ b/telegram-purple.c @@ -116,7 +116,7 @@ static void update_user_handler (struct tgl_state *TLS, struct tgl_user *user, u // own user object, do not add that user to the buddy list but make the ID known to the name lookup and // set the print name as the name to be displayed in IM chats instead of the login name (the phone number) purple_connection_set_display_name (tg_get_conn (TLS), user->print_name); - tgp_blist_peer_add_name (TLS, user->id, user->print_name); + tgp_blist_peer_add_purple_name (TLS, user->id, user->print_name); return; } @@ -143,13 +143,13 @@ static void update_user_handler (struct tgl_state *TLS, struct tgl_user *user, u // changing the username would mean dropping the history. The first print name that is known to the blist // will remain the permanent name for this user, all future name changes will just change the user alias. if (buddy) { - tgp_blist_peer_add_name (TLS, user->id, purple_buddy_get_name (buddy)); + tgp_blist_peer_add_purple_name (TLS, user->id, purple_buddy_get_name (buddy)); if (strcmp (user->print_name, purple_buddy_get_name (buddy))) { purple_blist_alias_buddy (buddy, user->print_name); } p2tgl_prpl_got_user_status (TLS, user->id, &user->status); } else { - tgp_blist_peer_add_name (TLS, user->id, user->print_name); + tgp_blist_peer_add_purple_name (TLS, user->id, user->print_name); } } else { // peer was altered in some way @@ -172,7 +172,7 @@ static void update_secret_chat_handler (struct tgl_state *TLS, struct tgl_secret debug ("update_secret_chat_handler: state=%d", U->state); if (flags & TGL_UPDATE_CREATED) { - tgp_blist_peer_add_name (TLS, U->id, U->print_name); + tgp_blist_peer_add_purple_name (TLS, U->id, U->print_name); } if (!(flags & TGL_UPDATE_DELETED)) { @@ -181,7 +181,7 @@ static void update_secret_chat_handler (struct tgl_state *TLS, struct tgl_secret purple_blist_add_buddy (buddy, NULL, tgp_blist_group_init ("Telegram"), NULL); purple_blist_alias_buddy (buddy, U->print_name); } - purple_prpl_got_user_status (tg_get_acc (TLS), tgp_blist_peer_get_name (TLS, U->id), "mobile", NULL); + purple_prpl_got_user_status (tg_get_acc (TLS), tgp_blist_peer_get_purple_name (TLS, U->id), "mobile", NULL); } if (flags & TGL_UPDATE_WORKING || flags & TGL_UPDATE_DELETED) { @@ -200,7 +200,7 @@ static void update_secret_chat_handler (struct tgl_state *TLS, struct tgl_secret if (!(flags & TGL_UPDATE_CREATED) && buddy) { if (flags & TGL_UPDATE_DELETED) { tgp_msg_sys_out (TLS, _("Secret chat terminated."), U->id, FALSE); - purple_prpl_got_user_status (tg_get_acc (TLS), tgp_blist_peer_get_name (TLS, U->id), "offline", NULL); + purple_prpl_got_user_status (tg_get_acc (TLS), tgp_blist_peer_get_purple_name (TLS, U->id), "offline", NULL); } else { _update_buddy (TLS, (tgl_peer_t *)U, flags); } @@ -209,7 +209,7 @@ static void update_secret_chat_handler (struct tgl_state *TLS, struct tgl_secret static void update_chat_handler (struct tgl_state *TLS, struct tgl_chat *chat, unsigned flags) { if (flags & TGL_UPDATE_CREATED) { - tgp_blist_peer_add_name (TLS, chat->id, chat->print_title); + tgp_blist_peer_add_purple_name (TLS, chat->id, chat->print_title); } if (! (flags & TGL_UPDATE_CREATED)) { @@ -226,7 +226,7 @@ static void update_chat_handler (struct tgl_state *TLS, struct tgl_chat *chat, u static void update_user_typing (struct tgl_state *TLS, struct tgl_user *U, enum tgl_typing_status status) { if (status == tgl_typing_typing) { - serv_got_typing (tg_get_conn(TLS), tgp_blist_peer_get_name (TLS, U->id), 2, PURPLE_TYPING); + serv_got_typing (tg_get_conn(TLS), tgp_blist_peer_get_purple_name (TLS, U->id), 2, PURPLE_TYPING); } } @@ -332,7 +332,7 @@ static void on_userpic_loaded (struct tgl_state *TLS, void *extra, int success, p2tgl_buddy_icons_set_for_user (conn->pa, P->id, filename); if (dld->get_user_info_data->show_info == 1) { - purple_notify_userinfo (tg_get_conn (TLS), tgp_blist_peer_get_name (TLS, P->id), + purple_notify_userinfo (tg_get_conn (TLS), tgp_blist_peer_get_purple_name (TLS, P->id), p2tgl_notify_peer_info_new (TLS, P), NULL, NULL); } } @@ -389,7 +389,7 @@ void on_user_get_info (struct tgl_state *TLS, void *info_data, int success, stru if (!U->photo || U->photo->sizes_num == 0) { // No profile pic to load, display it right away if (user_info_data->show_info) { - purple_notify_userinfo (tg_get_conn (TLS), tgp_blist_peer_get_name (TLS, P->id), p2tgl_notify_peer_info_new (TLS, P), + purple_notify_userinfo (tg_get_conn (TLS), tgp_blist_peer_get_purple_name (TLS, P->id), p2tgl_notify_peer_info_new (TLS, P), NULL, NULL); } g_free (user_info_data); @@ -655,8 +655,9 @@ static int tgprpl_send_im (PurpleConnection *gc, const char *who, const char *me static unsigned int tgprpl_send_typing (PurpleConnection *gc, const char *who, PurpleTypingState typing) { debug ("tgprpl_send_typing()"); - tgl_do_send_typing (gc_get_conn (gc)->TLS, tgp_blist_peer_find_id (gc_get_conn (gc)->TLS, who), - typing == PURPLE_TYPING ? tgl_typing_typing : tgl_typing_cancel, 0, 0); + tgl_peer_t *peer = tgp_blist_peer_find (gc_get_conn (gc)->TLS, who); + tgl_do_send_typing (gc_get_conn (gc)->TLS, peer->id, + typing == PURPLE_TYPING ? tgl_typing_typing : tgl_typing_cancel, 0, 0); return 0; } @@ -707,12 +708,11 @@ static void tgprpl_remove_buddy (PurpleConnection *gc, PurpleBuddy *buddy, Purpl } tgl_peer_t *peer = tgp_blist_buddy_get_peer (buddy); - - if (tgl_get_peer_type (peer->id) == TGL_PEER_ENCR_CHAT) { - /* TODO: implement the api call cancel secret chats. Currently the chat will only be marked as - deleted on our side so that it won't be added on startup - (when the secret chat file is loaded) */ - bl_do_peer_delete (gc_get_conn (gc)->TLS, peer->encr_chat.id); + if (tgl_get_peer_type (peer->id) == TGL_PEER_ENCR_CHAT) { + /* TODO: implement the api call cancel secret chats. Currently the chat will only be marked as + deleted on our side so that it won't be added on startup + (when the secret chat file is loaded) */ + bl_do_peer_delete (gc_get_conn (gc)->TLS, peer->encr_chat.id); } } diff --git a/tgp-2prpl.c b/tgp-2prpl.c index 27b8697..1906a88 100644 --- a/tgp-2prpl.c +++ b/tgp-2prpl.c @@ -85,7 +85,7 @@ void p2tgl_got_chat_left (struct tgl_state *TLS, tgl_peer_id_t chat) { void p2tgl_got_chat_in (struct tgl_state *TLS, tgl_peer_id_t chat, tgl_peer_id_t who, const char *message, int flags, time_t when) { - serv_got_chat_in (tg_get_conn(TLS), tgl_get_peer_id (chat), tgp_blist_peer_get_name (TLS, who), flags, message, when); + serv_got_chat_in (tg_get_conn(TLS), tgl_get_peer_id (chat), tgp_blist_peer_get_purple_name (TLS, who), flags, message, when); } void p2tgl_got_im_combo (struct tgl_state *TLS, tgl_peer_id_t who, const char *msg, int flags, time_t when) { @@ -109,14 +109,14 @@ void p2tgl_got_im_combo (struct tgl_state *TLS, tgl_peer_id_t who, const char *m PurpleConversation *conv = p2tgl_find_conversation_with_account (TLS, who); if (!conv) { conv = purple_conversation_new (PURPLE_CONV_TYPE_IM, tg_get_acc (TLS), - tgp_blist_peer_get_name (TLS, who)); + tgp_blist_peer_get_purple_name (TLS, who)); } - purple_conv_im_write (purple_conversation_get_im_data (conv), tgp_blist_peer_get_name (TLS, who), + purple_conv_im_write (purple_conversation_get_im_data (conv), tgp_blist_peer_get_purple_name (TLS, who), msg, PURPLE_MESSAGE_SEND, when); return; } #endif - serv_got_im (conn->gc, tgp_blist_peer_get_name (TLS, who), msg, flags, when); + serv_got_im (conn->gc, tgp_blist_peer_get_purple_name (TLS, who), msg, flags, when); } PurpleConversation *p2tgl_find_conversation_with_account (struct tgl_state *TLS, tgl_peer_id_t peer) { @@ -125,7 +125,7 @@ PurpleConversation *p2tgl_find_conversation_with_account (struct tgl_state *TLS, type = PURPLE_CONV_TYPE_CHAT; } PurpleConversation *conv = purple_find_conversation_with_account (type, - tgp_blist_peer_get_name (TLS, peer), tg_get_acc (TLS)); + tgp_blist_peer_get_purple_name (TLS, peer), tg_get_acc (TLS)); return conv; } @@ -133,15 +133,15 @@ void p2tgl_prpl_got_user_status (struct tgl_state *TLS, tgl_peer_id_t user, stru connection_data *data = TLS->ev_base; if (status->online == 1) { - purple_prpl_got_user_status (tg_get_acc (TLS), tgp_blist_peer_get_name (TLS, user), "available", NULL); + purple_prpl_got_user_status (tg_get_acc (TLS), tgp_blist_peer_get_purple_name (TLS, user), "available", NULL); } else { debug ("%d: when=%d", tgl_get_peer_id (user), status->when); if (tgp_time_n_days_ago (purple_account_get_int (data->pa, "inactive-days-offline", TGP_DEFAULT_INACTIVE_DAYS_OFFLINE)) > status->when && status->when) { debug ("offline"); - purple_prpl_got_user_status (tg_get_acc (TLS), tgp_blist_peer_get_name (TLS, user), "offline", NULL); + purple_prpl_got_user_status (tg_get_acc (TLS), tgp_blist_peer_get_purple_name (TLS, user), "offline", NULL); } else { debug ("mobile"); - purple_prpl_got_user_status (tg_get_acc (TLS), tgp_blist_peer_get_name (TLS, user), "mobile", NULL); + purple_prpl_got_user_status (tg_get_acc (TLS), tgp_blist_peer_get_purple_name (TLS, user), "mobile", NULL); } } } @@ -157,7 +157,7 @@ tgl_chat_id_t p2tgl_chat_get_id (PurpleChat *PC) { void p2tgl_conv_add_user (struct tgl_state *TLS, PurpleConversation *conv, int user, char *message, int flags, int new_arrival) { - purple_conv_chat_add_user (purple_conversation_get_chat_data (conv), tgp_blist_peer_get_name (TLS, TGL_MK_USER (user)), message, flags, new_arrival); + purple_conv_chat_add_user (purple_conversation_get_chat_data (conv), tgp_blist_peer_get_purple_name (TLS, TGL_MK_USER (user)), message, flags, new_arrival); } PurpleNotifyUserInfo *p2tgl_notify_user_info_new (struct tgl_user *U) { @@ -308,6 +308,6 @@ void p2tgl_buddy_icons_set_for_user (PurpleAccount *pa, tgl_peer_id_t id, const size_t len; GError *err = NULL; g_file_get_contents (filename, &data, &len, &err); - purple_buddy_icons_set_for_user (conn->pa, tgp_blist_peer_get_name (conn->TLS, id), data, len, NULL); + purple_buddy_icons_set_for_user (conn->pa, tgp_blist_peer_get_purple_name (conn->TLS, id), data, len, NULL); } diff --git a/tgp-blist.c b/tgp-blist.c index 162246c..6f559e8 100644 --- a/tgp-blist.c +++ b/tgp-blist.c @@ -24,17 +24,7 @@ #include #include -/* - Functions for handling telegram users in the buddy list - - Purple prefers human-readable names for buddy usernames, while Telegram uses numerical user ids. - In older versions of this plugin, the user id was used as username and the print name as the users - alias. This means that getting a useful username in the interface relied on the alias resolution, - which unfortunately doesn't work when a user isn't in the buddy list, or in Adium group chats. - Because of that, this plugin now uses the unique print names provided by libtgl as username instead. -*/ - -const char *tgp_blist_peer_get_name (struct tgl_state *TLS, tgl_peer_id_t id) { +const char *tgp_blist_peer_get_purple_name (struct tgl_state *TLS, tgl_peer_id_t id) { const char *name = g_hash_table_lookup (tg_get_data (TLS)->id_to_tgl_peer, GINT_TO_POINTER(tgl_get_peer_id (id))); if (! name) { assert (0); @@ -43,30 +33,22 @@ const char *tgp_blist_peer_get_name (struct tgl_state *TLS, tgl_peer_id_t id) { return name; } -void tgp_blist_peer_add_name (struct tgl_state *TLS, tgl_peer_id_t id, const char *name) { +void tgp_blist_peer_add_purple_name (struct tgl_state *TLS, tgl_peer_id_t id, const char *purple_name) { assert (g_hash_table_lookup (tg_get_data (TLS)->id_to_tgl_peer, GINT_TO_POINTER(tgl_get_peer_id (id))) == NULL); - g_hash_table_insert (tg_get_data (TLS)->id_to_tgl_peer, GINT_TO_POINTER(tgl_get_peer_id (id)), g_strdup (name)); + g_hash_table_insert (tg_get_data (TLS)->id_to_tgl_peer, GINT_TO_POINTER(tgl_get_peer_id (id)), + g_strdup (purple_name)); } -tgl_peer_id_t tgp_blist_peer_find_id (struct tgl_state *TLS, const char *who) { - PurpleBuddy *buddy = purple_find_buddy (tg_get_acc (TLS), who); - if (! buddy) { - assert (0); +tgl_peer_t *tgp_blist_peer_find (struct tgl_state *TLS, const char *purple_name) { + PurpleBuddy *buddy = purple_find_buddy (tg_get_acc (TLS), purple_name); + if (! buddy || ! tgp_blist_buddy_has_id (buddy)) { + return NULL; } - return tgp_blist_buddy_get_id (buddy); + return tgl_peer_get (TLS, tgp_blist_buddy_get_id (buddy)); } -tgl_peer_t *tgp_blist_peer_find (struct tgl_state *TLS, const char *who) { - return tgl_peer_get (TLS, tgp_blist_peer_find_id (TLS, who)); -} - -/* - To make this new approach robust to names changes, it is necessarry to store the user ID in each - blist node to allow reliable buddy list lookups by user ids. -*/ - PurpleBuddy *tgp_blist_buddy_new (struct tgl_state *TLS, tgl_peer_t *user) { - PurpleBuddy *buddy = purple_buddy_new (tg_get_acc (TLS), tgp_blist_peer_get_name (TLS, user->id), NULL); + PurpleBuddy *buddy = purple_buddy_new (tg_get_acc (TLS), tgp_blist_peer_get_purple_name (TLS, user->id), NULL); tgp_blist_buddy_set_id (buddy, user->id); return buddy; } @@ -88,6 +70,10 @@ void tgp_blist_buddy_set_id (PurpleBuddy *buddy, tgl_peer_id_t id) { purple_blist_node_set_int (&buddy->node, TGP_BUDDY_KEY_PEER_TYPE, type); } +int tgp_blist_buddy_has_id (PurpleBuddy *buddy) { + return purple_blist_node_get_int (&buddy->node, TGP_BUDDY_KEY_PEER_ID) != 0; +} + tgl_peer_id_t tgp_blist_buddy_get_id (PurpleBuddy *buddy) { int id = purple_blist_node_get_int (&buddy->node, TGP_BUDDY_KEY_PEER_ID), type = purple_blist_node_get_int (&buddy->node, TGP_BUDDY_KEY_PEER_TYPE); @@ -102,6 +88,9 @@ tgl_peer_id_t tgp_blist_buddy_get_id (PurpleBuddy *buddy) { } tgl_peer_t *tgp_blist_buddy_get_peer (PurpleBuddy *buddy) { + if (! tgp_blist_buddy_has_id (buddy)) { + return NULL; + } return tgl_peer_get (pbn_get_conn (&buddy->node)->TLS, tgp_blist_buddy_get_id (buddy)); } diff --git a/tgp-blist.h b/tgp-blist.h index a0b8bd9..3c0db26 100644 --- a/tgp-blist.h +++ b/tgp-blist.h @@ -27,12 +27,28 @@ #define TGP_BUDDY_KEY_PEER_ID "user_id" #define TGP_BUDDY_KEY_PEER_TYPE "peer_type" -const char *tgp_blist_peer_get_name (struct tgl_state *TLS, tgl_peer_id_t id); -void tgp_blist_peer_add_name (struct tgl_state *TLS, tgl_peer_id_t id, const char *name); -void tgp_blist_buddy_set_id (PurpleBuddy *buddy, tgl_peer_id_t id); -tgl_peer_id_t tgp_blist_peer_find_id (struct tgl_state *TLS, const char *who); -tgl_peer_t *tgp_blist_peer_find (struct tgl_state *TLS, const char *who); +/* + Functions for managing telegram contacts in the buddy list and performing id to purple-username and + purple-username to id lookups. + + Purple prefers human-readable names for buddy usernames, while Telegram uses numerical user ids. + In older versions of this plugin, the user id was used as username and the print name as the users + alias. This means that getting a useful username in the interface relied on the alias resolution, + which unfortunately doesn't work when a user isn't in the buddy list, or in Adium group chats. + Because of that, this plugin now uses the unique print names provided by libtgl as username instead. + */ +const char *tgp_blist_peer_get_purple_name (struct tgl_state *TLS, tgl_peer_id_t id); +void tgp_blist_peer_add_purple_name (struct tgl_state *TLS, tgl_peer_id_t id, const char *purple_name); +tgl_peer_t *tgp_blist_peer_find (struct tgl_state *TLS, const char *purple_name); + +/* + To make this new approach robust to names changes, it is necessarry to store the user ID in each + blist node to allow reliable buddy list lookups by user ids. + */ + +void tgp_blist_buddy_set_id (PurpleBuddy *buddy, tgl_peer_id_t id); +int tgp_blist_buddy_has_id (PurpleBuddy *buddy); tgl_peer_id_t tgp_blist_buddy_get_id (PurpleBuddy *buddy); tgl_peer_t *tgp_blist_buddy_get_peer (PurpleBuddy *peer); PurpleBuddy *tgp_blist_buddy_new (struct tgl_state *TLS, tgl_peer_t *user); diff --git a/tgp-chat.c b/tgp-chat.c index c993e8b..5fe2fd5 100644 --- a/tgp-chat.c +++ b/tgp-chat.c @@ -88,7 +88,7 @@ static void tgp_chat_add_all_users (struct tgl_state *TLS, PurpleConversation *c int i = 0; for (; i < C->user_list_size; i++) { struct tgl_chat_user *uid = (C->user_list + i); - users = g_list_append (users, g_strdup (tgp_blist_peer_get_name (TLS, TGL_MK_USER(uid->user_id)))); + users = g_list_append (users, g_strdup (tgp_blist_peer_get_purple_name (TLS, TGL_MK_USER(uid->user_id)))); flags = g_list_append (flags, GINT_TO_POINTER(C->admin_id == uid->user_id ? PURPLE_CBFLAGS_FOUNDER : PURPLE_CBFLAGS_NONE)); } purple_conv_chat_add_users (PURPLE_CONV_CHAT(conv), users, NULL, flags, FALSE); diff --git a/tgp-msg.c b/tgp-msg.c index 0b8e87a..db960bb 100644 --- a/tgp-msg.c +++ b/tgp-msg.c @@ -102,7 +102,7 @@ static char *format_service_msg (struct tgl_state *TLS, struct tgl_message *M) { txt_action = g_strdup_printf (_("%s deleted user %s."), txt_user, peer->print_name); purple_conv_chat_remove_user (purple_conversation_get_chat_data (conv), - tgp_blist_peer_get_name (TLS, TGL_MK_USER (M->action.user)), txt_action); + tgp_blist_peer_get_purple_name (TLS, TGL_MK_USER (M->action.user)), txt_action); if (M->action.user == tgl_get_peer_id (TLS->our_id)) { purple_conv_chat_left (purple_conversation_get_chat_data (conv)); @@ -241,7 +241,7 @@ void tgp_msg_err_out (struct tgl_state *TLS, const char *error, tgl_peer_id_t to break; case TGL_PEER_USER: case TGL_PEER_ENCR_CHAT: - serv_got_im (tg_get_conn (TLS), tgp_blist_peer_get_name (TLS, to), error, flags, now); + serv_got_im (tg_get_conn (TLS), tgp_blist_peer_get_purple_name (TLS, to), error, flags, now); break; } } @@ -260,7 +260,7 @@ void tgp_msg_sys_out (struct tgl_state *TLS, const char *msg, tgl_peer_id_t to_i break; case TGL_PEER_USER: case TGL_PEER_ENCR_CHAT: { - const char *name = tgp_blist_peer_get_name (TLS, to_id); + const char *name = tgp_blist_peer_get_purple_name (TLS, to_id); PurpleConversation *conv = p2tgl_find_conversation_with_account (TLS, to_id); if (! conv) { conv = purple_conversation_new (PURPLE_CONV_TYPE_IM, tg_get_acc (TLS), name); @@ -374,7 +374,7 @@ static char *tgp_msg_sticker_display (struct tgl_state *TLS, tgl_peer_id_t from, text = tgp_format_img (img); *flags |= PURPLE_MESSAGE_IMAGES; #else - text = g_strdup_printf (_("%s sent a sticker"), tgp_blist_peer_get_name (TLS, from)); + text = g_strdup_printf (_("%s sent a sticker"), tgp_blist_peer_get_purple_name (TLS, from)); *flags |= PURPLE_MESSAGE_SYSTEM; #endif return text; @@ -439,7 +439,7 @@ static void tgp_msg_display (struct tgl_state *TLS, struct tgp_msg_loading *C) { text = tgp_msg_photo_display (TLS, C->data, &flags); } else { if (! tgp_our_msg(TLS, M)) { - tgprpl_recv_file (conn->gc, tgp_blist_peer_get_name (TLS, M->from_id), M); + tgprpl_recv_file (conn->gc, tgp_blist_peer_get_purple_name (TLS, M->from_id), M); } return; } @@ -448,7 +448,7 @@ static void tgp_msg_display (struct tgl_state *TLS, struct tgp_msg_loading *C) { case tgl_message_media_video: case tgl_message_media_audio: { if (! tgp_our_msg(TLS, M)) { - tgprpl_recv_file (conn->gc, tgp_blist_peer_get_name (TLS, M->from_id), M); + tgprpl_recv_file (conn->gc, tgp_blist_peer_get_purple_name (TLS, M->from_id), M); } } break; @@ -462,7 +462,7 @@ static void tgp_msg_display (struct tgl_state *TLS, struct tgp_msg_loading *C) { text = tgp_msg_photo_display (TLS, C->data, &flags); } else { if (! tgp_our_msg(TLS, M)) { - tgprpl_recv_file (conn->gc, tgp_blist_peer_get_name (TLS, M->to_id), M); + tgprpl_recv_file (conn->gc, tgp_blist_peer_get_purple_name (TLS, M->to_id), M); } return; }