diff --git a/Makefile.in b/Makefile.in index 0ced8a4..a497257 100644 --- a/Makefile.in +++ b/Makefile.in @@ -36,7 +36,7 @@ EXE=bin OBJ=objs DIR_LIST=${DEP} ${EXE} ${OBJ} -PLUGIN_OBJECTS=${OBJ}/tgp-net.o ${OBJ}/tgp-timers.o ${OBJ}/msglog.o ${OBJ}/telegram-base.o ${OBJ}/telegram-purple.o ${OBJ}/tgp-2prpl.o ${OBJ}/tgp-structs.o ${OBJ}/tgp-utils.o ${OBJ}/tgp-chat.o ${OBJ}/tgp-ft.o ${OBJ}/tgp-msg.o ${OBJ}/tgp-request.o ${OBJ}/tgp-blist.o +PLUGIN_OBJECTS=${OBJ}/tgp-net.o ${OBJ}/tgp-timers.o ${OBJ}/msglog.o ${OBJ}/telegram-base.o ${OBJ}/telegram-purple.o ${OBJ}/tgp-2prpl.o ${OBJ}/tgp-structs.o ${OBJ}/tgp-utils.o ${OBJ}/tgp-chat.o ${OBJ}/tgp-ft.o ${OBJ}/tgp-msg.o ${OBJ}/tgp-request.o ${OBJ}/tgp-blist.o ${OBJ}/tgp-info.o ALL_OBJS=${PLUGIN_OBJECTS} ifdef MSGFMT_PATH diff --git a/telegram-adium/telegram-adium.xcodeproj/project.pbxproj b/telegram-adium/telegram-adium.xcodeproj/project.pbxproj index dbde3e2..6719f1d 100644 --- a/telegram-adium/telegram-adium.xcodeproj/project.pbxproj +++ b/telegram-adium/telegram-adium.xcodeproj/project.pbxproj @@ -42,6 +42,7 @@ C4B4BE391AB613950064AC17 /* TelegramJoinChatView.xib in Resources */ = {isa = PBXBuildFile; fileRef = C4B4BE381AB613950064AC17 /* TelegramJoinChatView.xib */; }; C4B57BF01B1598D4006997F4 /* libtgl.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C4B57BEF1B1598D4006997F4 /* libtgl.a */; }; C4D12DF01BC534CF00C0F6E1 /* tgp-blist.c in Sources */ = {isa = PBXBuildFile; fileRef = C4D12DEF1BC534CF00C0F6E1 /* tgp-blist.c */; }; + C4D3EB5A1C3824C5003C895B /* tgp-info.c in Sources */ = {isa = PBXBuildFile; fileRef = C4D3EB581C3824C5003C895B /* tgp-info.c */; }; C4D432D81BC2783C00561667 /* tg-server.tglpub in Resources */ = {isa = PBXBuildFile; fileRef = C4D432D71BC2783C00561667 /* tg-server.tglpub */; }; C4D819061A5C862E0044CBA9 /* tgp-structs.c in Sources */ = {isa = PBXBuildFile; fileRef = C4D819041A5C862E0044CBA9 /* tgp-structs.c */; }; C4D9185B1C1C6B3900AECCA2 /* libgpg-error.0.dylib in Resources */ = {isa = PBXBuildFile; fileRef = C4D9185A1C1C6B3900AECCA2 /* libgpg-error.0.dylib */; }; @@ -116,6 +117,8 @@ C4B57BEF1B1598D4006997F4 /* libtgl.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libtgl.a; path = ../libs/libtgl.a; sourceTree = ""; }; C4D12DEE1BC534CF00C0F6E1 /* tgp-blist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "tgp-blist.h"; path = "../tgp-blist.h"; sourceTree = ""; }; C4D12DEF1BC534CF00C0F6E1 /* tgp-blist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "tgp-blist.c"; path = "../tgp-blist.c"; sourceTree = ""; }; + C4D3EB581C3824C5003C895B /* tgp-info.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "tgp-info.c"; path = "../tgp-info.c"; sourceTree = ""; }; + C4D3EB591C3824C5003C895B /* tgp-info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "tgp-info.h"; path = "../tgp-info.h"; sourceTree = ""; }; C4D432D71BC2783C00561667 /* tg-server.tglpub */ = {isa = PBXFileReference; lastKnownFileType = file; name = "tg-server.tglpub"; path = "../tg-server.tglpub"; sourceTree = ""; }; C4D819041A5C862E0044CBA9 /* tgp-structs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "tgp-structs.c"; path = "../tgp-structs.c"; sourceTree = ""; }; C4D819051A5C862E0044CBA9 /* tgp-structs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "tgp-structs.h"; path = "../tgp-structs.h"; sourceTree = ""; }; @@ -271,6 +274,8 @@ C479A8011BB69C2100C153DF /* tgp-request.h */, C4D12DEE1BC534CF00C0F6E1 /* tgp-blist.h */, C4D12DEF1BC534CF00C0F6E1 /* tgp-blist.c */, + C4D3EB591C3824C5003C895B /* tgp-info.h */, + C4D3EB581C3824C5003C895B /* tgp-info.c */, 330704C72BA03B848124B6F7 /* telegram-adium */, ); name = "telegram-purple"; @@ -368,6 +373,7 @@ C425F9181A7069C300361AFC /* tgp-utils.c in Sources */, C4D819061A5C862E0044CBA9 /* tgp-structs.c in Sources */, C431EB7D1A76C737006521CB /* tgp-chat.c in Sources */, + C4D3EB5A1C3824C5003C895B /* tgp-info.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/telegram-purple.c b/telegram-purple.c index dc41631..5118cc5 100644 --- a/telegram-purple.c +++ b/telegram-purple.c @@ -35,7 +35,6 @@ static void update_user_handler (struct tgl_state *TLS, struct tgl_user *U, unsi static void update_secret_chat_handler (struct tgl_state *TLS, struct tgl_secret_chat *C, unsigned flags); static void update_chat_handler (struct tgl_state *TLS, struct tgl_chat *C, unsigned flags); static void update_channel_handler (struct tgl_state *TLS, struct tgl_channel *C, unsigned flags); -static void on_user_get_info (struct tgl_state *TLS, void *info_data, int success, struct tgl_user *U); const char *config_dir = "telegram-purple"; const char *user_pk_filename = "server.tglpub"; @@ -73,8 +72,10 @@ static void _update_buddy (struct tgl_state *TLS, tgl_peer_t *user, unsigned fla if (flags & TGL_UPDATE_CONTACT) { purple_blist_alias_buddy (buddy, user->print_name); } + if (flags & TGL_UPDATE_PHOTO) { - tgl_do_get_user_info (TLS, user->id, 0, on_user_get_info, get_user_info_data_new (0, user->id)); + debug ("update photo"); + tgp_info_update_photo (buddy, user); } } } @@ -114,9 +115,6 @@ static void update_user_handler (struct tgl_state *TLS, struct tgl_user *user, u if (buddy) { info ("migrating buddy from old name %s to %s", purple_buddy_get_name (buddy), user->print_name); buddy = tgp_blist_buddy_migrate (TLS, buddy, user); - if (user->photo_id) { - tgl_do_get_user_info (TLS, user->id, 0, on_user_get_info, get_user_info_data_new (0, user->id)); - } } // the id isn't known to the lookup yet since the user is not in the buddy list. Add the id to the @@ -129,7 +127,14 @@ static void update_user_handler (struct tgl_state *TLS, struct tgl_user *user, u if (strcmp (purple_buddy_get_alias (buddy), user->print_name)) { serv_got_alias (tls_get_conn (TLS), purple_buddy_get_name (buddy), user->print_name); } + } + + if (buddy) { p2tgl_prpl_got_user_status (TLS, user->id, &user->status); + + if (flags & TGL_UPDATE_PHOTO) { + tgp_info_update_photo (buddy, tgl_peer_get (TLS, user->id)); + } } } } else { @@ -140,10 +145,10 @@ static void update_user_handler (struct tgl_state *TLS, struct tgl_user *user, u static void update_channel_handler (struct tgl_state *TLS, struct tgl_channel *C, unsigned flags) { debug ("update_channel_handler() (%s)", print_flags_update (flags)); - assert (TLS); + + PurpleBuddy *buddy = tgp_blist_buddy_find (TLS, C->id); if (flags & TGL_UPDATE_CREATED) { - PurpleBuddy *buddy = tgp_blist_buddy_find (TLS, C->id); debug ("channel allocated '%s' (%s)", C->title, print_flags_channel (C->flags)); if (buddy) { tgp_blist_lookup_add (TLS, C->id, purple_buddy_get_name (buddy)); @@ -155,17 +160,16 @@ static void update_channel_handler (struct tgl_state *TLS, struct tgl_channel *C tgp_blist_lookup_add (TLS, C->id, C->title); } } else { - if (flags & TGL_UPDATE_FLAGS) { - debug ("channel updated flags '%s' to (%s)", C->title, print_flags_channel (C->flags)); - if (C->flags & TGLCHF_LEFT) { - PurpleBuddy *buddy = tgp_blist_buddy_find (TLS, C->id); - if (buddy) { + if (buddy) { + if (flags & TGL_UPDATE_FLAGS) { + debug ("channel updated flags '%s' to (%s)", C->title, print_flags_channel (C->flags)); + if (C->flags & TGLCHF_LEFT) { purple_blist_remove_buddy (buddy); } } - } - if (flags & TGL_UPDATE_PHOTO) { - tgl_do_get_channel_info (TLS, C->id, FALSE, channel_load_photo, NULL); + if (flags & TGL_UPDATE_PHOTO) { + tgp_info_update_photo (buddy, tgl_peer_get (TLS, C->id)); + } } } } @@ -265,54 +269,6 @@ static void update_marked_read (struct tgl_state *TLS, int num, struct tgl_messa } } -static void on_userpic_loaded (struct tgl_state *TLS, void *extra, int success, const char *filename) { - struct download_desc *dld = extra; - struct tgl_user *U = dld->data; - tgl_peer_t *P = tgl_peer_get (TLS, dld->get_user_info_data->peer); - - if (!success || !P) { - warning ("Can not load userpic for user %s %s", U->first_name, U->last_name); - tgp_notify_on_error_gw (TLS, NULL, success); - free (dld->get_user_info_data); - free (dld); - return; - } - - int imgStoreId = p2tgl_imgstore_add_with_id (filename); - if (imgStoreId > 0) { - used_images_add (tls_get_data (TLS), imgStoreId); - - p2tgl_buddy_icons_set_for_user (tls_get_pa (TLS), P->id, filename); - if (dld->get_user_info_data->show_info == 1) { - purple_notify_userinfo (tls_get_conn (TLS), tgp_blist_lookup_purple_name (TLS, P->id), - p2tgl_notify_peer_info_new (TLS, P), NULL, NULL); - } - } - free (dld->get_user_info_data); - free (dld); -} - -static void on_channel_loaded_photo (struct tgl_state *TLS, void *extra, int success, const char *filename) { - g_return_if_fail (success); - struct tgl_channel *C = extra; - - int img = p2tgl_imgstore_add_with_id (filename); - g_return_if_fail (img > 0); - info ("succesfully loaded photo for channel %s into imgstore %d", filename, C->title, img); - - used_images_add (tls_get_data (TLS), img); - p2tgl_buddy_icons_set_for_user (tls_get_pa (TLS), C->id, filename); -} - -void channel_load_photo (struct tgl_state *TLS, void *extra, int success, struct tgl_channel *C) { - g_return_if_fail (success); - - info ("loading photo for channel %s (%s)", C->title, print_flags_channel (C->flags)); - if (C->photo && C->photo->sizes_num > 0) { - tgl_do_load_photo (TLS, C->photo, on_channel_loaded_photo, C); - } -} - static void on_get_dialog_list_done (struct tgl_state *TLS, void *extra, int success, int size, tgl_peer_id_t peers[], tgl_message_id_t *last_msg_id[], int unread_count[]) { info ("Fetched dialogue list of size: %d", size); @@ -364,7 +320,7 @@ static void on_get_dialog_list_done (struct tgl_state *TLS, void *extra, int suc info ("%s is in the dialogue list but not in the buddy list, add the channel", UC->print_name); buddy = tgp_blist_buddy_new (TLS, UC); purple_blist_add_buddy (buddy, NULL, tgp_blist_group_init (_("Telegram Channels")), NULL); - tgl_do_get_channel_info (TLS, UC->id, FALSE, channel_load_photo, NULL); + tgp_info_update_photo (buddy, UC); } purple_prpl_got_user_status (tls_get_pa (TLS), tgp_blist_lookup_purple_name (TLS, UC->id), "available", NULL); @@ -376,29 +332,6 @@ static void on_get_dialog_list_done (struct tgl_state *TLS, void *extra, int suc tgp_chat_join_all_pending (TLS); } -void on_user_get_info (struct tgl_state *TLS, void *info_data, int success, struct tgl_user *U) { - get_user_info_data *user_info_data = (get_user_info_data *)info_data; - tgl_peer_t *P = tgl_peer_get (TLS, user_info_data->peer); - g_return_if_fail (P); - if (! success) { - tgp_notify_on_error_gw (TLS, NULL, success); - return; - } - 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 (tls_get_conn (TLS), tgp_blist_lookup_purple_name (TLS, P->id), - p2tgl_notify_peer_info_new (TLS, P), NULL, NULL); - } - g_free (user_info_data); - } else { - struct download_desc *dld = malloc (sizeof (struct download_desc)); - dld->data = U; - dld->get_user_info_data = info_data; - tgl_do_load_photo (TLS, U->photo, on_userpic_loaded, dld); - } -} - static const char *tgprpl_list_icon (PurpleAccount *acct, PurpleBuddy *buddy) { return "telegram"; } @@ -741,36 +674,6 @@ static unsigned int tgprpl_send_typing (PurpleConnection *gc, const char *who, P return 0; } -static void channel_show_info (struct tgl_state *TLS, void *extra, int success, struct tgl_channel *C) { - if (! success) { - tgp_notify_on_error_gw (TLS, NULL, FALSE); - return; - } - tgl_peer_t *P = tgl_peer_get (TLS, C->id); - g_return_if_fail (P); - purple_notify_userinfo (tls_get_conn (TLS), tgp_blist_lookup_purple_name (TLS, P->id), - p2tgl_notify_peer_info_new (TLS, P), NULL, NULL); -} - -static void tgprpl_get_info (PurpleConnection *gc, const char *who) { - debug ("tgprpl_get_info()"); - - tgl_peer_t *peer = tgp_blist_lookup_peer_get (gc_get_data (gc)->TLS, who); - if (peer) { - if (tgl_get_peer_type (peer->id) == TGL_PEER_ENCR_CHAT) { - tgl_peer_t *parent_peer = tgp_encr_chat_get_partner (gc_get_tls (gc), &peer->encr_chat); - if (parent_peer) { - tgl_do_get_user_info (gc_get_tls (gc), parent_peer->id, 0, on_user_get_info, - get_user_info_data_new (TRUE, peer->id)); - } - } else if (tgl_get_peer_type (peer->id) == TGL_PEER_CHANNEL) { - tgl_do_get_channel_info (gc_get_tls (gc), peer->id, FALSE, channel_show_info, NULL); - } else { - tgl_do_get_user_info (gc_get_tls (gc), peer->id, 0, on_user_get_info, get_user_info_data_new (TRUE, peer->id)); - } - } -} - static void tgprpl_set_status (PurpleAccount *acct, PurpleStatus *status) { debug ("tgprpl_set_status(%s)", purple_status_get_name (status)); @@ -855,7 +758,7 @@ static PurplePluginProtocolInfo prpl_info = { tgprpl_send_im, NULL, // set_info tgprpl_send_typing, - tgprpl_get_info, + tgprpl_info_show, tgprpl_set_status, NULL, // set_idle NULL, // change_passwd diff --git a/telegram-purple.h b/telegram-purple.h index e12e4c7..e2a55db 100644 --- a/telegram-purple.h +++ b/telegram-purple.h @@ -55,6 +55,7 @@ #include "tgp-ft.h" #include "tgp-msg.h" #include "tgp-request.h" +#include "tgp-info.h" #include "msglog.h" #define PLUGIN_ID "prpl-telegram" diff --git a/tgp-2prpl.c b/tgp-2prpl.c index b21a170..d457a18 100644 --- a/tgp-2prpl.c +++ b/tgp-2prpl.c @@ -135,116 +135,6 @@ void p2tgl_conv_add_user (struct tgl_state *TLS, PurpleConversation *conv, int u purple_conv_chat_add_user (purple_conversation_get_chat_data (conv), name, message, flags, new_arrival); } -PurpleNotifyUserInfo *p2tgl_notify_user_info_new (struct tgl_user *U) { - PurpleNotifyUserInfo *info = purple_notify_user_info_new(); - - if (str_not_empty (U->first_name) && str_not_empty (U->last_name)) { - purple_notify_user_info_add_pair (info, _("First name"), U->first_name); - purple_notify_user_info_add_pair (info, _("Last name"), U->last_name); - } else { - purple_notify_user_info_add_pair (info, _("Name"), U->print_name); - } - - if (str_not_empty (U->username)) { - char *username = g_strdup_printf ("@%s", U->username); - purple_notify_user_info_add_pair (info, _("Username"), username); - g_free (username); - } - - char *status = tgp_format_user_status (&U->status); - purple_notify_user_info_add_pair (info, _("Last seen"), status); - g_free (status); - - if (str_not_empty (U->phone)) { - char *phone = g_strdup_printf ("+%s", U->phone); - purple_notify_user_info_add_pair (info, _("Phone"), phone); - g_free (phone); - } - - return info; -} - -PurpleNotifyUserInfo *p2tgl_notify_channel_info_new (struct tgl_channel *C) { - PurpleNotifyUserInfo *info = purple_notify_user_info_new(); - - if (str_not_empty (C->about)) { - purple_notify_user_info_add_pair (info, _("Description"), C->about); - } - - if (str_not_empty (C->username)) { - char *link = g_strdup_printf ("https://telegram.me/%s", C->username); - purple_notify_user_info_add_pair (info, _("Link"), link); - g_free (link); - } - - if (str_not_empty (C->print_title)) { - purple_notify_user_info_add_pair (info, _("Print Title"), C->print_title); - } - - char *admins = g_strdup_printf ("%d", C->admins_count); - purple_notify_user_info_add_pair (info, _("Administrators"), admins); - g_free (admins); - - char *participants = g_strdup_printf ("%d", C->participants_count); - purple_notify_user_info_add_pair (info, _("Participants"), participants); - g_free (participants); - - char *kicked = g_strdup_printf ("%d", C->kicked_count); - purple_notify_user_info_add_pair (info, _("Kicked"), kicked); - g_free (kicked); - - return info; -} - -PurpleNotifyUserInfo *p2tgl_notify_encrypted_chat_info_new (struct tgl_state *TLS, struct tgl_secret_chat *secret, - struct tgl_user *U) { - PurpleNotifyUserInfo *info = p2tgl_notify_user_info_new (U); - - if (secret->state == sc_waiting) { - purple_notify_user_info_add_pair (info, "", _("Waiting for the user to get online...")); - return info; - } - - const char *ttl_key = _("Self destruction timer"); - if (secret->ttl) { - char *ttl = g_strdup_printf ("%d", secret->ttl); - purple_notify_user_info_add_pair (info, ttl_key, ttl); - g_free (ttl); - } else { - purple_notify_user_info_add_pair (info, ttl_key, _("Timer is not enabled.")); - } - - if (secret->first_key_sha[0]) { - int sha1key_store_id = tgp_visualize_key (TLS, secret->first_key_sha); - if (sha1key_store_id != -1) { - char *ident_icon = tgp_format_img (sha1key_store_id); - purple_notify_user_info_add_pair (info, _("Secret key"), ident_icon); - g_free(ident_icon); - } - } - - return info; -} - -PurpleNotifyUserInfo *p2tgl_notify_peer_info_new (struct tgl_state *TLS, tgl_peer_t *P) { - switch (tgl_get_peer_type (P->id)) { - case TGL_PEER_ENCR_CHAT: { - struct tgl_secret_chat *chat = &P->encr_chat; - tgl_peer_t *partner = tgp_encr_chat_get_partner (TLS, chat); - return p2tgl_notify_encrypted_chat_info_new (TLS, chat, &partner->user); - } - - case TGL_PEER_USER: - return p2tgl_notify_user_info_new (&P->user); - - case TGL_PEER_CHANNEL: - return p2tgl_notify_channel_info_new (&P->channel); - - default: - return purple_notify_user_info_new (); - } -} - int p2tgl_imgstore_add_with_id (const char* filename) { gchar *data = NULL; size_t len; @@ -336,12 +226,3 @@ int p2tgl_imgstore_add_with_id_webp (const char *filename) { return imgStoreId; } #endif - -void p2tgl_buddy_icons_set_for_user (PurpleAccount *pa, tgl_peer_id_t id, const char* filename) { - gchar *data = NULL; - size_t len; - GError *err = NULL; - g_file_get_contents (filename, &data, &len, &err); - purple_buddy_icons_set_for_user (pa, tgp_blist_lookup_purple_name (pa_get_data (pa)->TLS, id), data, len, NULL); -} - diff --git a/tgp-2prpl.h b/tgp-2prpl.h index 5a5ad4e..8a8d239 100644 --- a/tgp-2prpl.h +++ b/tgp-2prpl.h @@ -39,12 +39,8 @@ void p2tgl_got_im_combo (struct tgl_state *TLS, tgl_peer_id_t who, const char *m void p2tgl_prpl_got_user_status (struct tgl_state *TLS, tgl_peer_id_t user, struct tgl_user_status *status); void p2tgl_conv_add_user (struct tgl_state *TLS, PurpleConversation *conv, int user, char *message, int flags, int new_arrival); PurpleConversation *p2tgl_find_conversation_with_account (struct tgl_state *TLS, tgl_peer_id_t peer); -PurpleNotifyUserInfo *p2tgl_notify_peer_info_new (struct tgl_state *TLS, tgl_peer_t *P); -PurpleNotifyUserInfo *p2tgl_notify_user_info_new (struct tgl_user *U); -PurpleNotifyUserInfo *p2tgl_notify_encrypted_chat_info_new (struct tgl_state *TLS, struct tgl_secret_chat *secret, struct tgl_user *U); -int p2tgl_imgstore_add_with_id (const char* filename); -void p2tgl_buddy_icons_set_for_user (PurpleAccount *pa, tgl_peer_id_t id, const char* filename); +int p2tgl_imgstore_add_with_id (const char* filename); int p2tgl_imgstore_add_with_id_raw (const unsigned char *raw_rgba, unsigned width, unsigned height); #ifdef HAVE_LIBWEBP int p2tgl_imgstore_add_with_id_webp (const char *filename); diff --git a/tgp-info.c b/tgp-info.c new file mode 100644 index 0000000..f2dfbf5 --- /dev/null +++ b/tgp-info.c @@ -0,0 +1,286 @@ +/* + This file is part of telegram-purple + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + + Copyright Matthias Jentsch 2016 + */ + +#include "tgp-info.h" + + +// load photo + +static void tgp_info_load_photo_done (struct tgl_state *TLS, void *extra, int success, + const char *filename) { + struct tgp_info_load_photo_data *data = extra; + + if (! success) { + data->callback (TLS, data->extra, NULL, 0, 0); + } else { + gchar *img = NULL; + size_t len; + GError *err = NULL; + g_file_get_contents (filename, &img, &len, &err); + + if (err) { + failure ("getting file contents for %s failed: %s", filename, err->message); + data->callback (TLS, data->extra, NULL, 0, FALSE); + return; + } + data->callback (TLS, data->extra, img, len, success); + } + free (data); +} + +static void tgp_info_update_photo_chat_done (struct tgl_state *TLS, void *extra, int success, struct tgl_chat *C) { + g_return_if_fail(success); + g_return_if_fail(C->photo); + tgl_do_load_photo (TLS, C->photo, tgp_info_load_photo_done, extra); +} + +static void tgp_info_update_photo_user_done (struct tgl_state *TLS, void *extra, int success, struct tgl_user *U) { + g_return_if_fail(success); + g_return_if_fail(U->photo); + tgl_do_load_photo (TLS, U->photo, tgp_info_load_photo_done, extra); +} + +static void tgp_info_update_photo_channel_done (struct tgl_state *TLS, void *extra, int success, struct tgl_channel *CH) { + g_return_if_fail(success); + g_return_if_fail(CH->photo); + tgl_do_load_photo (TLS, CH->photo, tgp_info_load_photo_done, extra); +} + +void tgp_info_load_photo_peer (struct tgl_state *TLS, tgl_peer_t *P, void *extra, + void (*callback) (struct tgl_state *TLS, void *extra, gchar *img, size_t len, int success)) { + assert(callback); + + struct tgp_info_load_photo_data *D = talloc0 (sizeof(struct tgp_info_load_photo_data)); + D->callback = callback; + D->extra = extra; + D->TLS = TLS; + + switch (tgl_get_peer_type (P->id)) { + case TGL_PEER_CHANNEL: + tgl_do_get_channel_info (TLS, P->id, FALSE, tgp_info_update_photo_channel_done, D); + break; + + case TGL_PEER_USER: + tgl_do_get_user_info (TLS, P->id, FALSE, tgp_info_update_photo_user_done, D); + break; + + case TGL_PEER_CHAT: + tgl_do_get_chat_info (TLS, P->id, FALSE, tgp_info_update_photo_chat_done, D); + break; + + case TGL_PEER_ENCR_CHAT: { + tgl_peer_t *parent = tgp_encr_chat_get_partner (TLS, &P->encr_chat); + g_return_if_fail(parent); + tgl_do_get_user_info (TLS, parent->id, FALSE, tgp_info_update_photo_user_done, D); + break; + } + + default: + g_warn_if_reached(); + break; + } +} + + +// update photo + +static void tgp_info_update_photo_done (struct tgl_state *TLS, void *extra, gchar *img, size_t len, int success) { + PurpleBuddy *node = extra; + g_return_if_fail(success); + purple_buddy_icons_set_for_user (tls_get_pa (TLS), purple_buddy_get_name (node), img, len, NULL); +} + +void tgp_info_update_photo (PurpleBuddy *buddy, tgl_peer_t *P) { + PurpleBlistNode *node = &buddy->node; + tgl_peer_t *parent = NULL; + + long long photo = 0; + switch (tgl_get_peer_type (P->id)) { + case TGL_PEER_USER: + photo = P->user.photo_id; + break; + + case TGL_PEER_CHANNEL: + photo = P->channel.photo_id; + break; + + case TGL_PEER_ENCR_CHAT: { + parent = tgp_encr_chat_get_partner (pbn_get_data (node)->TLS, &P->encr_chat); + photo = parent->photo_id; + break; + } + + default: + return; + } + + const char *old = purple_blist_node_get_string (node, TGP_INFO_PHOTO_ID); + if (old) { + long long id = 0; + id = atoll (old); + if (id == photo) { + debug ("photo id for %s hasn't changed %lld", buddy->name, id); + return; + } + } + + if (photo != 0) { + tgp_info_load_photo_peer (pbn_get_data (node)->TLS, parent ? parent : P, node, tgp_info_update_photo_done); + } else { + purple_buddy_icons_set_for_user (purple_buddy_get_account (buddy), purple_buddy_get_name (buddy), NULL, + 0, NULL); + } + + // FIXME: call this in tgp_info_update_photo_done, right now just hope for the best + char *llid = g_strdup_printf ("%lld", photo); + debug ("tgl_info_update_photo %s", llid); + purple_blist_node_set_string (node, TGP_INFO_PHOTO_ID, llid); + g_free (llid); +} + + +// show user info + +static void tgp_info_load_channel_done (struct tgl_state *TLS, void *extra, int success, struct tgl_channel *C) { + g_return_if_fail(success); + + + PurpleNotifyUserInfo *info = purple_notify_user_info_new (); + + if (str_not_empty (C->about)) { + purple_notify_user_info_add_pair (info, _("Description"), C->about); + } + + if (str_not_empty (C->username)) { + char *link = g_strdup_printf ("https://telegram.me/%s", C->username); + purple_notify_user_info_add_pair (info, _("Link"), link); + g_free (link); + } + + if (str_not_empty (C->print_title)) { + purple_notify_user_info_add_pair (info, _("Print Title"), C->print_title); + } + + char *admins = g_strdup_printf ("%d", C->admins_count); + purple_notify_user_info_add_pair (info, _("Administrators"), admins); + g_free (admins); + + char *participants = g_strdup_printf ("%d", C->participants_count); + purple_notify_user_info_add_pair (info, _("Participants"), participants); + g_free (participants); + + char *kicked = g_strdup_printf ("%d", C->kicked_count); + purple_notify_user_info_add_pair (info, _("Kicked"), kicked); + g_free (kicked); + + purple_notify_userinfo (tls_get_conn (TLS), tgp_blist_lookup_purple_name (TLS, C->id), info, NULL, NULL); +} + +static void tgp_info_load_user_done (struct tgl_state *TLS, void *extra, int success, struct tgl_user *U) { + g_return_if_fail(success); + + // user info + + PurpleNotifyUserInfo *info = purple_notify_user_info_new (); + + if (str_not_empty (U->first_name) && str_not_empty (U->last_name)) { + purple_notify_user_info_add_pair (info, _("First name"), U->first_name); + purple_notify_user_info_add_pair (info, _("Last name"), U->last_name); + } else { + purple_notify_user_info_add_pair (info, _("Name"), U->print_name); + } + + if (str_not_empty (U->username)) { + char *username = g_strdup_printf ("@%s", U->username); + purple_notify_user_info_add_pair (info, _("Username"), username); + g_free (username); + } + + char *status = tgp_format_user_status (&U->status); + purple_notify_user_info_add_pair (info, _("Last seen"), status); + g_free (status); + + if (str_not_empty (U->phone)) { + char *phone = g_strdup_printf ("+%s", U->phone); + purple_notify_user_info_add_pair (info, _("Phone"), phone); + g_free (phone); + } + + // secret chat info + + tgl_peer_t *O = extra; + if (O && tgl_get_peer_type (O->id) == TGL_PEER_ENCR_CHAT) { + + struct tgl_secret_chat *secret = &O->encr_chat; + + if (secret->state == sc_waiting) { + purple_notify_user_info_add_pair (info, "", _("Waiting for the user to get online...")); + } else { + const char *ttl_key = _("Self destruction timer"); + if (secret->ttl) { + char *ttl = g_strdup_printf ("%d", secret->ttl); + purple_notify_user_info_add_pair (info, ttl_key, ttl); + g_free (ttl); + } else { + purple_notify_user_info_add_pair (info, ttl_key, _("Timer is not enabled.")); + } + + if (secret->first_key_sha[0]) { + int sha1key = tgp_visualize_key (TLS, secret->first_key_sha); + if (sha1key != -1) { + char *ident_icon = tgp_format_img (sha1key); + purple_notify_user_info_add_pair (info, _("Secret key"), ident_icon); + g_free(ident_icon); + } + } + } + } + + const char *who = NULL; + if (tgl_get_peer_type (O->id) == TGL_PEER_ENCR_CHAT) { + who = tgp_blist_lookup_purple_name (TLS, O->id); + } else { + who = tgp_blist_lookup_purple_name (TLS, U->id); + } + + purple_notify_userinfo (tls_get_conn (TLS), who, info, NULL, NULL); +} + +void tgprpl_info_show (PurpleConnection *gc, const char *who) { + tgl_peer_t *P = tgp_blist_lookup_peer_get (gc_get_data (gc)->TLS, who); + if (P) { + switch (tgl_get_peer_type (P->id)) { + case TGL_PEER_ENCR_CHAT: { + tgl_peer_t *parent = tgp_encr_chat_get_partner (gc_get_tls (gc), &P->encr_chat); + if (parent) { + tgl_do_get_user_info (gc_get_tls (gc), parent->id, 0, tgp_info_load_user_done, P); + } + break; + } + + case TGL_PEER_CHANNEL: + tgl_do_get_channel_info (gc_get_tls (gc), P->id, FALSE, tgp_info_load_channel_done, P); + break; + + case TGL_PEER_USER: + tgl_do_get_user_info (gc_get_tls (gc), P->id, 0, tgp_info_load_user_done, P); + break; + } + } +} diff --git a/tgp-info.h b/tgp-info.h new file mode 100644 index 0000000..0abfd2c --- /dev/null +++ b/tgp-info.h @@ -0,0 +1,37 @@ +/* + This file is part of telegram-purple + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA + + Copyright Matthias Jentsch 2016 + */ + +#ifndef tgp_info_h +#define tgp_info_h + +#include "telegram-purple.h" + +#define TGP_INFO_PHOTO_ID "tgp-photo-id" + +struct tgp_info_load_photo_data { + struct tgl_state *TLS; + void (* callback) (struct tgl_state *TLS, void *extra, gchar *img, size_t len, int success); + void *extra; +}; + +void tgp_info_load_photo_peer (struct tgl_state *TLS, tgl_peer_t *P, void *extra, + void (*callback) (struct tgl_state *TLS, void *extra, gchar *img, size_t len, int success)); +void tgp_info_update_photo (PurpleBuddy *buddy, tgl_peer_t *P); +void tgprpl_info_show (PurpleConnection *gc, const char *who); +#endif diff --git a/tgp-msg.c b/tgp-msg.c index f2ea416..07da700 100644 --- a/tgp-msg.c +++ b/tgp-msg.c @@ -164,7 +164,8 @@ static char *format_service_msg (struct tgl_state *TLS, struct tgl_message *M) { // Add the new channel to the buddy list PurpleBuddy *buddy = tgp_blist_buddy_new (TLS, fromPeer); purple_blist_add_buddy (buddy, NULL, tgp_blist_group_init (_("Telegram Channels")), NULL); - tgl_do_get_channel_info (TLS, fromPeer->id, FALSE, channel_load_photo, NULL); + tgp_info_update_photo (buddy, fromPeer); + purple_prpl_got_user_status (tls_get_pa (TLS), tgp_blist_lookup_purple_name (TLS, fromPeer->id), "available", NULL); break; diff --git a/tgp-structs.c b/tgp-structs.c index 59e9f1a..5747cee 100644 --- a/tgp-structs.c +++ b/tgp-structs.c @@ -127,11 +127,3 @@ void *connection_data_free (connection_data *conn) { free (conn); return NULL; } - -get_user_info_data* get_user_info_data_new (int show_info, tgl_peer_id_t peer) { - get_user_info_data *info_data = malloc (sizeof(get_user_info_data)); - info_data->show_info = show_info; - info_data->peer = peer; - return info_data; -} - diff --git a/tgp-structs.h b/tgp-structs.h index 576a0a9..5026c3f 100644 --- a/tgp-structs.h +++ b/tgp-structs.h @@ -50,11 +50,6 @@ typedef struct { int dialogues_ready; } connection_data; -typedef struct { - int show_info; - tgl_peer_id_t peer; -} get_user_info_data; - struct tgp_xfer_send_data { int timer; int loading; @@ -63,11 +58,6 @@ struct tgp_xfer_send_data { struct tgl_message *msg; }; -struct download_desc { - get_user_info_data *get_user_info_data; - void *data; -}; - struct tgp_msg_loading { int pending; struct tgl_message *msg; @@ -87,7 +77,6 @@ void pending_reads_send_user (struct tgl_state *TLS, tgl_peer_id_t id); void used_images_add (connection_data *data, gint imgid); void *connection_data_free (connection_data *conn); connection_data *connection_data_init (struct tgl_state *TLS, PurpleConnection *gc, PurpleAccount *pa); -get_user_info_data* get_user_info_data_new (int show_info, tgl_peer_id_t peer); struct tgp_msg_loading *tgp_msg_loading_init (struct tgl_message *M); struct tgp_msg_sending *tgp_msg_sending_init (struct tgl_state *TLS, char *M, tgl_peer_id_t to); void tgp_msg_loading_free (gpointer data);