Author: akv
Date: 2010-05-31 23:20:26 +0200 (Mon, 31 May 2010)
New Revision: 3413

Added:
   trunk/plugins/output-picasa/
   trunk/plugins/output-picasa/Makefile.am
   trunk/plugins/output-picasa/output-picasa.c
   trunk/plugins/output-picasa/picasa-logo.svg
   trunk/plugins/output-picasa/picasa-logo.svg_original
   trunk/plugins/output-picasa/rs-picasa-client.c
   trunk/plugins/output-picasa/rs-picasa-client.h
Log:
Initial add of picasa plugin - needs a bit og errorhandling.

Added: trunk/plugins/output-picasa/Makefile.am
===================================================================
--- trunk/plugins/output-picasa/Makefile.am                             (rev 0)
+++ trunk/plugins/output-picasa/Makefile.am     2010-05-31 21:20:26 UTC (rev 
3413)
@@ -0,0 +1,26 @@
+plugindir = $(libdir)
+
+AM_CFLAGS =\
+       -Wall\
+       -O4
+
+AM_CXXFLAGS = $(AM_CFLAGS)
+
+INCLUDES = \
+       -DPACKAGE_DATA_DIR=\""$(datadir)"\" \
+       -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
+       @PACKAGE_CFLAGS@ \
+       -I$(top_srcdir)/librawstudio/ \
+       -I$(top_srcdir)/
+
+lib_LTLIBRARIES = output_picasa.la
+
+libdir = $(datadir)/rawstudio/plugins/
+
+output_picasa_la_LIBADD = @PACKAGE_LIBS@ 
+output_picasa_la_LDFLAGS = -module -avoid-version -L/usr/lib
+output_picasa_la_SOURCES = output-picasa.c rs-picasa-client.c 
rs-picasa-client.h
+
+plugin_DATA = picasa-logo.svg
+
+EXTRA_DIST = $(plugin_DATA)
\ No newline at end of file

Added: trunk/plugins/output-picasa/output-picasa.c
===================================================================
--- trunk/plugins/output-picasa/output-picasa.c                         (rev 0)
+++ trunk/plugins/output-picasa/output-picasa.c 2010-05-31 21:20:26 UTC (rev 
3413)
@@ -0,0 +1,299 @@
+/*
+ * * Copyright (C) 2006-2010 Anders Brander <[email protected]>, 
+ * * Anders Kvist <[email protected]> and Klaus Post <[email protected]>
+ *
+ * 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  02110-1301, 
USA.
+ */
+
+/* Output plugin tmpl version 1 */
+
+#include <rawstudio.h>
+#include <gettext.h>
+#include "config.h"
+#include <unistd.h>
+#include <string.h>
+#include "rs-picasa-client.h"
+#include <conf_interface.h>
+
+#define RS_TYPE_PICASA (rs_picasa_type)
+#define RS_PICASA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), RS_TYPE_PICASA, 
RSPicasa))
+#define RS_PICASA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), 
RS_TYPE_PICASA, RSPicasaClass))
+#define RS_IS_PICASA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), RS_TYPE_PICASA))
+
+typedef struct _RSPicasa RSPicasa;
+typedef struct _RSPicasaClass RSPicasaClass;
+
+struct _RSPicasa
+{
+       RSOutput parent;
+        gchar *album_id;
+       gint quality;
+};
+
+struct _RSPicasaClass
+{
+       RSOutputClass parent_class;
+};
+
+typedef struct 
+{
+        PicasaClient *picasa_client;
+        GtkEntry *entry;
+        GtkComboBox *combobox;
+} CreateAlbumData;
+
+RS_DEFINE_OUTPUT (rs_picasa, RSPicasa)
+enum
+{
+       PROP_0,
+       PROP_LOGO,
+       PROP_JPEG_QUALITY,
+        PROP_ALBUM_SELECTOR
+};
+
+static void get_property (GObject * object, guint property_id, GValue * value, 
GParamSpec * pspec);
+static void set_property (GObject * object, guint property_id, const GValue * 
value, GParamSpec * pspec);
+static gboolean execute (RSOutput * output, RSFilter * filter);
+GtkWidget * get_album_selector_widget(RSPicasa *picasa);
+GtkWidget * get_logo_widget(RSPicasa *picasa);
+
+G_MODULE_EXPORT void rs_plugin_load (RSPlugin * plugin)
+{
+       rs_picasa_get_type (G_TYPE_MODULE (plugin));
+}
+
+static void
+rs_picasa_class_init (RSPicasaClass * klass)
+{
+       RSOutputClass *output_class = RS_OUTPUT_CLASS (klass);
+       GObjectClass *object_class = G_OBJECT_CLASS (klass);
+       
+       object_class->get_property = get_property;
+       object_class->set_property = set_property;
+
+       g_object_class_install_property (object_class,
+                                        PROP_JPEG_QUALITY,
+                                        g_param_spec_int ("quality",
+                                                          "JPEG Quality",
+                                                          _("JPEG Quality"), 
10,
+                                                          100, 90,
+                                                          G_PARAM_READWRITE));
+
+       g_object_class_install_property (object_class,
+                                        PROP_LOGO, g_param_spec_object ("Logo",
+                                                                               
   "logo",
+                                                                               
   "Logo",
+                                                                               
   GTK_TYPE_WIDGET,
+                                                                               
   G_PARAM_READABLE));
+
+        g_object_class_install_property (object_class,
+                                         PROP_ALBUM_SELECTOR, 
g_param_spec_object ("album selector",
+                                                                               
    "album selector",
+                                                                               
    "Album selector",
+                                                                               
    GTK_TYPE_WIDGET,
+                                                                               
    G_PARAM_READABLE));
+
+       output_class->execute = execute;
+       output_class->display_name = _("Upload photo to Picasa");
+}
+
+static void
+rs_picasa_init (RSPicasa * picasa)
+{
+       picasa->quality = 90;
+}
+
+static void
+get_property (GObject * object, guint property_id, GValue * value, GParamSpec 
* pspec)
+{
+       RSPicasa *picasa = RS_PICASA (object);
+
+       switch (property_id)
+       {
+       case PROP_JPEG_QUALITY:
+               g_value_set_int (value, picasa->quality);
+               break;
+       case PROP_LOGO:
+               g_value_set_object(value, get_logo_widget(picasa));
+               break;
+        case PROP_ALBUM_SELECTOR:
+                g_value_set_object(value, get_album_selector_widget(picasa));
+                break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+       }
+}
+
+static void
+set_property (GObject * object, guint property_id, const GValue * value, 
GParamSpec * pspec)
+{
+       RSPicasa *picasa = RS_PICASA (object);
+
+       switch (property_id)
+       {
+       case PROP_JPEG_QUALITY:
+               picasa->quality = g_value_get_int (value);
+               break;
+       default:
+               G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+       }
+}
+
+void
+combobox_cell_text(GtkComboBox *combo, gint col)
+{
+        GtkCellRenderer *rend = gtk_cell_renderer_text_new ();
+        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), rend, TRUE);
+        gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), rend, "text", 
col);
+}
+
+static void
+album_set_active(GtkComboBox *combo, gchar *aid)
+{
+        GtkTreeModel *model = gtk_combo_box_get_model(combo);
+        GtkTreeIter iter;
+        gchar *album_id;
+
+        if (model && gtk_tree_model_get_iter_first(model, &iter))
+                do
+                {
+                        gtk_tree_model_get(model, &iter,
+                                           1, &album_id,
+                                           -1);
+
+                        if (g_strcmp0(aid, album_id) == 0)
+                        {
+                                gtk_combo_box_set_active_iter(combo, &iter);
+                                g_free(album_id);
+                                return;
+                        }
+                        g_free(album_id);
+                }
+                while (gtk_tree_model_iter_next(model, &iter));
+}
+
+static void
+album_changed(GtkComboBox *combo, gpointer callback_data)
+{
+        RSPicasa *picasa = callback_data;
+        GtkTreeIter iter;
+        GtkTreeModel *model;
+        gchar *album, *aid;
+
+        gtk_combo_box_get_active_iter(GTK_COMBO_BOX(combo), &iter);
+        model = gtk_combo_box_get_model(GTK_COMBO_BOX(combo));
+        gtk_tree_model_get(model, &iter,
+                           0, &album,
+                           1, &aid,
+                           -1);
+
+        picasa->album_id = aid;
+        rs_conf_set_string(CONF_PICASA_CLIENT_ALBUM_ID, aid);
+
+        return;
+}
+
+static void
+create_album(GtkButton *button, gpointer callback_data)
+{
+        CreateAlbumData *create_album_data = callback_data;
+        PicasaClient *picasa_client = create_album_data->picasa_client;
+        GtkEntry *entry = create_album_data->entry;
+        GtkComboBox *combobox = create_album_data->combobox;
+        const gchar *album_name = gtk_entry_get_text(entry);
+
+       gchar *aid = rs_picasa_client_create_album(picasa_client, album_name);
+
+        if (aid)
+        {
+                GtkListStore *albums = 
rs_picasa_client_get_album_list(picasa_client);
+                gtk_combo_box_set_model(combobox, GTK_TREE_MODEL(albums));
+                album_set_active(combobox, aid);
+                gtk_entry_set_text(entry, "");
+        }
+}
+
+GtkWidget *
+get_album_selector_widget(RSPicasa *picasa)
+{
+        GError *error = NULL;
+        gchar *album_id = rs_conf_get_string(CONF_PICASA_CLIENT_ALBUM_ID);
+
+        CreateAlbumData *create_album_data = g_malloc(sizeof(CreateAlbumData));
+
+       PicasaClient *picasa_client = rs_picasa_client_init();
+
+        GtkListStore *albums = rs_picasa_client_get_album_list(picasa_client);
+        GtkWidget *combobox = gtk_combo_box_new();
+        combobox_cell_text(GTK_COMBO_BOX(combobox), 0);
+        gtk_combo_box_set_model(GTK_COMBO_BOX(combobox), 
GTK_TREE_MODEL(albums));
+        album_set_active(GTK_COMBO_BOX(combobox), album_id);
+       picasa->album_id = album_id;
+
+        g_signal_connect ((gpointer) combobox, "changed", G_CALLBACK 
(album_changed), picasa);
+
+        GtkWidget *box = gtk_hbox_new(FALSE, 2);
+        GtkWidget *label = gtk_label_new(_("Albums"));
+        GtkWidget *sep = gtk_vseparator_new();
+        GtkWidget *entry = gtk_entry_new();
+        GtkWidget *button = gtk_button_new_with_label(_("Create album"));
+        gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 2);
+        gtk_box_pack_start (GTK_BOX (box), combobox, FALSE, FALSE, 2);
+        gtk_box_pack_start (GTK_BOX (box), sep, FALSE, FALSE, 2);
+        gtk_box_pack_start (GTK_BOX (box), entry, FALSE, FALSE, 2);
+        gtk_box_pack_start (GTK_BOX (box), button, FALSE, FALSE, 2);
+
+        create_album_data->picasa_client = picasa_client;
+        create_album_data->entry = GTK_ENTRY(entry);
+        create_album_data->combobox = GTK_COMBO_BOX(combobox);
+
+        g_signal_connect ((gpointer) button, "clicked", G_CALLBACK 
(create_album), create_album_data);
+
+       return box;
+}
+
+static gboolean
+execute (RSOutput * output, RSFilter * filter)
+{
+       RSPicasa *picasa = RS_PICASA (output);
+       RSOutput *jpegsave = rs_output_new ("RSJpegfile");
+
+       PicasaClient *picasa_client = rs_picasa_client_init();
+
+       gchar *temp_file = g_strdup_printf ("%s%s.rawstudio-tmp-%d.jpg", 
g_get_tmp_dir (), G_DIR_SEPARATOR_S, (gint) (g_random_double () * 10000.0));
+
+       g_object_set (jpegsave, "filename", temp_file, "quality", 
picasa->quality, NULL);
+       rs_output_execute (jpegsave, filter);
+       g_object_unref (jpegsave);
+
+       gboolean ret = rs_picasa_client_upload_photo(picasa_client, temp_file, 
picasa->album_id);
+
+       unlink (temp_file);
+       g_free (temp_file);
+
+       return TRUE;
+}
+
+GtkWidget *
+get_logo_widget(RSPicasa *picasa)
+{
+       gchar *filename = g_build_filename(PACKAGE_DATA_DIR, PACKAGE, 
"/plugins/picasa-logo.svg", NULL);
+       GtkWidget *box = gtk_vbox_new(TRUE, 2);
+       GtkWidget *logo = gtk_image_new_from_file(filename);
+       g_free(filename);
+
+       gtk_box_pack_start (GTK_BOX (box), logo, FALSE, FALSE, 2);
+       return box;
+}

