Move all code to a subdir for the garage repo
[g2-sharing] / src / gallery2.c
diff --git a/src/gallery2.c b/src/gallery2.c
deleted file mode 100644 (file)
index c592d3d..0000000
+++ /dev/null
@@ -1,599 +0,0 @@
-/*
- * This file is part of sharing-plugin-gallery2
- *
- * Copyright (C) 2009 Heikki Kallasjoki. All rights reserved.
- * Copyright (C) 2008-2009 Nokia Corporation. All rights reserved.
- *
- * This code is licensed under a MIT-style license, that can be
- * found in the file called "COPYING" in the root directory.
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <glib.h>
-#include <osso-log.h>
-#include <sharing-http.h>
-#include "gallery2.h"
-
-/* Helpers: */
-
-static gchar* url_encode (const gchar* source);
-
-/**
- * gallery2_login:
- * @con: Connection to use
- * @urlbase: Base URL to the Gallery 2 site
- * @username: User name
- * @password: Password
- * @cookies: Output parameter for any cookies set.
- * @auth: Output paremeter for the authentication token.
- *
- * Logs in to the Gallery 2 service.
- *
- * Returns: Validation result.
- */
-SharingPluginInterfaceAccountValidateResult
-gallery2_login (ConIcConnection* con,
-               const gchar* urlbase, const gchar* username, const gchar* password,
-               GHashTable** cookies, gchar** auth)
-{
-       SharingPluginInterfaceAccountValidateResult ret = SHARING_ACCOUNT_VALIDATE_SUCCESS;
-
-       SharingHTTP* http = sharing_http_new ();
-
-       *cookies = 0;
-       *auth = 0;
-
-       /* Do the login request */
-
-       SharingHTTPRunResponse res = 0;
-
-       {
-               gchar* euser = url_encode (username);
-               gchar* epass = url_encode (password);
-
-               gchar* url = g_strdup_printf("%s/main.php?g2_controller=remote:GalleryRemote&"
-                               "g2_form[cmd]=login&g2_form[protocol_version]=2.0&"
-                               "g2_form[uname]=%s&g2_form[password]=%s",
-                               urlbase, euser, epass);
-
-               g_free (euser);
-               g_free (epass);
-
-               sharing_http_set_connection (http, con);
-               res = sharing_http_run (http, url);
-
-               g_free (url);
-       }
-
-       /* Parse the response */
-
-       if (res == SHARING_HTTP_RUNRES_SUCCESS && sharing_http_get_res_code (http) == 200)
-       {
-               /* Split response into lines */
-
-               gchar** lines = 0;
-
-               {
-                       gsize content_len = 0;
-                       const gchar* content = sharing_http_get_res_content (http, &content_len);
-                       gchar* c = g_strndup (content, content_len); /* force \0 termination */
-                       lines = g_strsplit_set (c, "\r\n", 0);
-                       g_free (c);
-               }
-
-               /* Process the lines */
-
-               *cookies = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
-
-               gboolean in_body = FALSE;
-
-               for (gchar** p = lines; *p; p++)
-               {
-                       gchar* line = *p;
-
-                       if (!in_body)
-                       {
-                               if (g_ascii_strncasecmp (line, "Set-Cookie:", 11) == 0)
-                               {
-                                       /* Extract the key=value part of the cookie */
-
-                                       gchar** data = 0;
-
-                                       {
-                                               gchar* c = g_strchug (line+11); /* start of cookie data */
-
-                                               char* end = strchr (c, ';');
-                                               if (end) *end = 0;
-
-                                               data = g_strsplit (c, "=", 2);
-                                       }
-
-                                       if (!data[0] || !data[1])
-                                       {
-                                               /* Bad Set-Cookie: header, ignore */
-                                               g_strfreev (data);
-                                               continue;
-                                       }
-
-                                       /* Insert into our table */
-
-                                       g_hash_table_replace (*cookies, data[0], data[1]);
-                                       g_free (data); /* not g_strfreev! strings still used in "cookies" */
-
-                                       continue;
-                               }
-
-                               if (g_str_has_prefix (line, "#__GR2PROTO__"))
-                               {
-                                       in_body = TRUE;
-                                       continue;
-                               }
-                       }
-                       else
-                       {
-                               /* Split key=value into fields */
-
-                               gchar* value = strchr (line, '=');
-                               if (!value) continue;
-                               *value = 0;
-                               value++;
-
-                               /* Process the necessary parts */
-
-                               if (strcmp (line, "status") == 0 && strcmp (value, "0") != 0)
-                               {
-                                       ULOG_ERR_L ("Gallery 2 login auth failed\n");
-                                       ret = SHARING_ACCOUNT_VALIDATE_FAILED;
-                                       break;
-                               }
-
-                               if (strcmp (line, "auth_token") == 0)
-                               {
-                                       *auth = g_strdup (value);
-                                       continue;
-                               }
-                       }
-               }
-
-               g_strfreev (lines);
-       }
-       else
-       {
-               ULOG_ERR_L ("Gallery 2 login connection failed\n");
-               ret = SHARING_ACCOUNT_VALIDATE_ERROR_CONNECTION;
-       }
-
-       if (ret != SHARING_ACCOUNT_VALIDATE_SUCCESS)
-       {
-               if (*cookies) g_hash_table_unref (*cookies);
-               if (*auth) g_free (auth);
-               *cookies = 0;
-               *auth = 0;
-       }
-
-       sharing_http_unref (http);
-       return ret;
-}
-
-/**
- * gallery2_lookup_album:
- * @con: Connection to use
- * @urlbase: Base URL to the Gallery 2 site
- * @albumpath: Slash-separated path to album
- * @album: Output parameter to hold the album ID
- * @cookies: Cookies from gallery2_login.
- * @auth: Authentication token from gallery2_login.
- *
- * Retrieves the album id based on an album path.
- */
-SharingPluginInterfaceAccountValidateResult
-gallery2_lookup_album (ConIcConnection* con,
-               const gchar* urlbase, const gchar* albumpath, gchar** album,
-               GHashTable* cookies, gchar* auth)
-{
-       SharingPluginInterfaceAccountValidateResult ret = SHARING_ACCOUNT_VALIDATE_ERROR_UNKNOWN;
-
-       SharingHTTP* http = sharing_http_new ();
-
-       /* Prepare and send the request */
-
-       gchar* url = g_strdup_printf("%s/main.php?g2_controller=remote:GalleryRemote%s%s&"
-                       "g2_form[cmd]=fetch-albums-prune&g2_form[protocol_version]=2.2&g2_form[no_perms]=yes",
-                       urlbase,
-                       auth ? "&g2_authToken=" : "", auth ? auth : "");
-
-       if (cookies)
-       {
-               GHashTableIter iter;
-               gpointer key, value;
-               g_hash_table_iter_init (&iter, cookies);
-               while (g_hash_table_iter_next (&iter, &key, &value))
-               {
-                       gchar* hdr = g_strdup_printf("Cookie: %s=%s", (gchar*)key, (gchar*)value);
-                       sharing_http_add_req_header_line (http, hdr);
-                       g_free (hdr);
-               }
-       }
-
-       sharing_http_set_connection (http, con);
-       SharingHTTPRunResponse res = sharing_http_run (http, url);
-
-       g_free (url);
-       url = 0;
-
-       /* Parse the response into an album map. */
-
-       GHashTable* album_names = 0;  /* map string (display-name) -> GSList [ string (url-name) ] */
-       GHashTable* album_parent = 0; /* map string (url-name) -> string (url-name) */
-       gchar* album_root = 0;        /* root album url-name */
-       gboolean valid = FALSE;       /* true if the maps are usable */
-       char** lines = 0;             /* raw data (response lines) */
-
-       if (res == SHARING_HTTP_RUNRES_SUCCESS && sharing_http_get_res_code (http) == 200)
-       {
-               {
-                       gsize content_len = 0;
-                       const gchar* content = sharing_http_get_res_body (http, &content_len);
-                       gchar* c = g_strndup (content, content_len); /* force \0 termination */
-                       lines = g_strsplit_set (c, "\r\n", 0);
-                       g_free (c);
-               }
-
-               gboolean in_body = FALSE;
-               gchar* current_ref_num = 0;
-               gchar* current_url_name = 0;
-
-               for (gchar** p = lines; *p; p++)
-               {
-                       gchar* line = *p;
-
-                       if (!in_body)
-                       {
-                               if (g_str_has_prefix (line, "#__GR2PROTO__"))
-                               {
-                                       album_names = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify)g_slist_free);
-                                       album_parent = g_hash_table_new (g_str_hash, g_str_equal);
-                                       in_body = TRUE;
-                               }
-                               continue;
-                       }
-
-                       gchar* value = strchr (line, '=');
-                       if (!value) continue;
-                       *value = 0;
-                       value++;
-
-                       if (strcmp (line, "status") == 0)
-                       {
-                               if (strcmp (value, "0") == 0)
-                                       valid = TRUE;
-                               continue;
-                       }
-                       else if (g_str_has_prefix (line, "album.name."))
-                       {
-                               current_ref_num = line + 11;
-                               current_url_name = value;
-                       }
-                       else if (g_str_has_prefix (line, "album.title."))
-                       {
-                               if (!current_ref_num || strcmp (current_ref_num, line + 12) != 0)
-                                       continue;
-                               GSList* others = g_hash_table_lookup (album_names, value);
-                               if (others) g_hash_table_steal (album_names, value);
-                               g_hash_table_insert (album_names, value, g_slist_prepend (others, current_url_name));
-                       }
-                       else if (g_str_has_prefix (line, "album.parent."))
-                       {
-                               if (!current_ref_num || strcmp (current_ref_num, line + 13) != 0)
-                                       continue;
-                               g_hash_table_insert (album_parent, current_url_name, value);
-                               if (strcmp (value, "0") == 0)
-                                       album_root = current_url_name;
-                       }
-               }
-       }
-       else
-               ret = SHARING_ACCOUNT_VALIDATE_ERROR_CONNECTION;
-
-       sharing_http_unref (http);
-
-       /* Find the album we are interested in. */
-
-       *album = 0;
-
-       if (album_names && album_parent && album_root && valid)
-       {
-               gchar* current_album = album_root;
-               gboolean seen_parents = FALSE; /* for the root special case */
-               gboolean found_final = FALSE;  /* to make sure the last real component is found */
-
-               gchar** components = g_strsplit (albumpath, "/", 0);
-
-               for (gchar** p = components; *p; p++)
-               {
-                       if (!**p) continue; /* ignore empty path components */
-                       found_final = FALSE; /* this component needs to be found */
-                       GSList* candidates = g_hash_table_lookup (album_names, *p);
-                       /* bad case: no candidates at all */
-                       if (!candidates) break;
-                       /* special case 1: if only one candidate and no unseen parents, choose that */
-                       if (!seen_parents && !g_slist_next (candidates))
-                       {
-                               found_final = TRUE;
-                               current_album = candidates->data;
-                               continue;
-                       }
-                       /* general case: find a candidate with an acceptable parent */
-                       while (candidates)
-                       {
-                               gchar* parent = g_hash_table_lookup (album_parent, candidates->data);
-                               /* suitable parents: current_album, or (if no specified parents) null or 0 (explicit root case) */
-                               if ((parent && strcmp (parent, current_album) == 0)
-                                               || (!seen_parents && (!parent || strcmp (parent, "0") == 0)))
-                               {
-                                       found_final = TRUE;
-                                       current_album = candidates->data;
-                                       break;
-                               }
-                               candidates = g_slist_next (candidates); /* try next */
-                       }
-               }
-
-               g_strfreev (components);
-
-               if (found_final)
-               {
-                       *album = g_strdup(current_album);
-                       ret = SHARING_ACCOUNT_VALIDATE_SUCCESS;
-               }
-       }
-
-       if (album_names) g_hash_table_unref (album_names);
-       if (album_parent) g_hash_table_unref (album_parent);
-       g_strfreev (lines);
-
-       return ret;
-}
-
-/* gallery2_send callback helper declarations */
-
-struct gallery2_send_record
-{
-       SharingTransfer* transfer;
-       gdouble progress_start;
-       gdouble progress_end;
-       guint64 media_bytes;
-       gboolean* dms;
-};
-
-gboolean gallery2_send_callback (SharingHTTP* http, guint64 bytes_sent, gpointer user_data);
-
-/**
- * gallery2_send:
- * @con: Connection to use
- * @transfer: Sharing transfer object
- * @progress_start: Initial state of progress meter
- * @progress_end: Desired final state of progress meter
- * @dms: Dead man's switch
- * @media: Media item to send
- * @urlbase: Base URL to the Gallery 2 site
- * @album: Album ID from gallery2_lookup_album.
- * @cookies: Cookies from gallery2_login.
- * @auth: Authentication token from gallery2_login.
- *
- * Sends a media item to a Gallery 2 service.
- *
- * Returns: Send result.
- */
-SharingPluginInterfaceSendResult
-gallery2_send (ConIcConnection* con,
-               SharingTransfer* transfer, gdouble progress_start, gdouble progress_end, gboolean *dms,
-               SharingEntryMedia* media,
-               const gchar* urlbase, const gchar* album, GHashTable* cookies, gchar* auth)
-{
-       struct gallery2_send_record rec = {
-               .transfer = transfer,
-               .progress_start = progress_start,
-               .progress_end = progress_end,
-               .media_bytes = 0,
-               .dms = dms
-       };
-
-       SharingPluginInterfaceSendResult ret = SHARING_SEND_SUCCESS;
-
-       SharingHTTP* http = sharing_http_new ();
-
-       /* Prepare and send the request */
-
-       gchar* media_title = sharing_entry_media_get_title (media);
-       gchar* media_mime = sharing_entry_media_get_mime (media);
-       gchar* media_filename = sharing_entry_media_get_filename (media);
-
-       const gchar* desc = sharing_entry_media_get_desc (media);
-
-       const gchar* title = media_title;
-       if (!title || !*title) title = media_filename;
-       if (!title || !*title) title = "(unknown)";
-
-       gchar* url = 0;
-
-       {
-               gchar* edesc = (desc && *desc ? url_encode (desc) : 0);
-               gchar* etitle = url_encode (title);
-               url = g_strdup_printf("%s/main.php?g2_controller=remote:GalleryRemote%s%s&"
-                               "g2_form[cmd]=add-item&g2_form[protocol_version]=2.0&"
-                               "g2_form[set_albumName]=%s&g2_form[caption]=%s"
-                               "%s%s%s%s",
-                               urlbase,
-                               auth ? "&g2_authToken=" : "", auth ? auth : "",
-                               album, etitle,
-                               edesc ? "&g2_form[extrafield.Summary]=" : "", edesc ? edesc : "",
-                               edesc ? "&g2_form[extrafield.Description]=" : "", edesc ? edesc : "");
-               g_free (etitle);
-               g_free (edesc);
-       }
-
-       if (cookies)
-       {
-               GHashTableIter iter;
-               gpointer key, value;
-               g_hash_table_iter_init (&iter, cookies);
-               while (g_hash_table_iter_next (&iter, &key, &value))
-               {
-                       gchar* hdr = g_strdup_printf("Cookie: %s=%s", (gchar*)key, (gchar*)value);
-                       sharing_http_add_req_header_line (http, hdr);
-                       g_free (hdr);
-               }
-       }
-
-       sharing_http_add_req_multipart_file_with_filename (http,
-               "g2_userfile",
-               sharing_entry_media_get_localpath (media),
-               media_mime ? media_mime : "image/jpeg",
-               media_filename ? media_filename : "unknown.jpg");
-
-       g_free (media_title);
-       g_free (media_mime);
-       g_free (media_filename);
-
-       media_title = media_mime = media_filename = 0;
-
-       rec.media_bytes = sharing_entry_media_get_size (media);
-       sharing_http_set_progress_callback (http, gallery2_send_callback, &rec);
-
-       *dms = FALSE;
-       sharing_http_set_connection (http, con);
-       SharingHTTPRunResponse res = sharing_http_run (http, url);
-       *dms = FALSE;
-
-       g_free (url);
-       url = 0;
-
-       /* Parse the response */
-
-       if (res == SHARING_HTTP_RUNRES_SUCCESS && sharing_http_get_res_code (http) == 200)
-       {
-               gchar** lines = 0;
-
-               {
-                       gsize content_len = 0;
-                       const gchar* content = sharing_http_get_res_body (http, &content_len);
-                       gchar* c = g_strndup (content, content_len); /* force \0 termination */
-                       lines = g_strsplit_set (c, "\r\n", 0);
-                       g_free (c);
-               }
-
-               gboolean in_body = FALSE;
-               ret = SHARING_SEND_ERROR_UNKNOWN;
-
-               for (gchar** p = lines; *p; p++)
-               {
-                       gchar* line = *p;
-
-                       if (!in_body)
-                       {
-                               if (g_str_has_prefix (line, "#__GR2PROTO__"))
-                                       in_body = TRUE;
-                               continue;
-                       }
-
-                       gchar* value = strchr (line, '=');
-                       if (!value) continue;
-                       *value = 0;
-                       value++;
-
-                       if (strcmp (line, "status") == 0)
-                       {
-                               if (strcmp (value, "0") == 0)
-                                       ret = SHARING_SEND_SUCCESS;
-                               break;
-                       }
-               }
-
-               g_strfreev (lines);
-       }
-       else if (res == SHARING_HTTP_RUNRES_CANCELLED)
-               ret = SHARING_SEND_CANCELLED;
-       else
-               ret = SHARING_SEND_ERROR_CONNECTION;
-
-       sharing_http_unref (http);
-
-       *dms = FALSE;
-       sharing_transfer_set_progress (transfer, progress_end);
-
-       return ret;
-}
-
-/* gallery2_send callback implementation */
-
-gboolean gallery2_send_callback (SharingHTTP* http, guint64 bytes_sent, gpointer user_data)
-{
-       struct gallery2_send_record* rec = user_data;
-
-       if (!sharing_transfer_continue (rec->transfer))
-               return FALSE;
-
-       *rec->dms = FALSE;
-
-       gdouble progress = (rec->progress_start + rec->progress_end) / 2.0;
-
-       if (rec->media_bytes)
-       {
-               if (bytes_sent >= rec->media_bytes)
-                       progress = rec->progress_end;
-               else
-                       progress = rec->progress_start + (bytes_sent / (gdouble)rec->media_bytes) * (rec->progress_end - rec->progress_start);
-       }
-
-       sharing_transfer_set_progress (rec->transfer, progress);
-
-       return TRUE;
-}
-
-/* Helper implementations */
-
-static gchar url_encode_hex[16] = {
-       '0', '1', '2', '3', '4', '5', '6', '7',
-       '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
-};
-
-static gchar* url_encode (const gchar* source)
-{
-       gchar* dest = 0;
-       gsize dest_len = 0;
-       const gchar* s;
-       gchar* d;
-
-       /* Count new string length */
-
-       for (s = source; *s; s++)
-       {
-               dest_len++;
-               if (!((*s >= '0' && *s <= '9') || (*s >= 'A' && *s <= 'Z') || (*s >= 'a' && *s <= 'z')))
-                       dest_len += 2;
-       }
-
-       /* Build encoded string */
-
-       dest = g_malloc (dest_len + 1);
-
-       for (s = source, d = dest; *s; s++)
-       {
-               if ((*s >= '0' && *s <= '9') || (*s >= 'A' && *s <= 'Z') || (*s >= 'a' && *s <= 'z'))
-                       *d++ = *s;
-               else if (*s == ' ')
-                       *d++ = '+';
-               else
-               {
-                       *d++ = '%';
-                       *d++ = url_encode_hex[(*s >> 4) & 0xf];
-                       *d++ = url_encode_hex[*s & 0xf];
-               }
-       }
-
-       *d = 0;
-       return dest;
-}