| 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 ******************************************************************************/ |
| 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); |