Added: trunk/plugins/output-picasa/picasa-logo.svg
===================================================================
--- trunk/plugins/output-picasa/picasa-logo.svg                         (rev 0)
+++ trunk/plugins/output-picasa/picasa-logo.svg 2010-05-31 21:20:26 UTC (rev 
3413)
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   width="375.00000pt"
+   height="150.00000pt"
+   id="svg1392"
+   sodipodi:version="0.32"
+   inkscape:version="0.47 r22583"
+   sodipodi:docname="picasa-logo.svg"
+   version="1.1">
+  <defs
+     id="defs3">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 93.75 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="468.75 : 93.75 : 1"
+       inkscape:persp3d-origin="234.375 : 62.5 : 1"
+       id="perspective15" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.35"
+     inkscape:cx="-133.57143"
+     inkscape:cy="405.71429"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="1104"
+     inkscape:window-height="724"
+     inkscape:window-x="0"
+     inkscape:window-y="25"
+     showgrid="false"
+     inkscape:window-maximized="0" />
+  <metadata
+     id="metadata4">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <path
+       d="M 118.69106,26.902170 C 109.62228,22.800310 100.02337,20.679610 
90.078429,20.679610 C 81.804939,20.679610 73.670979,22.270130 
65.849529,25.227940 C 65.849529,25.227940 118.69106,73.166740 
118.69106,73.166740 C 118.69106,73.166740 118.69106,26.902170 
118.69106,26.902170 z "
+       class="ps05 ps10 ps21"
+       id="path1199"
+       style="fill:#fa0b0b;fill-opacity:1.0000000" />
+    <path
+       d="M 54.367109,149.34422 C 54.367109,149.34422 54.367109,89.685810 
54.367109,89.685810 C 54.367109,89.685810 25.698689,115.74798 
25.698689,115.74798 C 31.254359,129.67201 41.405759,141.50323 
54.367109,149.34422 z "
+       class="ps06 ps10 ps21"
+       id="path1201"
+       style="fill:#5a55b8;fill-opacity:1.0000000" />
+    <path
+       d="M 20.692739,90.076470 C 20.692739,96.047900 21.591259,102.10304 
23.212469,108.10233 C 23.212469,108.10233 84.723679,52.210960 
84.723679,52.210960 C 84.723679,52.210960 58.457799,28.381070 
58.457799,28.381070 C 35.158089,40.351820 20.692739,63.902670 
20.692739,90.076470 z "
+       class="ps07 ps10 ps21"
+       id="path1203"
+       style="fill:#9e5cb9;fill-opacity:1.0000000" />
+    <path
+       d="M 61.655579,120.24051 C 61.655579,120.24051 61.655579,153.33447 
61.655579,153.33447 C 70.676899,157.40844 80.225589,159.47332 
90.078429,159.47332 C 116.54246,159.47332 140.84668,144.07038 
152.39886,120.24051 C 152.39886,120.24051 61.655579,120.24051 
61.655579,120.24051 z "
+       class="ps08 ps10 ps21"
+       id="path1205"
+       style="fill:#3ca335;fill-opacity:1.0000000" />
+    <path
+       d="M 126.00184,30.892420 C 126.00184,30.892420 126.00184,112.92970 
126.00184,112.92970 C 126.00184,112.92970 155.52410,112.92970 
155.52410,112.92970 C 158.11916,105.53520 159.48644,97.861650 
159.48644,90.076470 C 159.48644,65.967550 146.65068,43.449150 
126.00184,30.892420 z "
+       class="ps09 ps10 ps21"
+       id="path1207"
+       style="fill:#e9881c;fill-opacity:1.0000000" />
+    <path
+       d="M 410.53734,144.15411 C 401.71972,144.15411 394.79958,136.42474 
394.79958,127.04904 C 394.79958,117.47803 401.71972,109.66495 
410.53734,109.66495 C 419.18754,109.66495 426.47045,117.47803 
426.47045,127.04904 C 426.47045,136.42474 419.18754,144.15411 
410.53734,144.15411 z M 434.19980,106.00957 C 434.19980,103.94469 
432.52556,102.27045 430.48861,102.27045 C 428.42371,102.27045 
426.74949,103.94469 426.74949,106.00957 C 426.74949,106.03748 
426.74949,106.03748 426.74949,106.06538 C 426.74949,106.06538 
426.74949,106.06538 426.74949,106.06538 C 426.74949,106.06538 
426.74949,110.94853 426.74949,110.94853 C 423.45682,106.20490 
417.45750,102.29837 410.53734,102.29837 C 397.08771,102.29837 
387.07021,113.40406 387.07021,126.96533 C 387.07021,140.49869 
397.08771,151.52073 410.53734,151.52073 C 417.45750,151.52073 
423.45682,147.61418 426.74949,142.78680 C 426.74949,142.78680 
426.74949,147.69789 426.74949,147.69789 C 426.74949,147.69789 
426.74949,147.69789 426.74949,147.69789 C 426.74949,149.76277 
428.42371,151.43700 430.48861,151.43700 C 432.52556,151.43700 
434.19980,149.76277 434.19980,147.69789 C 434.19980,147.69789 
434.19980,106.06538 434.19980,106.06538 C 434.19980,106.06538 
434.19980,106.06538 434.19980,106.06538 C 434.19980,106.03748 
434.19980,106.03748 434.19980,106.00957 z M 314.65975,144.15411 C 
305.81424,144.15411 298.89407,136.42474 298.89407,127.04904 C 
298.89407,117.47803 305.81424,109.66495 314.65975,109.66495 C 
323.28205,109.66495 330.56494,117.47803 330.56494,127.04904 C 
330.56494,136.42474 323.28205,144.15411 314.65975,144.15411 z M 
334.58309,102.27045 C 332.51820,102.27045 330.84396,103.94469 
330.84396,106.00957 C 330.84396,106.03748 330.87186,106.03748 
330.87186,106.06538 C 330.87186,106.06538 330.84396,106.06538 
330.84396,106.06538 C 330.84396,106.06538 330.84396,110.94853 
330.84396,110.94853 C 327.57921,106.20490 321.57989,102.29837 
314.65975,102.29837 C 301.18218,102.29837 291.19262,113.40406 
291.19262,126.96533 C 291.19262,140.49869 301.18218,151.52073 
314.65975,151.52073 C 321.57989,151.52073 327.57921,147.61418 
330.84396,142.78680 C 330.84396,142.78680 330.84396,147.69789 
330.84396,147.69789 C 330.84396,147.69789 330.84396,147.69789 
330.84396,147.69789 C 330.84396,149.76277 332.51820,151.43700 
334.58309,151.43700 C 336.64797,151.43700 338.32221,149.76277 
338.32221,147.69789 C 338.32221,147.69789 338.32221,106.06538 
338.32221,106.06538 C 338.32221,106.06538 338.29431,106.06538 
338.29431,106.06538 C 338.29431,106.03748 338.32221,106.03748 
338.32221,106.00957 C 338.32221,103.94469 336.64797,102.27045 
334.58309,102.27045 z M 234.26877,89.881140 C 232.14808,89.881140 
230.41804,91.611180 230.41804,93.759780 C 230.41804,95.880470 
232.14808,97.610520 234.26877,97.610520 C 236.41737,97.610520 
238.14741,95.880470 238.14741,93.759780 C 238.14741,91.611180 
236.41737,89.881140 234.26877,89.881140 z M 234.26877,102.27045 C 
232.14808,102.27045 230.41804,104.00050 230.41804,106.14909 C 
230.41804,106.17700 230.41804,106.17700 230.41804,106.20490 C 
230.41804,106.20490 230.41804,106.20490 230.41804,106.20490 C 
230.41804,106.20490 230.41804,147.53046 230.41804,147.53046 C 
230.41804,147.53046 230.41804,147.53046 230.41804,147.53046 C 
230.41804,147.53046 230.41804,147.55837 230.41804,147.55837 C 
230.41804,149.67907 232.14808,151.40910 234.26877,151.40910 C 
236.41737,151.40910 238.14741,149.67907 238.14741,147.55837 C 
238.14741,147.55837 238.14741,147.53046 238.14741,147.53046 C 
238.14741,147.53046 238.14741,147.53046 238.14741,147.53046 C 
238.14741,147.53046 238.14741,106.20490 238.14741,106.20490 C 
238.14741,106.20490 238.11951,106.20490 238.11951,106.20490 C 
238.11951,106.17700 238.14741,106.17700 238.14741,106.14909 C 
238.14741,104.00050 236.41737,102.27045 234.26877,102.27045 z M 
365.33313,121.94264 C 356.15275,120.49164 353.50189,119.31968 
353.50189,115.94332 C 353.50189,112.31581 357.96651,109.38592 
364.16116,109.38592 C 369.88146,109.38592 374.34606,111.95306 
375.43432,116.94785 C 375.43432,116.94785 375.46224,116.94785 
375.46224,116.94785 C 375.93659,118.53838 377.38760,119.71033 
379.14553,119.71033 C 381.26620,119.71033 383.02417,117.98030 
383.02417,115.83170 C 383.02417,115.44105 382.94044,115.07830 
382.82884,114.71555 C 380.93137,106.93037 374.03914,102.29837 
364.16116,102.29837 C 351.60444,102.29837 345.77254,109.46962 
345.77254,116.22235 C 345.77254,125.03996 352.69269,127.77454 
364.04955,129.42087 C 375.51803,130.95558 376.80160,133.41112 
376.80160,136.70377 C 376.80160,140.77774 372.33698,144.32152 
365.05409,144.32152 C 358.44088,144.32152 353.11125,141.05677 
352.02298,135.72714 C 351.68815,133.94129 350.12553,132.57401 
348.22807,132.57401 C 346.07948,132.57401 344.34944,134.30404 
344.34944,136.42474 C 344.34944,136.70377 344.37732,136.95491 
344.43315,137.20604 C 344.43315,137.20604 344.43315,137.20604 
344.43315,137.20604 C 346.38641,146.10737 354.36691,151.52073 
365.05409,151.52073 C 376.24354,151.52073 384.25193,145.60510 
384.25193,136.22941 C 384.25193,125.59804 375.71336,123.58896 
365.33313,121.94264 z M 267.05579,109.66495 C 273.13883,109.66495 
277.96619,112.84598 280.61705,117.92448 C 281.28675,119.04064 
282.48663,119.79405 283.88181,119.79405 C 286.00250,119.79405 
287.73254,118.09191 287.73254,115.99913 C 287.73254,115.32943 
287.53720,114.74345 287.25818,114.21328 C 287.25818,114.18537 
287.25818,114.15746 287.25818,114.12956 C 283.35164,106.84667 
276.04082,102.29837 267.05579,102.29837 C 254.13631,102.29837 
243.58865,113.40406 243.58865,126.96533 C 243.58865,140.49869 
254.13631,151.43700 267.05579,151.43700 C 276.04082,151.43700 
283.40744,146.86077 287.28606,139.60577 C 287.28606,139.57787 
287.28606,139.54997 287.28606,139.52206 C 287.56512,138.99189 
287.73254,138.40591 287.73254,137.79202 C 287.73254,135.67133 
286.00250,133.96919 283.88181,133.96919 C 282.51450,133.96919 
281.34256,134.69469 280.67287,135.75504 C 280.64496,135.75504 
280.64496,135.75504 280.64496,135.75504 C 278.10571,140.86144 
273.25045,144.04249 267.05579,144.04249 C 258.43349,144.04249 
251.31802,136.42474 251.31802,126.96533 C 251.31802,117.47803 
258.43349,109.66495 267.05579,109.66495 z M 205.10926,118.03610 C 
205.10926,118.03610 186.27417,118.03610 186.27417,118.03610 C 
186.27417,118.03610 186.27417,94.568990 186.27417,94.568990 C 
186.27417,94.568990 205.10926,94.568990 205.10926,94.568990 C 
212.47588,94.568990 217.74970,98.029070 217.74970,106.28862 C 
217.74970,114.57603 212.47588,118.03610 205.10926,118.03610 z M 
205.10926,87.202380 C 205.10926,87.202380 178.51687,87.202380 
178.51687,87.202380 C 178.51687,87.202380 178.51687,147.53046 
178.51687,147.53046 C 178.51687,147.53046 178.51687,147.53046 
178.51687,147.53046 C 178.51687,147.53046 178.51687,147.55837 
178.51687,147.55837 C 178.51687,149.67907 180.24690,151.40910 
182.39552,151.40910 C 184.54413,151.40910 186.27417,149.67907 
186.27417,147.55837 C 186.27417,147.55837 186.24625,147.53046 
186.24625,147.53046 C 186.24625,147.53046 186.27417,147.53046 
186.27417,147.53046 C 186.27417,147.53046 186.27417,125.40271 
186.27417,125.40271 C 186.27417,125.40271 205.10926,125.40271 
205.10926,125.40271 C 218.11245,125.40271 225.39536,117.39431 
225.39536,106.28862 C 225.39536,95.099160 218.11245,87.202380 
205.10926,87.202380 z "
+       class="ps010 ps10 ps21"
+       id="path1209"
+       style="fill:#dddddd;fill-opacity:1" />
+    <path
+       d="M 443.12902,151.29749 C 443.12902,151.29749 443.12902,145.13074 
443.12902,145.13074 C 443.12902,145.13074 441.14784,145.13074 
441.14784,145.13074 C 441.14784,145.13074 441.14784,144.37734 
441.14784,144.37734 C 441.14784,144.37734 445.94729,144.37734 
445.94729,144.37734 C 445.94729,144.37734 445.94729,145.13074 
445.94729,145.13074 C 445.94729,145.13074 443.99403,145.13074 
443.99403,145.13074 C 443.99403,145.13074 443.99403,151.29749 
443.99403,151.29749 C 443.99403,151.29749 443.12902,151.29749 
443.12902,151.29749 z "
+       class="ps010 ps10 ps21"
+       id="path1211" />
+    <path
+       d="M 447.62154,151.29749 C 447.62154,151.29749 446.89604,151.29749 
446.89604,151.29749 C 446.89604,151.29749 446.89604,144.37734 
446.89604,144.37734 C 446.89604,144.37734 448.17962,144.37734 
448.17962,144.37734 C 448.17962,144.37734 450.27240,149.93021 
450.27240,149.93021 C 450.27240,149.93021 452.30940,144.37734 
452.30940,144.37734 C 452.30940,144.37734 453.59296,144.37734 
453.59296,144.37734 C 453.59296,144.37734 453.59296,151.29749 
453.59296,151.29749 C 453.59296,151.29749 452.72792,151.29749 
452.72792,151.29749 C 452.72792,151.29749 452.72792,145.27025 
452.72792,145.27025 C 452.72792,145.27025 452.67213,145.27025 
452.67213,145.27025 C 452.67213,145.27025 450.49565,151.29749 
450.49565,151.29749 C 450.49565,151.29749 449.90965,151.29749 
449.90965,151.29749 C 449.90965,151.29749 447.64943,145.27025 
447.64943,145.27025 C 447.64943,145.27025 447.62154,145.27025 
447.62154,145.27025 C 447.62154,145.27025 447.62154,151.29749 
447.62154,151.29749 z "
+       class="ps010 ps10 ps21"
+       id="path1213" />
+  </g>
+</svg>

