Fix buddy icon refreshing and refactor user info and icon handling

Keep track of loaded pictures to refresh user pictures more reliably. Create new file tgp-info to contain all code related to user information and icons. Clean up the messy code for fetching user info and user pictures and provide a streamlined function in tg-info.
This commit is contained in:
mjentsch 2016-01-03 23:55:45 +01:00
parent 8e3cebf165
commit d8fc5281ce
11 changed files with 355 additions and 263 deletions

View file

@ -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

View file

@ -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 = "<group>"; };
C4D12DEE1BC534CF00C0F6E1 /* tgp-blist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "tgp-blist.h"; path = "../tgp-blist.h"; sourceTree = "<group>"; };
C4D12DEF1BC534CF00C0F6E1 /* tgp-blist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "tgp-blist.c"; path = "../tgp-blist.c"; sourceTree = "<group>"; };
C4D3EB581C3824C5003C895B /* tgp-info.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "tgp-info.c"; path = "../tgp-info.c"; sourceTree = "<group>"; };
C4D3EB591C3824C5003C895B /* tgp-info.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "tgp-info.h"; path = "../tgp-info.h"; sourceTree = "<group>"; };
C4D432D71BC2783C00561667 /* tg-server.tglpub */ = {isa = PBXFileReference; lastKnownFileType = file; name = "tg-server.tglpub"; path = "../tg-server.tglpub"; sourceTree = "<group>"; };
C4D819041A5C862E0044CBA9 /* tgp-structs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "tgp-structs.c"; path = "../tgp-structs.c"; sourceTree = "<group>"; };
C4D819051A5C862E0044CBA9 /* tgp-structs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "tgp-structs.h"; path = "../tgp-structs.h"; sourceTree = "<group>"; };
@ -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;
};

View file

@ -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

View file

@ -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"

View file

@ -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);
}

View file

@ -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);

286
tgp-info.c Normal file
View file

@ -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;
}
}
}

37
tgp-info.h Normal file
View file

@ -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

View file

@ -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;

View file

@ -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;
}

View file

@ -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);