Add 9a03f1d0... changes in autogenerated files
[g2-sharing] / src / plugin.c
1 /*
2  * This file is part of sharing-plugin-gallery2
3  *
4  * Copyright (C) 2009 Heikki Kallasjoki. All rights reserved.
5  * Copyright (C) 2008-2009 Nokia Corporation. All rights reserved.
6  *
7  * This code is licensed under a MIT-style license, that can be
8  * found in the file called "COPYING" in the root directory.
9  *
10  */
11
12 #include <gtk/gtk.h>
13 #include <glib.h>
14 #include <string.h>
15 #include <stdio.h>
16 #include <sharing-plugin-interface.h>
17 #include <sharing-transfer.h>
18 #include <conicconnection.h>
19 #include <osso-log.h>
20 #include <hildon/hildon.h>
21
22 #include "gallery2.h"
23
24 /* Plugin interface definition: */
25
26 guint sharing_plugin_interface_init (gboolean* dead_mans_switch);
27 guint sharing_plugin_interface_uninit (gboolean* dead_mans_switch);
28 SharingPluginInterfaceSendResult sharing_plugin_interface_send (
29                 SharingTransfer* transfer, ConIcConnection* con,
30                 gboolean* dead_mans_switch);
31 SharingPluginInterfaceAccountSetupResult
32 sharing_plugin_interface_account_setup (
33                 GtkWindow* parent,
34                 SharingService* service, SharingAccount** worked_on,
35                 osso_context_t* osso);
36 SharingPluginInterfaceEditAccountResult
37 sharing_plugin_interface_edit_account (
38                 GtkWindow* parent,
39                 SharingAccount* account,
40                 ConIcConnection* con,
41                 gboolean* dead_mans_switch);
42 SharingPluginInterfaceAccountValidateResult
43 sharing_plugin_interface_account_validate (
44                 SharingAccount* account, ConIcConnection* con,
45                 gboolean *cont, gboolean* dead_mans_switch);
46
47 /* UI flow helper definition: */
48
49 static SharingPluginInterfaceEditAccountResult edit_account (SharingAccount* account, GtkWindow* parent, gboolean setup);
50
51 /**
52  * sharing_plugin_interface_init:
53  * @dead_mans_switch: What?
54  *
55  * Initialize interface
56  *
57  * Returns: 0
58  */
59 guint sharing_plugin_interface_init (gboolean* dead_mans_switch)
60 {
61     ULOG_DEBUG_L("sharing_plugin_interface_init, gallery2");
62         *dead_mans_switch = FALSE;
63     return 0;
64 }
65
66 /**
67  * sharing_plugin_interface_uninit:
68  * @dead_mans_switch: What?
69  *
70  * Uninitialize interface
71  *
72  * Returns: 0
73  */
74 guint sharing_plugin_interface_uninit (gboolean* dead_mans_switch)
75 {
76     ULOG_DEBUG_L("sharing_plugin_interface_uninit, gallery2");
77         *dead_mans_switch = FALSE;
78     return 0;
79 }
80
81 /**
82  * sharing_plugin_interface_send:
83  * @transfer: Transfer to be send
84  * @con: Connection used
85  * @dead_mans_switch: 
86  *
87  * Send interface.
88  *
89  * Returns: Result of send
90  */
91 SharingPluginInterfaceSendResult sharing_plugin_interface_send (
92                 SharingTransfer* transfer, ConIcConnection* con,
93                 gboolean* dead_mans_switch)
94 {
95     ULOG_DEBUG_L ("sharing_plugin_interface_send, gallery2");
96
97         SharingPluginInterfaceSendResult ret = SHARING_SEND_SUCCESS;
98
99         SharingEntry *entry = sharing_transfer_get_entry (transfer);
100         SharingAccount *account = sharing_entry_get_account (entry);
101
102         gchar* urlbase = sharing_account_get_param (account, "urlbase");
103         gchar* albumname = sharing_account_get_param (account, "albumname");
104
105         GHashTable* cookies = 0;
106         gchar* auth = 0;
107
108         gchar* album = 0;
109
110         /* Login to the target service */
111
112         sharing_transfer_set_progress (transfer, 0.0);
113         *dead_mans_switch = FALSE;
114
115         SharingPluginInterfaceAccountValidateResult login_ret = SHARING_ACCOUNT_VALIDATE_FAILED;
116
117         if (urlbase)
118         {
119                 gchar* user = sharing_account_get_username (account);
120                 gchar* pass = sharing_account_get_password (account);
121                 if (user && pass)
122                         login_ret = gallery2_login (con,
123                                         urlbase, user, pass,
124                                         &cookies, &auth);
125                 g_free (user);
126                 g_free (pass);
127         }
128
129         if (login_ret != SHARING_ACCOUNT_VALIDATE_SUCCESS || !sharing_transfer_continue (transfer))
130         {
131                 if (cookies) g_hash_table_unref (cookies);
132                 g_free (auth);
133                 g_free (urlbase);
134                 g_free (albumname);
135                 if (!sharing_transfer_continue (transfer))
136                         return SHARING_SEND_CANCELLED;
137                 else if (login_ret == SHARING_ACCOUNT_VALIDATE_ERROR_CONNECTION)
138                         return SHARING_SEND_ERROR_CONNECTION;
139                 else
140                         return SHARING_SEND_ERROR_AUTH;
141         }
142
143         /* Look up the album */
144
145         sharing_transfer_set_progress (transfer, 0.05);
146         *dead_mans_switch = FALSE;
147
148         login_ret = gallery2_lookup_album (con, urlbase, albumname, &album, cookies, auth);
149         g_free (albumname);
150         albumname = 0;
151
152         if (login_ret != SHARING_ACCOUNT_VALIDATE_SUCCESS || !album || !sharing_transfer_continue (transfer))
153         {
154                 if (cookies) g_hash_table_unref (cookies);
155                 g_free (auth);
156                 g_free (urlbase);
157                 g_free (album); /* just in case... */
158                 if (!sharing_transfer_continue (transfer))
159                         return SHARING_SEND_CANCELLED;
160                 else if (login_ret == SHARING_ACCOUNT_VALIDATE_ERROR_CONNECTION)
161                         return SHARING_SEND_ERROR_CONNECTION;
162                 else
163                         return SHARING_SEND_ERROR_UNKNOWN;
164         }
165
166         /* Start sending items */
167
168         sharing_transfer_set_progress (transfer, 0.1);
169         *dead_mans_switch = FALSE;
170
171         guint64 total_bytes = 0;
172
173         for (GSList* p = sharing_entry_get_media (entry); p; p = g_slist_next (p))
174         {
175                 SharingEntryMedia* media = p->data;
176                 if (!sharing_entry_media_get_sent (media))
177                         total_bytes += sharing_entry_media_get_size (media);
178         }
179
180         if (!total_bytes) total_bytes = 1; /* just in case... */
181
182         guint64 sent_bytes = 0;
183
184         for (GSList* p = sharing_entry_get_media (entry); p; p = g_slist_next (p))
185         {
186                 SharingEntryMedia* media = p->data;
187                 if (sharing_entry_media_get_sent (media))
188                         continue;
189
190                 if (!sharing_transfer_continue (transfer))
191                 {
192                         ret = SHARING_SEND_CANCELLED;
193                         break;
194                 }
195
196                 guint64 media_size = sharing_entry_media_get_size (media);
197
198                 gdouble progress_start = 1.0 - 0.9*((total_bytes - sent_bytes) / (gdouble)total_bytes);
199                 gdouble progress_end = 1.0 - 0.9*((total_bytes - (sent_bytes + media_size)) / (gdouble)total_bytes);
200
201                 sharing_transfer_set_progress (transfer, progress_start);
202                 *dead_mans_switch = FALSE;
203
204                 SharingPluginInterfaceSendResult mret = gallery2_send (con,
205                                 transfer, progress_start, progress_end, dead_mans_switch,
206                                 media,
207                                 urlbase, album, cookies, auth);
208
209                 if (mret == SHARING_SEND_SUCCESS)
210                         sharing_entry_media_set_sent (media, TRUE);
211                 else
212                         ret = mret; /* propagate last error */
213         }
214
215         sharing_transfer_set_progress (transfer, 1.0);
216         *dead_mans_switch = FALSE;
217
218         if (cookies) g_hash_table_unref (cookies);
219         g_free (auth);
220         g_free (urlbase);
221         g_free (album);
222
223         return ret;
224 }
225
226 /**
227  * sharing_plugin_interface_account_setup:
228  * @parent: Parent window
229  * @service: Service information
230  * @worked_on: Who knows?
231  * @osso: osso_context_t for the dialog.
232  *
233  * Custom account setup UI flow.
234  *
235  * Returns: Something?
236  */
237 SharingPluginInterfaceAccountSetupResult
238 sharing_plugin_interface_account_setup (
239                 GtkWindow* parent,
240                 SharingService* service, SharingAccount** worked_on,
241                 osso_context_t* osso)
242 {
243         if (!worked_on || !*worked_on)
244                 return SHARING_ACCOUNT_SETUP_ERROR_UNKNOWN;
245
246         SharingPluginInterfaceEditAccountResult res = edit_account (*worked_on, parent, TRUE);
247         if (res == SHARING_EDIT_ACCOUNT_SUCCESS)
248                 return SHARING_ACCOUNT_SETUP_SUCCESS;
249         else
250                 return SHARING_ACCOUNT_SETUP_ERROR_UNKNOWN;
251 }
252
253 /**
254  * sharing_plugin_interface_edit_account:
255  * @parent: Parent window
256  * @account: Account to edit
257  * @con: Connection to use (for what?)
258  * @dead_mans_switch: Switch to flip (really?!)
259  */
260 SharingPluginInterfaceEditAccountResult
261 sharing_plugin_interface_edit_account (
262                 GtkWindow* parent,
263                 SharingAccount* account,
264                 ConIcConnection* con,
265                 gboolean* dead_mans_switch)
266 {
267         if (!account)
268                 return SHARING_EDIT_ACCOUNT_NOT_STARTED;
269
270         return edit_account (account, parent, FALSE);
271 }
272
273 /**
274  * sharing_plugin_interface_account_validate:
275  * @account: Account tested
276  * @con: Connection used to test account
277  * @cont: ...
278  * @dead_mans_switch: ...
279  *
280  * Validates account information.
281  *
282  * Returns: Result of account validation
283  */
284 SharingPluginInterfaceAccountValidateResult
285 sharing_plugin_interface_account_validate (
286                 SharingAccount* account, ConIcConnection* con,
287                 gboolean *cont, gboolean* dead_mans_switch)
288 {
289         ULOG_DEBUG_L ("sharing_plugin_interface_account_validate, gallery2");
290
291         gchar* user = sharing_account_get_username (account);
292         gchar* pass = sharing_account_get_password (account);
293         gchar* urlbase = sharing_account_get_param (account, "urlbase");
294         gchar* albumname = sharing_account_get_param (account, "albumname");
295
296         SharingPluginInterfaceAccountValidateResult ret = SHARING_ACCOUNT_VALIDATE_FAILED;
297
298         if (user && pass && urlbase && albumname)
299         {
300                 GHashTable* cookies = 0;
301                 gchar* auth = 0;
302
303                 /* URL sanity checks and fixups */
304
305                 gboolean update_url = FALSE;
306
307                 if (!(g_str_has_prefix (urlbase, "http://")
308                                 || g_str_has_prefix (urlbase, "https://")))
309                 {
310                         gchar* prev = urlbase;
311                         urlbase = g_strdup_printf ("http://%s", prev);
312                         update_url = TRUE;
313                         g_free (prev);
314                 }
315
316                 if (g_str_has_suffix (urlbase, "/main.php"))
317                 {
318                         gchar* prev = urlbase;
319                         urlbase = g_strndup (prev, strlen (prev) - 9);
320                         update_url = TRUE;
321                         g_free (prev);
322                 }
323                 else if (g_str_has_suffix (urlbase, "/"))
324                 {
325                         gchar* prev = urlbase;
326                         urlbase = g_strndup (prev, strlen (prev) - 1);
327                         update_url = TRUE;
328                         g_free (prev);
329                 }
330
331                 if (update_url)
332                         sharing_account_set_param (account, "urlbase", urlbase);
333
334                 /* Validate by trying to login */
335
336                 ret = gallery2_login (con,
337                                 urlbase, user, pass,
338                                 &cookies, &auth);
339                 *dead_mans_switch = FALSE;
340
341                 /* Also validate the album name here, if login ok */
342
343                 if (ret == SHARING_ACCOUNT_VALIDATE_SUCCESS)
344                 {
345                         gchar* album = 0;
346                         ret = gallery2_lookup_album (con, urlbase, albumname, &album, cookies, auth);
347                         *dead_mans_switch = FALSE;
348                         g_free (album);
349                 }
350
351                 if (cookies) g_hash_table_unref (cookies);
352                 if (auth) g_free (auth);
353         }
354
355         g_free (user);
356         g_free (pass);
357         g_free (urlbase);
358         g_free (albumname);
359
360         return ret;
361 }
362
363 /* UI flow helper implementations. */
364
365 static void gui_add_item (GtkWidget* table, guint row,
366                 gchar* id, const gchar* label, const gchar* placeholder,
367                 gboolean invis, SharingAccount* a, GHashTable* h);
368 static gboolean gui_read_item (GHashTable* h, const gchar* id, SharingAccount* a);
369 static gboolean gui_read (GHashTable* h, SharingAccount* a);
370
371 static void gui_add_item (GtkWidget* table, guint row,
372                 gchar* id, const gchar* label, const gchar* placeholder,
373                 gboolean invis, SharingAccount* a, GHashTable* h)
374 {
375         GtkWidget* wlabel = gtk_label_new (label);
376         gtk_table_attach (GTK_TABLE (table), wlabel, 0, 1, row, row+1, GTK_FILL, GTK_FILL|GTK_EXPAND, HILDON_MARGIN_DOUBLE, 0);
377
378         GtkWidget* wentry = hildon_entry_new (HILDON_SIZE_AUTO);
379         hildon_entry_set_placeholder (HILDON_ENTRY (wentry), placeholder);
380         if (invis)
381                 hildon_gtk_entry_set_input_mode (GTK_ENTRY (wentry), HILDON_GTK_INPUT_MODE_FULL | HILDON_GTK_INPUT_MODE_INVISIBLE);
382         gtk_table_attach_defaults (GTK_TABLE (table), wentry, 1, 2, row, row+1);
383
384         g_hash_table_insert (h, id, wentry);
385
386         gchar* old = sharing_account_get_param (a, id);
387         if (old)
388         {
389                 gtk_entry_set_text (GTK_ENTRY (wentry), old);
390                 g_free (old);
391         }
392 }
393
394 static gboolean gui_read_item (GHashTable* h, const gchar* id, SharingAccount* a)
395 {
396         GtkWidget* wentry = g_hash_table_lookup (h, id);
397         if (!wentry) return FALSE;
398
399         gchar* old = sharing_account_get_param (a, id);
400         const gchar* new = gtk_entry_get_text (GTK_ENTRY (wentry));
401
402         gboolean changed = FALSE;
403
404         if (!old || strcmp (old, new) != 0)
405         {
406                 sharing_account_set_param (a, id, new);
407                 changed = TRUE;
408         }
409
410         g_free (old);
411         return changed;
412 }
413
414 static gboolean gui_read (GHashTable* h, SharingAccount* a)
415 {
416         gboolean changed = FALSE;
417         if (gui_read_item (h, "username", a)) changed = TRUE;
418         if (gui_read_item (h, "password", a)) changed = TRUE;
419         if (gui_read_item (h, "urlbase", a)) changed = TRUE;
420         if (gui_read_item (h, "albumname", a)) changed = TRUE;
421         return changed;
422 }
423
424 static SharingPluginInterfaceEditAccountResult edit_account (SharingAccount* account, GtkWindow* parent, gboolean setup)
425 {
426         GHashTable* h = g_hash_table_new (g_str_hash, g_str_equal);
427
428         GtkWidget* dlg = 0;
429
430         if (setup)
431                 dlg = gtk_dialog_new_with_buttons (
432                                 "Account setup - Gallery 2", parent,
433                                 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
434                                 GTK_STOCK_OK, GTK_RESPONSE_YES,
435                                 NULL);
436         else
437                 dlg = gtk_dialog_new_with_buttons (
438                                 "Edit account - Gallery 2", parent,
439                                 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
440                                 GTK_STOCK_SAVE, GTK_RESPONSE_YES,
441                                 GTK_STOCK_DELETE, GTK_RESPONSE_NO,
442                                 NULL);
443
444         GtkWidget* dlg_content = gtk_dialog_get_content_area (GTK_DIALOG (dlg));
445
446         GtkWidget* table = gtk_table_new (4, 2, FALSE);
447         gtk_container_add (GTK_CONTAINER (dlg_content), table);
448
449         gui_add_item (table, 0, "username", "User name", "Gallery 2 account name", FALSE, account, h);
450         gui_add_item (table, 1, "password", "Password", "Gallery 2 account password", TRUE, account, h);
451         gui_add_item (table, 2, "urlbase", "URL", "Gallery 2 site address", FALSE, account, h);
452         gui_add_item (table, 3, "albumname", "Album", "Album name to upload to", FALSE, account, h);
453
454         gtk_widget_show_all (GTK_WIDGET (dlg));
455         gint result = gtk_dialog_run (GTK_DIALOG (dlg));
456
457         gboolean changed = FALSE;
458         if (result == GTK_RESPONSE_YES)
459                 changed = gui_read (h, account);
460
461         gtk_widget_destroy (dlg);
462         g_hash_table_unref (h);
463
464         if (result == GTK_RESPONSE_YES && (changed || setup))
465                 return SHARING_EDIT_ACCOUNT_SUCCESS;
466         else if (result == GTK_RESPONSE_YES) /* !changed in edit */
467                 return SHARING_EDIT_ACCOUNT_NOT_STARTED;
468         else if (result == GTK_RESPONSE_NO)
469                 return SHARING_EDIT_ACCOUNT_DELETE;
470         else
471                 return SHARING_EDIT_ACCOUNT_CANCELLED;
472 }