Added: trunk/plugins/output-picasa/picasa-logo.svg_original
===================================================================
--- trunk/plugins/output-picasa/picasa-logo.svg_original                        
        (rev 0)
+++ trunk/plugins/output-picasa/picasa-logo.svg_original        2010-05-31 
21:20:26 UTC (rev 3413)
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://web.resource.org/cc/";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   width="375.00000pt"
+   height="150.00000pt"
+   id="svg1392"
+   sodipodi:version="0.32"
+   inkscape:version="0.40+cvs"
+   sodipodi:docbase="C:\Dokumente und Einstellungen\Felix\Desktop"
+   sodipodi:docname="Picasa.svg">
+  <defs
+     id="defs3" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.35000000"
+     inkscape:cx="375.00000"
+     inkscape:cy="520.00000"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     inkscape:window-width="1104"
+     inkscape:window-height="744"
+     inkscape:window-x="-4"
+     inkscape:window-y="-4" />
+  <metadata
+     id="metadata4">
+    <rdf:RDF
+       id="RDF5">
+      <cc:Work
+         rdf:about=""
+         id="Work6">
+        <dc:format
+           id="format7">image/svg+xml</dc:format>
+        <dc:type
+           id="type9"
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <path
+       d="M 118.69106,26.902170 C 109.62228,22.800310 100.02337,20.679610 
90.078429,20.679610 C 81.804939,20.679610 73.670979,22.270130 
65.849529,25.227940 C 65.849529,25.227940 118.69106,73.166740 
118.69106,73.166740 C 118.69106,73.166740 118.69106,26.902170 
118.69106,26.902170 z "
+       class="ps05 ps10 ps21"
+       id="path1199"
+       style="fill:#fa0b0b;fill-opacity:1.0000000" />
+    <path
+       d="M 54.367109,149.34422 C 54.367109,149.34422 54.367109,89.685810 
54.367109,89.685810 C 54.367109,89.685810 25.698689,115.74798 
25.698689,115.74798 C 31.254359,129.67201 41.405759,141.50323 
54.367109,149.34422 z "
+       class="ps06 ps10 ps21"
+       id="path1201"
+       style="fill:#5a55b8;fill-opacity:1.0000000" />
+    <path
+       d="M 20.692739,90.076470 C 20.692739,96.047900 21.591259,102.10304 
23.212469,108.10233 C 23.212469,108.10233 84.723679,52.210960 
84.723679,52.210960 C 84.723679,52.210960 58.457799,28.381070 
58.457799,28.381070 C 35.158089,40.351820 20.692739,63.902670 
20.692739,90.076470 z "
+       class="ps07 ps10 ps21"
+       id="path1203"
+       style="fill:#9e5cb9;fill-opacity:1.0000000" />
+    <path
+       d="M 61.655579,120.24051 C 61.655579,120.24051 61.655579,153.33447 
61.655579,153.33447 C 70.676899,157.40844 80.225589,159.47332 
90.078429,159.47332 C 116.54246,159.47332 140.84668,144.07038 
152.39886,120.24051 C 152.39886,120.24051 61.655579,120.24051 
61.655579,120.24051 z "
+       class="ps08 ps10 ps21"
+       id="path1205"
+       style="fill:#3ca335;fill-opacity:1.0000000" />
+    <path
+       d="M 126.00184,30.892420 C 126.00184,30.892420 126.00184,112.92970 
126.00184,112.92970 C 126.00184,112.92970 155.52410,112.92970 
155.52410,112.92970 C 158.11916,105.53520 159.48644,97.861650 
159.48644,90.076470 C 159.48644,65.967550 146.65068,43.449150 
126.00184,30.892420 z "
+       class="ps09 ps10 ps21"
+       id="path1207"
+       style="fill:#e9881c;fill-opacity:1.0000000" />
+    <path
+       d="M 410.53734,144.15411 C 401.71972,144.15411 394.79958,136.42474 
394.79958,127.04904 C 394.79958,117.47803 401.71972,109.66495 
410.53734,109.66495 C 419.18754,109.66495 426.47045,117.47803 
426.47045,127.04904 C 426.47045,136.42474 419.18754,144.15411 
410.53734,144.15411 z M 434.19980,106.00957 C 434.19980,103.94469 
432.52556,102.27045 430.48861,102.27045 C 428.42371,102.27045 
426.74949,103.94469 426.74949,106.00957 C 426.74949,106.03748 
426.74949,106.03748 426.74949,106.06538 C 426.74949,106.06538 
426.74949,106.06538 426.74949,106.06538 C 426.74949,106.06538 
426.74949,110.94853 426.74949,110.94853 C 423.45682,106.20490 
417.45750,102.29837 410.53734,102.29837 C 397.08771,102.29837 
387.07021,113.40406 387.07021,126.96533 C 387.07021,140.49869 
397.08771,151.52073 410.53734,151.52073 C 417.45750,151.52073 
423.45682,147.61418 426.74949,142.78680 C 426.74949,142.78680 
426.74949,147.69789 426.74949,147.69789 C 426.74949,147.69789 
426.74949,147.69789 426.74949,147.69789 C 426.74949,149.76277 
428.42371,151.43700 430.48861,151.43700 C 432.52556,151.43700 
434.19980,149.76277 434.19980,147.69789 C 434.19980,147.69789 
434.19980,106.06538 434.19980,106.06538 C 434.19980,106.06538 
434.19980,106.06538 434.19980,106.06538 C 434.19980,106.03748 
434.19980,106.03748 434.19980,106.00957 z M 314.65975,144.15411 C 
305.81424,144.15411 298.89407,136.42474 298.89407,127.04904 C 
298.89407,117.47803 305.81424,109.66495 314.65975,109.66495 C 
323.28205,109.66495 330.56494,117.47803 330.56494,127.04904 C 
330.56494,136.42474 323.28205,144.15411 314.65975,144.15411 z M 
334.58309,102.27045 C 332.51820,102.27045 330.84396,103.94469 
330.84396,106.00957 C 330.84396,106.03748 330.87186,106.03748 
330.87186,106.06538 C 330.87186,106.06538 330.84396,106.06538 
330.84396,106.06538 C 330.84396,106.06538 330.84396,110.94853 
330.84396,110.94853 C 327.57921,106.20490 321.57989,102.29837 
314.65975,102.29837 C 301.18218,102.29837 291.19262,113.40406 
291.19262,126.96533 C 291.19262,140.49869 301.18218,151.52073 
314.65975,151.52073 C 321.57989,151.52073 327.57921,147.61418 
330.84396,142.78680 C 330.84396,142.78680 330.84396,147.69789 
330.84396,147.69789 C 330.84396,147.69789 330.84396,147.69789 
330.84396,147.69789 C 330.84396,149.76277 332.51820,151.43700 
334.58309,151.43700 C 336.64797,151.43700 338.32221,149.76277 
338.32221,147.69789 C 338.32221,147.69789 338.32221,106.06538 
338.32221,106.06538 C 338.32221,106.06538 338.29431,106.06538 
338.29431,106.06538 C 338.29431,106.03748 338.32221,106.03748 
338.32221,106.00957 C 338.32221,103.94469 336.64797,102.27045 
334.58309,102.27045 z M 234.26877,89.881140 C 232.14808,89.881140 
230.41804,91.611180 230.41804,93.759780 C 230.41804,95.880470 
232.14808,97.610520 234.26877,97.610520 C 236.41737,97.610520 
238.14741,95.880470 238.14741,93.759780 C 238.14741,91.611180 
236.41737,89.881140 234.26877,89.881140 z M 234.26877,102.27045 C 
232.14808,102.27045 230.41804,104.00050 230.41804,106.14909 C 
230.41804,106.17700 230.41804,106.17700 230.41804,106.20490 C 
230.41804,106.20490 230.41804,106.20490 230.41804,106.20490 C 
230.41804,106.20490 230.41804,147.53046 230.41804,147.53046 C 
230.41804,147.53046 230.41804,147.53046 230.41804,147.53046 C 
230.41804,147.53046 230.41804,147.55837 230.41804,147.55837 C 
230.41804,149.67907 232.14808,151.40910 234.26877,151.40910 C 
236.41737,151.40910 238.14741,149.67907 238.14741,147.55837 C 
238.14741,147.55837 238.14741,147.53046 238.14741,147.53046 C 
238.14741,147.53046 238.14741,147.53046 238.14741,147.53046 C 
238.14741,147.53046 238.14741,106.20490 238.14741,106.20490 C 
238.14741,106.20490 238.11951,106.20490 238.11951,106.20490 C 
238.11951,106.17700 238.14741,106.17700 238.14741,106.14909 C 
238.14741,104.00050 236.41737,102.27045 234.26877,102.27045 z M 
365.33313,121.94264 C 356.15275,120.49164 353.50189,119.31968 
353.50189,115.94332 C 353.50189,112.31581 357.96651,109.38592 
364.16116,109.38592 C 369.88146,109.38592 374.34606,111.95306 
375.43432,116.94785 C 375.43432,116.94785 375.46224,116.94785 
375.46224,116.94785 C 375.93659,118.53838 377.38760,119.71033 
379.14553,119.71033 C 381.26620,119.71033 383.02417,117.98030 
383.02417,115.83170 C 383.02417,115.44105 382.94044,115.07830 
382.82884,114.71555 C 380.93137,106.93037 374.03914,102.29837 
364.16116,102.29837 C 351.60444,102.29837 345.77254,109.46962 
345.77254,116.22235 C 345.77254,125.03996 352.69269,127.77454 
364.04955,129.42087 C 375.51803,130.95558 376.80160,133.41112 
376.80160,136.70377 C 376.80160,140.77774 372.33698,144.32152 
365.05409,144.32152 C 358.44088,144.32152 353.11125,141.05677 
352.02298,135.72714 C 351.68815,133.94129 350.12553,132.57401 
348.22807,132.57401 C 346.07948,132.57401 344.34944,134.30404 
344.34944,136.42474 C 344.34944,136.70377 344.37732,136.95491 
344.43315,137.20604 C 344.43315,137.20604 344.43315,137.20604 
344.43315,137.20604 C 346.38641,146.10737 354.36691,151.52073 
365.05409,151.52073 C 376.24354,151.52073 384.25193,145.60510 
384.25193,136.22941 C 384.25193,125.59804 375.71336,123.58896 
365.33313,121.94264 z M 267.05579,109.66495 C 273.13883,109.66495 
277.96619,112.84598 280.61705,117.92448 C 281.28675,119.04064 
282.48663,119.79405 283.88181,119.79405 C 286.00250,119.79405 
287.73254,118.09191 287.73254,115.99913 C 287.73254,115.32943 
287.53720,114.74345 287.25818,114.21328 C 287.25818,114.18537 
287.25818,114.15746 287.25818,114.12956 C 283.35164,106.84667 
276.04082,102.29837 267.05579,102.29837 C 254.13631,102.29837 
243.58865,113.40406 243.58865,126.96533 C 243.58865,140.49869 
254.13631,151.43700 267.05579,151.43700 C 276.04082,151.43700 
283.40744,146.86077 287.28606,139.60577 C 287.28606,139.57787 
287.28606,139.54997 287.28606,139.52206 C 287.56512,138.99189 
287.73254,138.40591 287.73254,137.79202 C 287.73254,135.67133 
286.00250,133.96919 283.88181,133.96919 C 282.51450,133.96919 
281.34256,134.69469 280.67287,135.75504 C 280.64496,135.75504 
280.64496,135.75504 280.64496,135.75504 C 278.10571,140.86144 
273.25045,144.04249 267.05579,144.04249 C 258.43349,144.04249 
251.31802,136.42474 251.31802,126.96533 C 251.31802,117.47803 
258.43349,109.66495 267.05579,109.66495 z M 205.10926,118.03610 C 
205.10926,118.03610 186.27417,118.03610 186.27417,118.03610 C 
186.27417,118.03610 186.27417,94.568990 186.27417,94.568990 C 
186.27417,94.568990 205.10926,94.568990 205.10926,94.568990 C 
212.47588,94.568990 217.74970,98.029070 217.74970,106.28862 C 
217.74970,114.57603 212.47588,118.03610 205.10926,118.03610 z M 
205.10926,87.202380 C 205.10926,87.202380 178.51687,87.202380 
178.51687,87.202380 C 178.51687,87.202380 178.51687,147.53046 
178.51687,147.53046 C 178.51687,147.53046 178.51687,147.53046 
178.51687,147.53046 C 178.51687,147.53046 178.51687,147.55837 
178.51687,147.55837 C 178.51687,149.67907 180.24690,151.40910 
182.39552,151.40910 C 184.54413,151.40910 186.27417,149.67907 
186.27417,147.55837 C 186.27417,147.55837 186.24625,147.53046 
186.24625,147.53046 C 186.24625,147.53046 186.27417,147.53046 
186.27417,147.53046 C 186.27417,147.53046 186.27417,125.40271 
186.27417,125.40271 C 186.27417,125.40271 205.10926,125.40271 
205.10926,125.40271 C 218.11245,125.40271 225.39536,117.39431 
225.39536,106.28862 C 225.39536,95.099160 218.11245,87.202380 
205.10926,87.202380 z "
+       class="ps010 ps10 ps21"
+       id="path1209"
+       style="fill:#666666;fill-opacity:1.0000000" />
+    <path
+       d="M 443.12902,151.29749 C 443.12902,151.29749 443.12902,145.13074 
443.12902,145.13074 C 443.12902,145.13074 441.14784,145.13074 
441.14784,145.13074 C 441.14784,145.13074 441.14784,144.37734 
441.14784,144.37734 C 441.14784,144.37734 445.94729,144.37734 
445.94729,144.37734 C 445.94729,144.37734 445.94729,145.13074 
445.94729,145.13074 C 445.94729,145.13074 443.99403,145.13074 
443.99403,145.13074 C 443.99403,145.13074 443.99403,151.29749 
443.99403,151.29749 C 443.99403,151.29749 443.12902,151.29749 
443.12902,151.29749 z "
+       class="ps010 ps10 ps21"
+       id="path1211" />
+    <path
+       d="M 447.62154,151.29749 C 447.62154,151.29749 446.89604,151.29749 
446.89604,151.29749 C 446.89604,151.29749 446.89604,144.37734 
446.89604,144.37734 C 446.89604,144.37734 448.17962,144.37734 
448.17962,144.37734 C 448.17962,144.37734 450.27240,149.93021 
450.27240,149.93021 C 450.27240,149.93021 452.30940,144.37734 
452.30940,144.37734 C 452.30940,144.37734 453.59296,144.37734 
453.59296,144.37734 C 453.59296,144.37734 453.59296,151.29749 
453.59296,151.29749 C 453.59296,151.29749 452.72792,151.29749 
452.72792,151.29749 C 452.72792,151.29749 452.72792,145.27025 
452.72792,145.27025 C 452.72792,145.27025 452.67213,145.27025 
452.67213,145.27025 C 452.67213,145.27025 450.49565,151.29749 
450.49565,151.29749 C 450.49565,151.29749 449.90965,151.29749 
449.90965,151.29749 C 449.90965,151.29749 447.64943,145.27025 
447.64943,145.27025 C 447.64943,145.27025 447.62154,145.27025 
447.62154,145.27025 C 447.62154,145.27025 447.62154,151.29749 
447.62154,151.29749 z "
+       class="ps010 ps10 ps21"
+       id="path1213" />
+  </g>
+</svg>

