diff --git a/telegram-purple.c b/telegram-purple.c index c655328..c403b2d 100644 --- a/telegram-purple.c +++ b/telegram-purple.c @@ -864,11 +864,11 @@ static void tgprpl_init (PurplePlugin *plugin) { ADD_VALUE(choices, _("Always"), "always"); ADD_VALUE(choices, _("Never"), "never"); ADD_VALUE(choices, _("Ask"), "ask"); - + opt = purple_account_option_list_new (_("Accept secret chats"), TGP_KEY_ACCEPT_SECRET_CHATS, choices); prpl_info.protocol_options = g_list_append(prpl_info.protocol_options, opt); - + opt = purple_account_option_int_new (_("Display buddies offline after (days)"), TGP_KEY_INACTIVE_DAYS_OFFLINE, TGP_DEFAULT_INACTIVE_DAYS_OFFLINE); prpl_info.protocol_options = g_list_append (prpl_info.protocol_options, opt); @@ -876,26 +876,34 @@ static void tgprpl_init (PurplePlugin *plugin) { opt = purple_account_option_int_new (_("Don't fetch history older than (days)\n(0 for unlimited)"), TGP_KEY_HISTORY_RETRIEVAL_THRESHOLD, TGP_DEFAULT_HISTORY_RETRIEVAL_THRESHOLD); prpl_info.protocol_options = g_list_append (prpl_info.protocol_options, opt); - - // Media - opt = purple_account_option_int_new (_("Autoload media size (kb)"), TGP_KEY_MEDIA_SIZE, - TGP_DEFAULT_MEDIA_SIZE); + + // Media and documents + choices = NULL; + ADD_VALUE(choices, _("Discard"), "discard"); + ADD_VALUE(choices, _("Auto load"), "autoload"); + ADD_VALUE(choices, _("Ask"), "ask"); + + opt = purple_account_option_list_new (_("Handle file transfers"), TGP_KEY_FT_HANDLING, choices); prpl_info.protocol_options = g_list_append (prpl_info.protocol_options, opt); - + + opt = purple_account_option_int_new (_("Auto load file transfers up to (kb)"), TGP_KEY_MEDIA_SIZE, + TGP_DEFAULT_MEDIA_SIZE); + prpl_info.protocol_options = g_list_append (prpl_info.protocol_options, opt); + // Chats opt = purple_account_option_bool_new (_("Add all group chats to buddy list"), TGP_KEY_JOIN_GROUP_CHATS, TGP_DEFAULT_JOIN_GROUP_CHATS); prpl_info.protocol_options = g_list_append (prpl_info.protocol_options, opt); - // Read notifications + // Receipts opt = purple_account_option_bool_new (_("Display notices of receipt"), TGP_KEY_DISPLAY_READ_NOTIFICATIONS, TGP_DEFAULT_DISPLAY_READ_NOTIFICATIONS); prpl_info.protocol_options = g_list_append (prpl_info.protocol_options, opt); - + opt = purple_account_option_bool_new (_("Send notices of receipt when present"), TGP_KEY_SEND_READ_NOTIFICATIONS, TGP_DEFAULT_SEND_READ_NOTIFICATIONS); prpl_info.protocol_options = g_list_append (prpl_info.protocol_options, opt); - + _telegram_protocol = plugin; debug ("tgprpl_init finished: This is " PACKAGE_VERSION "+g" GIT_COMMIT " on libtgl " TGL_VERSION); } diff --git a/telegram-purple.h b/telegram-purple.h index e45fe29..480ce48 100644 --- a/telegram-purple.h +++ b/telegram-purple.h @@ -67,6 +67,9 @@ #define TGP_MAX_MSG_SIZE 4096 #define TGP_DEFAULT_MAX_MSG_SPLIT_COUNT 4 +#define TGP_DEFAULT_FT_HANDLING "ask" +#define TGP_KEY_FT_HANDLING "media-handling-behavior" + #define TGP_DEFAULT_MEDIA_SIZE 32768 #define TGP_KEY_MEDIA_SIZE "media-size-threshold" diff --git a/tgp-2prpl.c b/tgp-2prpl.c index 1d135ab..24b319b 100644 --- a/tgp-2prpl.c +++ b/tgp-2prpl.c @@ -36,11 +36,19 @@ connection_data *tls_get_data (struct tgl_state *TLS) { return TLS->ev_base; } -int tls_get_media_threshold (struct tgl_state *TLS) { +int tls_get_ft_threshold (struct tgl_state *TLS) { return purple_account_get_int (tls_get_pa (TLS), TGP_KEY_MEDIA_SIZE, TGP_DEFAULT_MEDIA_SIZE) << 10; } +int tls_get_ft_autoload (struct tgl_state *TLS) { + return ! strcmp (purple_account_get_string (tls_get_pa (TLS), TGP_KEY_FT_HANDLING, TGP_DEFAULT_FT_HANDLING), "autoload"); +} + +int tls_get_ft_discard (struct tgl_state *TLS) { + return ! strcmp (purple_account_get_string (tls_get_pa (TLS), TGP_KEY_FT_HANDLING, TGP_DEFAULT_FT_HANDLING), "discard"); +} + connection_data *gc_get_data (PurpleConnection *gc) { return purple_connection_get_protocol_data (gc); } diff --git a/tgp-2prpl.h b/tgp-2prpl.h index 3025aca..e4edce9 100644 --- a/tgp-2prpl.h +++ b/tgp-2prpl.h @@ -27,7 +27,9 @@ PurpleAccount *tls_get_pa (struct tgl_state *TLS); PurpleConnection *tls_get_conn (struct tgl_state *TLS); connection_data *tls_get_data (struct tgl_state *TLS); -int tls_get_media_threshold (struct tgl_state *TLS); +int tls_get_ft_threshold (struct tgl_state *TLS); +int tls_get_ft_discard (struct tgl_state *TLS); +int tls_get_ft_autoload (struct tgl_state *TLS); connection_data *gc_get_data (PurpleConnection *gc); connection_data *pa_get_data (PurpleAccount *pa); connection_data *pbn_get_data (PurpleBlistNode *node); diff --git a/tgp-msg.c b/tgp-msg.c index ee7ba31..a46b774 100644 --- a/tgp-msg.c +++ b/tgp-msg.c @@ -186,6 +186,26 @@ static char *format_geo_link_osm (double lat, double lon) { return link; } +static char *format_document (const char *path, const char *filename, const char* caption, const char *mime, long long size) { + gchar *format; + + gchar *capt = g_markup_escape_text (caption, -1); + gchar *pth = g_markup_escape_text (path, -1); + gchar *fle = g_markup_escape_text (filename, -1); + gchar *mme = g_markup_escape_text (mime, -1); + gchar *fsize = g_format_size (size); + + format = g_strdup_printf ("[%s %s %s %s]", capt, pth, fle, mme, fsize); + + g_free (capt); + g_free (pth); + g_free (fle); + g_free (mme); + g_free (fsize); + + return format; +} + static void tgp_msg_send_done (struct tgl_state *TLS, void *callback_extra, int success, struct tgl_message *M) { if (! success) { char *err = _("Sending message failed."); @@ -376,15 +396,6 @@ int tgp_msg_send (struct tgl_state *TLS, const char *message, tgl_peer_id_t to) return 0; } -static char *tgp_msg_file_display (const char *path, const char *filename, const char* caption, const char *mime, long long size) { - gchar *fsize = g_format_size(size); - gchar *format; - format = g_strdup_printf ("[%s %s %s %s]", g_markup_escape_text (caption, -1), g_markup_escape_text (path, -1), - g_markup_escape_text (filename, -1), g_markup_escape_text (mime, -1), fsize); - g_free (fsize); - return format; -} - static char *tgp_msg_photo_display (struct tgl_state *TLS, const char *filename, int *flags) { connection_data *conn = TLS->ev_base; int img = p2tgl_imgstore_add_with_id (filename); @@ -490,55 +501,57 @@ static void tgp_msg_display (struct tgl_state *TLS, struct tgp_msg_loading *C) { } break; } - + case tgl_message_media_document: - + case tgl_message_media_video: + case tgl_message_media_audio: if (M->media.document->flags & TGLDF_STICKER) { g_return_if_fail(C->data != NULL); text = tgp_msg_sticker_display (TLS, M->from_id, C->data, &flags); - } else if (M->media.document->flags & TGLDF_ANIMATED) { - g_return_if_fail(C->data != NULL); - text = tgp_msg_file_display (C->data, M->media.document->caption, _("animation"), - M->media.document->mime_type, M->media.document->size); - - } else if (M->media.document->flags & TGLDF_IMAGE) { + } else if (M->media.document->flags & TGLDF_IMAGE && !(M->media.document->flags & TGLDF_ANIMATED)) { g_return_if_fail(C->data != NULL); text = tgp_msg_photo_display (TLS, C->data, &flags); } else { - if (! tgp_our_msg (TLS, M)) { - if (C->data) { - text = tgp_msg_file_display (C->data, M->media.document->caption, _("document"), - M->media.document->mime_type, M->media.document->size); - } else { - tgprpl_recv_file (tls_get_conn (TLS), tgp_blist_lookup_purple_name (TLS, M->from_id), M); - return; + // Automatically loaded files have C->data set to the file path + if (C->data) { + const char* path = C->data; + + const char *caption = _("document"); + if (M->media.document->flags & TGLDF_AUDIO) { + caption = _("audio"); + } else if (M->media.document->flags & TGLDF_ANIMATED) { + caption = _("animation"); + } else if (M->media.document->flags & TGLDF_VIDEO) { + caption = _("video"); } + + const char *filename = M->media.document->caption; + if (! str_not_empty (filename)) { + // audio and video snippets recorded from Telegram don't have captions + const char *segment = path + strlen(path) - 1; + while (segment > (char *)path && *segment != G_DIR_SEPARATOR) { + segment --; + } + filename = segment + 1; + } + + const char *mime = ""; + if (str_not_empty (M->media.document->mime_type)) { + mime = M->media.document->mime_type; + } + + text = format_document (path, filename, caption, mime, M->media.document->size); + } else { + if (! tgp_our_msg (TLS, M) && ! tls_get_ft_discard (TLS)) { + tgprpl_recv_file (tls_get_conn (TLS), tgp_blist_lookup_purple_name (TLS, M->from_id), M); + } + return; } } break; - case tgl_message_media_video: - case tgl_message_media_audio: { - if (! tgp_our_msg (TLS, M)) { - if (C->data) { - const char *filename = C->data + strlen(C->data) - 1; - while (filename > (char *)C->data && *filename != G_DIR_SEPARATOR) { - filename --; - } - filename ++; - text = tgp_msg_file_display (C->data, filename, - M->media.type == tgl_message_media_audio ? _("audio") : _("video"), - M->media.document->mime_type, M->media.document->size); - } else { - tgprpl_recv_file (tls_get_conn (TLS), tgp_blist_lookup_purple_name (TLS, M->from_id), M); - return; - } - } - } - break; - case tgl_message_media_document_encr: if (M->media.encr_document->flags & TGLDF_STICKER) { g_return_if_fail(C->data != NULL); @@ -551,7 +564,7 @@ static void tgp_msg_display (struct tgl_state *TLS, struct tgp_msg_loading *C) { } else { if (! tgp_our_msg (TLS, M)) { if (C->data) { - text = tgp_msg_file_display (C->data, M->media.encr_document->caption, _("document"), + text = format_document (C->data, M->media.encr_document->caption, _("document"), M->media.encr_document->mime_type, M->media.encr_document->size); } else { @@ -836,6 +849,7 @@ void tgp_msg_recv (struct tgl_state *TLS, struct tgl_message *M, GList *before) } if (! (M->flags & TGLMF_SERVICE)) { + debug ("service msg"); // handle all messages that need to load content before they can be displayed if (M->media.type != tgl_message_media_none) { @@ -854,42 +868,34 @@ void tgp_msg_recv (struct tgl_state *TLS, struct tgl_message *M, GList *before) // documents that are stickers or images will be displayed just like regular photo messages // and need to be loaded beforehand case tgl_message_media_document: + case tgl_message_media_video: + case tgl_message_media_audio: if (M->media.document->flags & (TGLDF_STICKER | TGLDF_IMAGE)) { ++ C->pending; tgl_do_load_document (TLS, M->media.document, tgp_msg_on_loaded_document, C); } else { - // adium doesn't support file links, autoloading media would mean that it - // wouldn't be possible to show a usable link to the user + + // adium doesn't support printing an inline file link to the downloaded file #ifndef __ADIUM_ - if (M->media.document->size <= tls_get_media_threshold (TLS)) { + + if (M->media.document->size <= tls_get_ft_threshold (TLS) || tls_get_ft_autoload (TLS)) { ++ C->pending; + if (M->media.document->flags & TGLDF_AUDIO) { tgl_do_load_audio (TLS, M->media.document, tgp_msg_on_loaded_document, C); + } else if (M->media.document->flags & TGLDF_VIDEO) { tgl_do_load_video (TLS, M->media.document, tgp_msg_on_loaded_document, C); + } else { tgl_do_load_document (TLS, M->media.document, tgp_msg_on_loaded_document, C); } } -#endif - } - break; -#ifndef __ADIUM_ - case tgl_message_media_video: - if (M->media.document->size <= tls_get_media_threshold (TLS)) { - ++ C->pending; - tgl_do_load_video (TLS, M->media.document, tgp_msg_on_loaded_document, C); - } - break; - case tgl_message_media_audio: - if (M->media.document->size <= tls_get_media_threshold (TLS)) { - ++ C->pending; - tgl_do_load_audio (TLS, M->media.document, tgp_msg_on_loaded_document, C); - } - break; #endif + } + break; case tgl_message_media_document_encr: if (M->media.encr_document->flags & TGLDF_STICKER || M->media.encr_document->flags & TGLDF_IMAGE) {