Sat, 22 Aug 2020 04:02:53 -0500
Remove purple_chat_user_[sg]et_ui_data.
Remove `purple_chat_user_[gs]et_ui_data`.
Remove `deleting-chat-user` signal. It's unused now, and just a substitute for a finalization notification.
Testing Done:
Compile only.
Reviewed at https://reviews.imfreedom.org/r/83/
/* * Image Uploader - an inline images implementation for protocols without * support for such feature. * * Copyright (C) 2014, Tomasz Wasilczyk <twasilczyk@pidgin.im> * * 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 */ #include "internal.h" #include <purple.h> #include "gtkconv.h" #include "gtkplugin.h" #include "gtkutils.h" #include "gtkwebviewtoolbar.h" #include <json-glib/json-glib.h> #include <libsoup/soup.h> #define IMGUP_IMGUR_CLIENT_ID "b6d33c6bb80e1b6" #define IMGUP_PREF_PREFIX "/plugins/gtk/imgupload/" static PurplePlugin *plugin_handle = NULL; static SoupSession *session = NULL; static void imgup_upload_done(PidginWebView *webview, const gchar *url, const gchar *title); static void imgup_upload_failed(PidginWebView *webview); /****************************************************************************** * Helper functions ******************************************************************************/ static gboolean imgup_conn_is_hooked(PurpleConnection *gc) { return GPOINTER_TO_INT(g_object_get_data(G_OBJECT(gc), "imgupload-set")); } /****************************************************************************** * Imgur implementation ******************************************************************************/ static void imgup_imgur_uploaded(G_GNUC_UNUSED SoupSession *session, SoupMessage *msg, gpointer _webview) { JsonParser *parser; JsonObject *result; PidginWebView *webview = PIDGIN_WEBVIEW(_webview); const gchar *url, *title; if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code)) { imgup_upload_failed(webview); return; } parser = json_parser_new(); if (!json_parser_load_from_data(parser, msg->response_body->data, msg->response_body->length, NULL)) { purple_debug_warning("imgupload", "Invalid json got from imgur"); imgup_upload_failed(webview); return; } result = json_node_get_object(json_parser_get_root(parser)); if (!json_object_get_boolean_member(result, "success")) { g_object_unref(parser); purple_debug_warning("imgupload", "imgur - not a success"); imgup_upload_failed(webview); return; } result = json_object_get_object_member(result, "data"); url = json_object_get_string_member(result, "link"); title = g_object_get_data(G_OBJECT(msg), "imgupload-imgur-name"); imgup_upload_done(webview, url, title); g_object_unref(parser); g_object_set_data(G_OBJECT(msg), "imgupload-imgur-name", NULL); } static PurpleHttpConnection * imgup_imgur_upload(PidginWebView *webview, PurpleImage *image) { SoupMessage *msg; gchar *req_data, *img_data, *img_data_e; msg = soup_message_new("POST", "https://api.imgur.com/3/image"); soup_message_headers_replace(msg, "Authorization", "Client-ID " IMGUP_IMGUR_CLIENT_ID); /* TODO: make it a plain, multipart/form-data request */ img_data = g_base64_encode(purple_image_get_data(image), purple_image_get_data_size(image)); img_data_e = g_uri_escape_string(img_data, NULL, FALSE); g_free(img_data); req_data = g_strdup_printf("type=base64&image=%s", img_data_e); g_free(img_data_e); soup_message_set_request(msg, "application/x-www-form-urlencoded", SOUP_MESSAGE_TAKE, req_data, strlen(req_data)); g_object_set_data_full(G_OBJECT(msg), "imgupload-imgur-name", g_strdup(purple_image_get_friendly_filename(image)), g_free); soup_session_queue_message(session, msg, imgup_imgur_uploaded, webview); return msg; } /****************************************************************************** * Image/link upload and insertion ******************************************************************************/ static void imgup_upload_finish(PidginWebView *webview) { gpointer plswait; g_object_steal_data(G_OBJECT(webview), "imgupload-msg"); plswait = g_object_get_data(G_OBJECT(webview), "imgupload-plswait"); g_object_set_data(G_OBJECT(webview), "imgupload-plswait", NULL); if (plswait) purple_request_close(PURPLE_REQUEST_WAIT, plswait); } static void imgup_upload_done(PidginWebView *webview, const gchar *url, const gchar *title) { gboolean url_desc; imgup_upload_finish(webview); if (!purple_prefs_get_bool(IMGUP_PREF_PREFIX "use_url_desc")) url_desc = FALSE; else { PidginWebViewButtons format; format = pidgin_webview_get_format_functions(webview); url_desc = format & PIDGIN_WEBVIEW_LINKDESC; } pidgin_webview_insert_link(webview, url, url_desc ? title : NULL); } static void imgup_upload_failed(PidginWebView *webview) { gboolean is_cancelled; imgup_upload_finish(webview); is_cancelled = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(webview), "imgupload-cancelled")); g_object_set_data(G_OBJECT(webview), "imgupload-cancelled", NULL); if (!is_cancelled) purple_debug_error("imgupload", "Failed uploading image"); } static void imgup_upload_cancel_message(SoupMessage *msg) { soup_session_cancel_message(session, msg, SOUP_STATUS_CANCELLED); } static void imgup_upload_cancel(gpointer _webview) { SoupMessage *msg; PidginWebView *webview = PIDGIN_WEBVIEW(_webview); g_object_set_data(G_OBJECT(webview), "imgupload-plswait", NULL); g_object_set_data(G_OBJECT(webview), "imgupload-cancelled", GINT_TO_POINTER(TRUE)); msg = g_object_steal_data(G_OBJECT(webview), "imgupload-msg"); if (msg) { soup_session_cancel_message(session, msg, SOUP_STATUS_CANCELLED); } } static gboolean imgup_upload_start(PidginWebView *webview, PurpleImage *image, gpointer _gtkconv) { PidginConversation *gtkconv = _gtkconv; PurpleConversation *conv = gtkconv->active_conv; SoupMessage *msg; gpointer plswait; if (!imgup_conn_is_hooked(purple_conversation_get_connection(conv))) return FALSE; msg = imgup_imgur_upload(webview, image); g_object_set_data_full(G_OBJECT(webview), "imgupload-msg", msg, (GDestroyNotify)imgup_upload_cancel_message); plswait = purple_request_wait(plugin_handle, _("Uploading image"), _("Please wait for image URL being retrieved..."), NULL, FALSE, imgup_upload_cancel, purple_request_cpar_from_conversation(conv), webview); g_object_set_data(G_OBJECT(webview), "imgupload-plswait", plswait); return TRUE; } /****************************************************************************** * Setup/cleanup ******************************************************************************/ static void imgup_pidconv_init(PidginConversation *gtkconv) { PidginWebView *webview; webview = PIDGIN_WEBVIEW(gtkconv->entry); g_signal_connect(G_OBJECT(webview), "insert-image", G_CALLBACK(imgup_upload_start), gtkconv); } static void imgup_pidconv_uninit(PidginConversation *gtkconv) { PidginWebView *webview; webview = PIDGIN_WEBVIEW(gtkconv->entry); g_signal_handlers_disconnect_by_func(G_OBJECT(webview), G_CALLBACK(imgup_upload_start), gtkconv); } static void imgup_conv_init(PurpleConversation *conv) { PurpleConnection *gc; gc = purple_conversation_get_connection(conv); if (!gc) return; if (!imgup_conn_is_hooked(gc)) return; purple_conversation_set_features(conv, purple_conversation_get_features(conv) & ~PURPLE_CONNECTION_FLAG_NO_IMAGES); g_object_set_data(G_OBJECT(conv), "imgupload-set", GINT_TO_POINTER(TRUE)); } static void imgup_conv_uninit(PurpleConversation *conv) { PurpleConnection *gc; gc = purple_conversation_get_connection(conv); if (gc) { if (!imgup_conn_is_hooked(gc)) return; } else { if (!g_object_get_data(G_OBJECT(conv), "imgupload-set")) return; } purple_conversation_set_features(conv, purple_conversation_get_features(conv) | PURPLE_CONNECTION_FLAG_NO_IMAGES); g_object_set_data(G_OBJECT(conv), "imgupload-set", NULL); } static void imgup_conn_init(PurpleConnection *gc) { PurpleConnectionFlags flags; flags = purple_connection_get_flags(gc); if (!(flags & PURPLE_CONNECTION_FLAG_NO_IMAGES)) return; flags &= ~PURPLE_CONNECTION_FLAG_NO_IMAGES; purple_connection_set_flags(gc, flags); g_object_set_data(G_OBJECT(gc), "imgupload-set", GINT_TO_POINTER(TRUE)); } static void imgup_conn_uninit(PurpleConnection *gc) { if (!imgup_conn_is_hooked(gc)) return; purple_connection_set_flags(gc, purple_connection_get_flags(gc) | PURPLE_CONNECTION_FLAG_NO_IMAGES); g_object_set_data(G_OBJECT(gc), "imgupload-set", NULL); } /****************************************************************************** * Prefs ******************************************************************************/ static void imgup_prefs_ok(gpointer _unused, PurpleRequestFields *fields) { gboolean use_url_desc; use_url_desc = purple_request_fields_get_bool(fields, "use_url_desc"); purple_prefs_set_bool(IMGUP_PREF_PREFIX "use_url_desc", use_url_desc); } static gpointer imgup_prefs_get(PurplePlugin *plugin) { PurpleRequestCommonParameters *cpar; PurpleRequestFields *fields; PurpleRequestFieldGroup *group; PurpleRequestField *field; gpointer handle; fields = purple_request_fields_new(); group = purple_request_field_group_new(NULL); purple_request_fields_add_group(fields, group); field = purple_request_field_bool_new("use_url_desc", _("Use image filename as link description"), purple_prefs_get_bool(IMGUP_PREF_PREFIX "use_url_desc")); purple_request_field_group_add_field(group, field); cpar = purple_request_cpar_new(); purple_request_cpar_set_icon(cpar, PURPLE_REQUEST_ICON_DIALOG); handle = purple_request_fields(plugin, _("Image Uploader"), NULL, NULL, fields, _("OK"), (GCallback)imgup_prefs_ok, _("Cancel"), NULL, cpar, NULL); return handle; } /****************************************************************************** * Plugin stuff ******************************************************************************/ static PidginPluginInfo * plugin_query(GError **error) { const gchar * const authors[] = { "Tomasz Wasilczyk <twasilczyk@pidgin.im>", NULL }; return pidgin_plugin_info_new( "id", "gtk-imgupload", "name", N_("Image Uploader"), "version", DISPLAY_VERSION, "category", N_("Utility"), "summary", N_("Inline images implementation for protocols " "without such feature."), "description", N_("Adds inline images support for protocols " "lacking this feature by uploading them to the " "external service."), "authors", authors, "website", PURPLE_WEBSITE, "abi-version", PURPLE_ABI_VERSION, "pref-request-cb", imgup_prefs_get, NULL ); } static gboolean plugin_load(PurplePlugin *plugin, GError **error) { GList *it; purple_prefs_add_none("/plugins"); purple_prefs_add_none("/plugins/gtk"); purple_prefs_add_none("/plugins/gtk/imgupload"); purple_prefs_add_bool(IMGUP_PREF_PREFIX "use_url_desc", TRUE); plugin_handle = plugin; session = soup_session_new(); it = purple_connections_get_all(); for (; it; it = g_list_next(it)) { PurpleConnection *gc = it->data; imgup_conn_init(gc); } it = purple_conversations_get_all(); for (; it; it = g_list_next(it)) { PurpleConversation *conv = it->data; imgup_conv_init(conv); if (PIDGIN_IS_PIDGIN_CONVERSATION(conv)) imgup_pidconv_init(PIDGIN_CONVERSATION(conv)); } purple_signal_connect(purple_connections_get_handle(), "signed-on", plugin, PURPLE_CALLBACK(imgup_conn_init), NULL); purple_signal_connect(purple_connections_get_handle(), "signing-off", plugin, PURPLE_CALLBACK(imgup_conn_uninit), NULL); purple_signal_connect(pidgin_conversations_get_handle(), "conversation-displayed", plugin, PURPLE_CALLBACK(imgup_pidconv_init), NULL); return TRUE; } static gboolean plugin_unload(PurplePlugin *plugin, GError **error) { GList *it; soup_session_abort(session); it = purple_conversations_get_all(); for (; it; it = g_list_next(it)) { PurpleConversation *conv = it->data; imgup_conv_uninit(conv); if (PIDGIN_IS_PIDGIN_CONVERSATION(conv)) imgup_pidconv_uninit(PIDGIN_CONVERSATION(conv)); } it = purple_connections_get_all(); for (; it; it = g_list_next(it)) { PurpleConnection *gc = it->data; imgup_conn_uninit(gc); } g_clear_object(&session); plugin_handle = NULL; return TRUE; } PURPLE_PLUGIN_INIT(imgupload, plugin_query, plugin_load, plugin_unload);