Added: trunk/plugins/output-picasa/rs-picasa-client.c
===================================================================
--- trunk/plugins/output-picasa/rs-picasa-client.c                              
(rev 0)
+++ trunk/plugins/output-picasa/rs-picasa-client.c      2010-05-31 21:20:26 UTC 
(rev 3413)
@@ -0,0 +1,356 @@
+/**
+ * Documentation for Picasa:
+ * 
http://code.google.com/apis/picasaweb/docs/2.0/developers_guide_protocol.html
+ * Login: http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html
+ *
+ * Documentation for CURL:
+ * http://curl.haxx.se/libcurl/c/curl_easy_setopt.html
+ */
+
+#include <glib.h>
+#include <gtk/gtk.h>
+#include <libxml/encoding.h>
+#include <string.h>
+#include <curl/curl.h>
+#include "rs-picasa-client.h"
+#include "conf_interface.h"
+
+#define PICASA_LOGIN_URL "https://www.google.com/accounts/ClientLogin";
+#define PICASA_DATA_URL "http://picasaweb.google.com/data/feed/api";
+#define HTTP_BOUNDARY "5d0ae7df9faf6ee0ae584d7676ca34d0" /* md5sum of 
"Rawstudio2PicasaWebAlbums" */
+
+typedef enum {
+       PICASA_ALBUM_NAME,
+       PICASA_ALBUM_ID
+} PicasaAlbum;
+
+static GtkListStore *
+xml_album_list_response(const GString *xml)
+{
+       xmlDocPtr doc = xmlParseMemory(xml->str, xml->len);
+       xmlNodePtr cur, child;
+
+       cur = xmlDocGetRootElement(doc);
+       cur = cur->xmlChildrenNode;
+
+       gchar *id = NULL;
+       gchar *name = NULL;
+
+       GtkListStore *albums = NULL;
+       GtkTreeIter iter;
+
+       while (cur)
+       {
+               if ((!xmlStrcmp(cur->name, BAD_CAST("entry"))))
+               {
+                       child = cur->xmlChildrenNode;
+
+                       while (child)
+                       {
+                               if ((!xmlStrcmp(child->name, BAD_CAST("name"))) 
&& g_strcmp0((char *) child->ns->prefix, "gphoto") == 0)
+                                       name = (gchar *) 
xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
+                               if ((!xmlStrcmp(child->name, BAD_CAST("id"))) 
&& g_strcmp0((char *) child->ns->prefix, "gphoto") == 0)
+                                       id = (gchar *) 
xmlNodeListGetString(doc, child->xmlChildrenNode, 1);
+                               child = child->next;
+                       }
+
+                       if (name && id)
+                       {
+                               if (!albums)
+                                       albums = gtk_list_store_new(2, 
G_TYPE_STRING, G_TYPE_STRING);
+
+                               gtk_list_store_append(albums, &iter);
+                               gtk_list_store_set(albums, &iter,
+                                                  PICASA_ALBUM_NAME, name,
+                                                  PICASA_ALBUM_ID, id,
+                                                  -1);
+                               id = NULL;
+                               name = NULL;
+                       }
+               }
+               cur = cur->next;
+       }
+       return albums;
+}
+
+gchar *
+xml_album_create_response(const GString *xml)
+{
+       xmlDocPtr doc = xmlParseMemory(xml->str, xml->len);
+       xmlNodePtr cur;
+
+       cur = xmlDocGetRootElement(doc);
+       cur = cur->xmlChildrenNode;
+
+       gchar *id = NULL;
+
+       while (cur)
+       {
+               if ((!xmlStrcmp(cur->name, BAD_CAST("id"))) && g_strcmp0((char 
*) cur->ns->prefix, "gphoto") == 0)
+               {
+                       id = (gchar *) xmlNodeListGetString(doc, 
cur->xmlChildrenNode, 1);
+                       return id;
+               }
+               cur = cur->next;
+       }
+       return NULL;
+}
+
+static size_t
+write_callback(void *ptr, size_t size, size_t nmemb, void *userp)
+{
+       GString *string = (GString *) userp;
+       g_string_append_len(string, (char *) ptr, size * nmemb);
+       return (size * nmemb);
+}
+
+gboolean
+handle_curl_code(CURLcode result)
+{
+       if (result != CURLE_OK)
+       {
+               g_warning("Something has happened with the request, please try 
to recreate this error and tell the developers about it...");
+               /* FIXME: g_warning() with some debug from CURL - request, 
returncode and such... */
+               return FALSE;
+       }
+       else
+       {
+               return TRUE;
+       }
+}
+
+gboolean 
+rs_picasa_client_auth_popup(PicasaClient *picasa_client)
+{
+        gdk_threads_enter ();
+        GtkWidget *auth_dialog = gtk_dialog_new ();
+        gtk_window_set_title (GTK_WINDOW (auth_dialog), "Rawstudio");
+        gtk_container_set_border_width (GTK_CONTAINER (auth_dialog), 4);
+        gtk_dialog_set_has_separator (GTK_DIALOG (auth_dialog), FALSE);
+
+        GtkWidget *vbox = GTK_DIALOG (auth_dialog)->vbox;
+
+        GtkWidget *textlabel = gtk_label_new("Please type in your username and 
password for Picasa Web Albums.");
+        gtk_label_set_line_wrap (GTK_LABEL (textlabel), TRUE);
+
+        gtk_box_pack_start (GTK_BOX (vbox), textlabel, TRUE, TRUE, 4);
+
+        GtkWidget *table = gtk_table_new (2, 2, FALSE);
+
+        GtkWidget *username = gtk_label_new ("Username: ");
+        GtkWidget *password = gtk_label_new ("Password: ");
+
+       GtkWidget *input_username = gtk_entry_new();
+       GtkWidget *input_password = gtk_entry_new();
+       gtk_entry_set_visibility(GTK_ENTRY(input_password), FALSE);
+
+        GtkWidget *cancelbutton = gtk_button_new_from_stock (GTK_STOCK_CANCEL);
+        GtkWidget *acceptbutton = gtk_button_new_from_stock 
(GTK_STOCK_GO_FORWARD);
+
+        gtk_dialog_add_action_widget (GTK_DIALOG (auth_dialog), cancelbutton, 
GTK_RESPONSE_CANCEL);
+        gtk_dialog_add_action_widget (GTK_DIALOG (auth_dialog), acceptbutton, 
GTK_RESPONSE_OK);
+
+        gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 4);
+
+        gtk_table_attach_defaults (GTK_TABLE (table), username, 0, 1, 0, 1);
+        gtk_table_attach_defaults (GTK_TABLE (table), password, 0, 1, 1, 2);
+
+        gtk_table_attach_defaults (GTK_TABLE (table), input_username, 1, 2, 0, 
1);
+        gtk_table_attach_defaults (GTK_TABLE (table), input_password, 1, 2, 1, 
2);
+
+        gtk_widget_show_all (auth_dialog);
+        gint response = gtk_dialog_run (GTK_DIALOG (auth_dialog));
+
+       picasa_client->username = 
g_strdup(gtk_entry_get_text(GTK_ENTRY(input_username)));
+       picasa_client->password = 
g_strdup(gtk_entry_get_text(GTK_ENTRY(input_password)));
+
+        gtk_widget_destroy (auth_dialog);
+
+        gdk_threads_leave ();
+
+       if (response == GTK_RESPONSE_ACCEPT)
+                return TRUE;
+        else
+                return FALSE;
+}
+
+void
+rs_picasa_client_auth(PicasaClient *picasa_client)
+{
+       g_assert(picasa_client->username != NULL);
+       g_assert(picasa_client->password != NULL);
+
+       GString *data = g_string_new(NULL);
+        struct curl_slist *header = NULL;
+
+       GString *post_str = g_string_new(NULL);
+       g_string_printf(post_str, 
"accountType=GOOGLE&Email=%s&Passwd=%s&service=lh2&source=Rawstudio", 
picasa_client->username, picasa_client->password);
+       g_free(picasa_client->password);
+
+       header = curl_slist_append(header, "Content-Type: 
application/x-www-form-urlencoded");
+
+        curl_easy_reset(picasa_client->curl);
+        curl_easy_setopt(picasa_client->curl, CURLOPT_URL, PICASA_LOGIN_URL);
+        curl_easy_setopt(picasa_client->curl, CURLOPT_POST, TRUE);
+       curl_easy_setopt(picasa_client->curl, CURLOPT_POSTFIELDS, 
post_str->str);
+        curl_easy_setopt(picasa_client->curl, CURLOPT_POSTFIELDSIZE, 
post_str->len);
+        curl_easy_setopt(picasa_client->curl, CURLOPT_WRITEFUNCTION, 
write_callback);
+       curl_easy_setopt(picasa_client->curl, CURLOPT_WRITEDATA, data);
+        curl_easy_setopt(picasa_client->curl, CURLOPT_HTTPHEADER, header);
+
+        CURLcode result = curl_easy_perform(picasa_client->curl);
+       handle_curl_code(result);
+       
+       /* To read values as GKeyFile we need a group */
+       data = g_string_prepend(data, "[PICASA]\n");
+
+       GKeyFile *kf = g_key_file_new();
+       g_key_file_load_from_data(kf, data->str, data->len, G_KEY_FILE_NONE, 
NULL);
+
+       picasa_client->captcha_token = g_key_file_get_value(kf, "PICASA", 
"CaptchaToken", NULL);
+       picasa_client->captcha_url = g_key_file_get_value(kf, "PICASA", 
"CaptchaUrl", NULL);
+
+       if (picasa_client->captcha_token && picasa_client->captcha_url)
+       {
+               g_warning("Capcha required and not implemented yet..sorry :(");
+               // FIXME: fetch captcha and let user re-authenticate - call 
this function again.
+               g_free(picasa_client->captcha_token);
+               g_free(picasa_client->captcha_url);
+       }
+       else
+       {
+               picasa_client->auth_token = g_key_file_get_value(kf, "PICASA", 
"Auth", NULL);
+       }
+
+       g_string_free(data, TRUE);
+       g_string_free(post_str, TRUE);
+       curl_slist_free_all(header);
+}
+
+GtkListStore *
+rs_picasa_client_get_album_list(PicasaClient *picasa_client)
+{
+       g_assert(picasa_client->auth_token != NULL);
+       g_assert(picasa_client->username != NULL);
+
+       GString *data = g_string_new(NULL);
+       struct curl_slist *header = NULL;
+
+       GString *url = g_string_new(NULL);
+       g_string_printf(url, "%s/user/%s", PICASA_DATA_URL, 
picasa_client->username);
+
+       GString *auth_string = g_string_new("Authorization: GoogleLogin auth=");
+       auth_string = g_string_append(auth_string, picasa_client->auth_token);
+       header = curl_slist_append(header, auth_string->str);
+
+        curl_easy_reset(picasa_client->curl);
+        curl_easy_setopt(picasa_client->curl, CURLOPT_URL, url->str);
+       curl_easy_setopt(picasa_client->curl, CURLOPT_WRITEFUNCTION, 
write_callback);
+       curl_easy_setopt(picasa_client->curl, CURLOPT_WRITEDATA, data);
+        curl_easy_setopt(picasa_client->curl, CURLOPT_HTTPHEADER, header);
+
+        CURLcode result = curl_easy_perform(picasa_client->curl);
+       handle_curl_code(result);
+
+       return xml_album_list_response(data);
+}
+
+gchar *
+rs_picasa_client_create_album(PicasaClient *picasa_client, const gchar *name)
+{
+       gchar *body = g_strdup_printf("<entry 
xmlns='http://www.w3.org/2005/Atom' xmlns:media='http://search.yahoo.com/mrss/' 
xmlns:gphoto='http://schemas.google.com/photos/2007'> <title 
type='text'>%s</title><summary 
type='text'></summary><gphoto:location></gphoto:location><gphoto:access>private</gphoto:access><gphoto:commentingEnabled>true</gphoto:commentingEnabled><gphoto:timestamp>%d000</gphoto:timestamp><category
 scheme='http://schemas.google.com/g/2005#kind' 
term='http://schemas.google.com/photos/2007#album'></category></entry>", name, 
(int) time(NULL));
+
+       g_assert(picasa_client->auth_token != NULL);
+       g_assert(picasa_client->username != NULL);
+
+       GString *data = g_string_new(NULL);
+       struct curl_slist *header = NULL;
+
+       GString *url = g_string_new(NULL);
+       g_string_printf(url, "%s/user/%s", PICASA_DATA_URL, 
picasa_client->username);
+
+       GString *auth_string = g_string_new("Authorization: GoogleLogin auth=");
+       auth_string = g_string_append(auth_string, picasa_client->auth_token);
+       header = curl_slist_append(header, auth_string->str);
+       header = curl_slist_append(header, "Content-Type: 
application/atom+xml");
+
+        curl_easy_reset(picasa_client->curl);
+        curl_easy_setopt(picasa_client->curl, CURLOPT_URL, url->str);
+       curl_easy_setopt(picasa_client->curl, CURLOPT_WRITEFUNCTION, 
write_callback);
+       curl_easy_setopt(picasa_client->curl, CURLOPT_WRITEDATA, data);
+        curl_easy_setopt(picasa_client->curl, CURLOPT_VERBOSE, TRUE);
+        curl_easy_setopt(picasa_client->curl, CURLOPT_HTTPHEADER, header);
+        curl_easy_setopt(picasa_client->curl, CURLOPT_POST, TRUE);
+       curl_easy_setopt(picasa_client->curl, CURLOPT_POSTFIELDS, body);
+        curl_easy_setopt(picasa_client->curl, CURLOPT_POSTFIELDSIZE, 
strlen(body));
+
+        CURLcode result = curl_easy_perform(picasa_client->curl);
+       handle_curl_code(result);
+
+       return xml_album_create_response(data);
+}
+
+gboolean
+rs_picasa_client_upload_photo(PicasaClient *picasa_client, gchar *photo, gchar 
*albumid)
+{
+       g_assert(picasa_client->auth_token != NULL);
+       g_assert(picasa_client->username != NULL);
+
+       GString *data = g_string_new(NULL);
+       struct curl_slist *header = NULL;
+
+       GString *url = g_string_new(NULL);
+       g_string_printf(url, "%s/user/%s/albumid/%s", PICASA_DATA_URL, 
picasa_client->username, albumid);
+
+       GString *auth_string = g_string_new("Authorization: GoogleLogin auth=");
+       auth_string = g_string_append(auth_string, picasa_client->auth_token);
+
+       gchar *contents;
+       gsize length;
+       g_file_get_contents(photo, &contents, &length, NULL);
+
+       header = curl_slist_append(header, auth_string->str);
+       header = curl_slist_append(header, "Content-Type: image/jpeg");
+
+        curl_easy_reset(picasa_client->curl);
+        curl_easy_setopt(picasa_client->curl, CURLOPT_URL, url->str);
+        curl_easy_setopt(picasa_client->curl, CURLOPT_HTTPHEADER, header);
+        curl_easy_setopt(picasa_client->curl, CURLOPT_POST, TRUE);
+       curl_easy_setopt(picasa_client->curl, CURLOPT_POSTFIELDS, contents);
+        curl_easy_setopt(picasa_client->curl, CURLOPT_POSTFIELDSIZE, (gint) 
length);
+       curl_easy_setopt(picasa_client->curl, CURLOPT_WRITEFUNCTION, 
write_callback);
+       curl_easy_setopt(picasa_client->curl, CURLOPT_WRITEDATA, data);
+
+        CURLcode result = curl_easy_perform(picasa_client->curl);
+       handle_curl_code(result);
+
+       glong response_code;
+       curl_easy_getinfo(picasa_client->curl, CURLINFO_RESPONSE_CODE, 
&response_code);
+       if (response_code != 201)
+       {
+               g_warning("Uncactched error - please submit the following as a 
bugreport.");
+               g_warning("%s", data->str);
+               return FALSE;
+       }
+
+       return TRUE;
+}
+
+PicasaClient *
+rs_picasa_client_init()
+{
+        PicasaClient *picasa_client = g_malloc(sizeof(PicasaClient));
+       picasa_client->curl = curl_easy_init();
+
+       picasa_client->auth_token = 
rs_conf_get_string(CONF_PICASA_CLIENT_AUTH_TOKEN);
+       picasa_client->username = 
rs_conf_get_string(CONF_PICASA_CLIENT_USERNAME);
+
+       if (!picasa_client->auth_token || !picasa_client->username)
+       {
+               rs_picasa_client_auth_popup(picasa_client);
+               rs_picasa_client_auth(picasa_client);
+               rs_conf_set_string(CONF_PICASA_CLIENT_AUTH_TOKEN, 
picasa_client->auth_token);
+               rs_conf_set_string(CONF_PICASA_CLIENT_USERNAME, 
picasa_client->username);
+       }
+       return picasa_client;
+}

Added: trunk/plugins/output-picasa/rs-picasa-client.h
===================================================================
--- trunk/plugins/output-picasa/rs-picasa-client.h                              
(rev 0)
+++ trunk/plugins/output-picasa/rs-picasa-client.h      2010-05-31 21:20:26 UTC 
(rev 3413)
@@ -0,0 +1,23 @@
+#ifndef RS_PICASA_CLIENT_H
+#define RS_PICASA_CLIENT_H
+
+#include <glib.h>
+#include <curl/curl.h>
+
+typedef struct {
+       CURL *curl;
+       gchar *username;
+       gchar *password;
+       gchar *auth_token;
+       gchar *captcha_token;
+       gchar *captcha_url;
+} PicasaClient;
+
+gboolean rs_picasa_client_auth_popup(PicasaClient *picasa_client);
+void rs_picasa_client_auth(PicasaClient *picasa_client);
+GtkListStore * rs_picasa_client_get_album_list(PicasaClient *picasa_client);
+char * rs_picasa_client_create_album(PicasaClient *picasa_client, const gchar 
*name);
+gboolean rs_picasa_client_upload_photo(PicasaClient *picasa_client, gchar 
*photo, gchar *albumid);
+PicasaClient * rs_picasa_client_init();
+
+#endif /* RS_PICASA_CLIENT_H */


_______________________________________________
Rawstudio-commit mailing list
[email protected]
http://rawstudio.org/cgi-bin/mailman/listinfo/rawstudio-commit

Reply via email to