pidgin/plugins/imgupload.c

changeset 39992
bffad41e933f
parent 39502
818d74083471
child 40016
26a9086b8cec
equal deleted inserted replaced
39991:aef6dc04cf17 39992:bffad41e933f
31 #include "gtkplugin.h" 31 #include "gtkplugin.h"
32 #include "gtkutils.h" 32 #include "gtkutils.h"
33 #include "gtkwebviewtoolbar.h" 33 #include "gtkwebviewtoolbar.h"
34 34
35 #include <json-glib/json-glib.h> 35 #include <json-glib/json-glib.h>
36 #include <libsoup/soup.h>
36 37
37 #define IMGUP_IMGUR_CLIENT_ID "b6d33c6bb80e1b6" 38 #define IMGUP_IMGUR_CLIENT_ID "b6d33c6bb80e1b6"
38 #define IMGUP_PREF_PREFIX "/plugins/gtk/imgupload/" 39 #define IMGUP_PREF_PREFIX "/plugins/gtk/imgupload/"
39 40
40 static PurplePlugin *plugin_handle = NULL; 41 static PurplePlugin *plugin_handle = NULL;
42 static SoupSession *session = NULL;
41 43
42 static void 44 static void
43 imgup_upload_done(PidginWebView *webview, const gchar *url, const gchar *title); 45 imgup_upload_done(PidginWebView *webview, const gchar *url, const gchar *title);
44 static void 46 static void
45 imgup_upload_failed(PidginWebView *webview); 47 imgup_upload_failed(PidginWebView *webview);
59 /****************************************************************************** 61 /******************************************************************************
60 * Imgur implementation 62 * Imgur implementation
61 ******************************************************************************/ 63 ******************************************************************************/
62 64
63 static void 65 static void
64 imgup_imgur_uploaded(PurpleHttpConnection *hc, PurpleHttpResponse *resp, 66 imgup_imgur_uploaded(G_GNUC_UNUSED SoupSession *session, SoupMessage *msg,
65 gpointer _webview) 67 gpointer _webview)
66 { 68 {
67 JsonParser *parser; 69 JsonParser *parser;
68 JsonObject *result; 70 JsonObject *result;
69 const gchar *data;
70 gsize data_len;
71 PidginWebView *webview = PIDGIN_WEBVIEW(_webview); 71 PidginWebView *webview = PIDGIN_WEBVIEW(_webview);
72 const gchar *url, *title; 72 const gchar *url, *title;
73 73
74 if (!purple_http_response_is_successful(resp)) { 74 if (!SOUP_STATUS_IS_SUCCESSFUL(msg->status_code)) {
75 imgup_upload_failed(webview); 75 imgup_upload_failed(webview);
76 return; 76 return;
77 } 77 }
78 78
79 data = purple_http_response_get_data(resp, &data_len);
80 parser = json_parser_new(); 79 parser = json_parser_new();
81 if (!json_parser_load_from_data(parser, data, data_len, NULL)) { 80 if (!json_parser_load_from_data(parser, msg->response_body->data,
81 msg->response_body->length, NULL)) {
82 purple_debug_warning("imgupload", "Invalid json got from imgur"); 82 purple_debug_warning("imgupload", "Invalid json got from imgur");
83 83
84 imgup_upload_failed(webview); 84 imgup_upload_failed(webview);
85 return; 85 return;
86 } 86 }
97 } 97 }
98 98
99 result = json_object_get_object_member(result, "data"); 99 result = json_object_get_object_member(result, "data");
100 url = json_object_get_string_member(result, "link"); 100 url = json_object_get_string_member(result, "link");
101 101
102 title = g_object_get_data(G_OBJECT(webview), "imgupload-imgur-name"); 102 title = g_object_get_data(G_OBJECT(msg), "imgupload-imgur-name");
103 103
104 imgup_upload_done(webview, url, title); 104 imgup_upload_done(webview, url, title);
105 105
106 g_object_unref(parser); 106 g_object_unref(parser);
107 g_object_set_data(G_OBJECT(webview), "imgupload-imgur-name", NULL); 107 g_object_set_data(G_OBJECT(msg), "imgupload-imgur-name", NULL);
108 } 108 }
109 109
110 static PurpleHttpConnection * 110 static PurpleHttpConnection *
111 imgup_imgur_upload(PidginWebView *webview, PurpleImage *image) 111 imgup_imgur_upload(PidginWebView *webview, PurpleImage *image)
112 { 112 {
113 PurpleHttpRequest *req; 113 SoupMessage *msg;
114 PurpleHttpConnection *hc;
115 gchar *req_data, *img_data, *img_data_e; 114 gchar *req_data, *img_data, *img_data_e;
116 115
117 req = purple_http_request_new("https://api.imgur.com/3/image"); 116 msg = soup_message_new("POST", "https://api.imgur.com/3/image");
118 purple_http_request_set_method(req, "POST"); 117 soup_message_headers_replace(msg, "Authorization",
119 purple_http_request_header_set(req, "Authorization", 118 "Client-ID " IMGUP_IMGUR_CLIENT_ID);
120 "Client-ID " IMGUP_IMGUR_CLIENT_ID);
121 119
122 /* TODO: make it a plain, multipart/form-data request */ 120 /* TODO: make it a plain, multipart/form-data request */
123 img_data = g_base64_encode(purple_image_get_data(image), 121 img_data = g_base64_encode(purple_image_get_data(image),
124 purple_image_get_data_size(image)); 122 purple_image_get_data_size(image));
125 img_data_e = g_uri_escape_string(img_data, NULL, FALSE); 123 img_data_e = g_uri_escape_string(img_data, NULL, FALSE);
126 g_free(img_data); 124 g_free(img_data);
127 req_data = g_strdup_printf("type=base64&image=%s", img_data_e); 125 req_data = g_strdup_printf("type=base64&image=%s", img_data_e);
128 g_free(img_data_e); 126 g_free(img_data_e);
129 127
130 purple_http_request_header_set(req, "Content-Type", 128 soup_message_set_request(msg, "application/x-www-form-urlencoded",
131 "application/x-www-form-urlencoded"); 129 SOUP_MESSAGE_TAKE, req_data, -1);
132 purple_http_request_set_contents(req, req_data, -1); 130
133 g_free(req_data); 131 g_object_set_data_full(G_OBJECT(msg), "imgupload-imgur-name",
134 132 g_strdup(purple_image_get_friendly_filename(image)),
135 /* TODO: set it to hc, not webview (after gobjectifying it) */ 133 g_free);
136 g_object_set_data_full(G_OBJECT(webview), "imgupload-imgur-name", 134
137 g_strdup(purple_image_get_friendly_filename(image)), g_free); 135 soup_session_queue_message(session, msg, imgup_imgur_uploaded, webview);
138 136
139 hc = purple_http_request(NULL, req, imgup_imgur_uploaded, webview); 137 return msg;
140 purple_http_request_unref(req);
141
142 return hc;
143 } 138 }
144 139
145 /****************************************************************************** 140 /******************************************************************************
146 * Image/link upload and insertion 141 * Image/link upload and insertion
147 ******************************************************************************/ 142 ******************************************************************************/
149 static void 144 static void
150 imgup_upload_finish(PidginWebView *webview) 145 imgup_upload_finish(PidginWebView *webview)
151 { 146 {
152 gpointer plswait; 147 gpointer plswait;
153 148
154 g_object_steal_data(G_OBJECT(webview), "imgupload-hc"); 149 g_object_steal_data(G_OBJECT(webview), "imgupload-msg");
155 plswait = g_object_get_data(G_OBJECT(webview), "imgupload-plswait"); 150 plswait = g_object_get_data(G_OBJECT(webview), "imgupload-plswait");
156 g_object_set_data(G_OBJECT(webview), "imgupload-plswait", NULL); 151 g_object_set_data(G_OBJECT(webview), "imgupload-plswait", NULL);
157 152
158 if (plswait) 153 if (plswait)
159 purple_request_close(PURPLE_REQUEST_WAIT, plswait); 154 purple_request_close(PURPLE_REQUEST_WAIT, plswait);
192 if (!is_cancelled) 187 if (!is_cancelled)
193 purple_debug_error("imgupload", "Failed uploading image"); 188 purple_debug_error("imgupload", "Failed uploading image");
194 } 189 }
195 190
196 static void 191 static void
192 imgup_upload_cancel_message(SoupMessage *msg)
193 {
194 soup_session_cancel_message(session, msg, SOUP_STATUS_CANCELLED);
195 }
196
197 static void
197 imgup_upload_cancel(gpointer _webview) 198 imgup_upload_cancel(gpointer _webview)
198 { 199 {
199 PurpleHttpConnection *hc; 200 SoupMessage *msg;
200 PidginWebView *webview = PIDGIN_WEBVIEW(_webview); 201 PidginWebView *webview = PIDGIN_WEBVIEW(_webview);
201 202
202 g_object_set_data(G_OBJECT(webview), "imgupload-plswait", NULL); 203 g_object_set_data(G_OBJECT(webview), "imgupload-plswait", NULL);
203 g_object_set_data(G_OBJECT(webview), "imgupload-cancelled", 204 g_object_set_data(G_OBJECT(webview), "imgupload-cancelled",
204 GINT_TO_POINTER(TRUE)); 205 GINT_TO_POINTER(TRUE));
205 hc = g_object_get_data(G_OBJECT(webview), "imgupload-hc"); 206 msg = g_object_steal_data(G_OBJECT(webview), "imgupload-msg");
206 if (hc) 207 if (msg) {
207 purple_http_conn_cancel(hc); 208 soup_session_cancel_message(session, msg, SOUP_STATUS_CANCELLED);
209 }
208 } 210 }
209 211
210 static gboolean 212 static gboolean
211 imgup_upload_start(PidginWebView *webview, PurpleImage *image, gpointer _gtkconv) 213 imgup_upload_start(PidginWebView *webview, PurpleImage *image, gpointer _gtkconv)
212 { 214 {
213 PidginConversation *gtkconv = _gtkconv; 215 PidginConversation *gtkconv = _gtkconv;
214 PurpleConversation *conv = gtkconv->active_conv; 216 PurpleConversation *conv = gtkconv->active_conv;
215 PurpleHttpConnection *hc; 217 SoupMessage *msg;
216 gpointer plswait; 218 gpointer plswait;
217 219
218 if (!imgup_conn_is_hooked(purple_conversation_get_connection(conv))) 220 if (!imgup_conn_is_hooked(purple_conversation_get_connection(conv)))
219 return FALSE; 221 return FALSE;
220 222
221 hc = imgup_imgur_upload(webview, image); 223 msg = imgup_imgur_upload(webview, image);
222 g_object_set_data_full(G_OBJECT(webview), "imgupload-hc", 224 g_object_set_data_full(G_OBJECT(webview), "imgupload-msg", msg,
223 hc, (GDestroyNotify)purple_http_conn_cancel); 225 (GDestroyNotify)imgup_upload_cancel_message);
224 226
225 plswait = purple_request_wait(plugin_handle, _("Uploading image"), 227 plswait = purple_request_wait(plugin_handle, _("Uploading image"),
226 _("Please wait for image URL being retrieved..."), 228 _("Please wait for image URL being retrieved..."),
227 NULL, FALSE, imgup_upload_cancel, 229 NULL, FALSE, imgup_upload_cancel,
228 purple_request_cpar_from_conversation(conv), webview); 230 purple_request_cpar_from_conversation(conv), webview);
409 purple_prefs_add_none("/plugins/gtk/imgupload"); 411 purple_prefs_add_none("/plugins/gtk/imgupload");
410 412
411 purple_prefs_add_bool(IMGUP_PREF_PREFIX "use_url_desc", TRUE); 413 purple_prefs_add_bool(IMGUP_PREF_PREFIX "use_url_desc", TRUE);
412 414
413 plugin_handle = plugin; 415 plugin_handle = plugin;
416 session = soup_session_new();
414 417
415 it = purple_connections_get_all(); 418 it = purple_connections_get_all();
416 for (; it; it = g_list_next(it)) { 419 for (; it; it = g_list_next(it)) {
417 PurpleConnection *gc = it->data; 420 PurpleConnection *gc = it->data;
418 imgup_conn_init(gc); 421 imgup_conn_init(gc);
442 static gboolean 445 static gboolean
443 plugin_unload(PurplePlugin *plugin, GError **error) 446 plugin_unload(PurplePlugin *plugin, GError **error)
444 { 447 {
445 GList *it; 448 GList *it;
446 449
450 soup_session_abort(session);
451
447 it = purple_conversations_get_all(); 452 it = purple_conversations_get_all();
448 for (; it; it = g_list_next(it)) { 453 for (; it; it = g_list_next(it)) {
449 PurpleConversation *conv = it->data; 454 PurpleConversation *conv = it->data;
450 imgup_conv_uninit(conv); 455 imgup_conv_uninit(conv);
451 if (PIDGIN_IS_PIDGIN_CONVERSATION(conv)) 456 if (PIDGIN_IS_PIDGIN_CONVERSATION(conv))
456 for (; it; it = g_list_next(it)) { 461 for (; it; it = g_list_next(it)) {
457 PurpleConnection *gc = it->data; 462 PurpleConnection *gc = it->data;
458 imgup_conn_uninit(gc); 463 imgup_conn_uninit(gc);
459 } 464 }
460 465
466 g_clear_object(&session);
461 plugin_handle = NULL; 467 plugin_handle = NULL;
462 468
463 return TRUE; 469 return TRUE;
464 } 470 }
465 471

mercurial