[f-spot] Clean up the Gallery export addin



commit 0bb8ccf34597ae76eeb7c944c9832c566e810e60
Author: Stephen Shaw <sshaw decriptor com>
Date:   Mon Mar 5 16:02:04 2012 -0700

    Clean up the Gallery export addin
    
    Split out the gallery, gallery1, gallery2
    classes into their own files.
    
    Removed unused usings
    
    Added default parameters to reduce the number
    of methods.
    
    Convert several variables to automatic parameters
    
    Minor clean ups

 .../FSpot.Exporters.Gallery.csproj                 |    4 +
 .../FSpot.Exporters.Gallery/AccountDialog.cs       |   17 +-
 .../FSpot.Exporters.Gallery/FormClient.cs          |   38 +-
 .../FSpot.Exporters.Gallery/Gallery.cs             |  472 ++++++++++
 .../FSpot.Exporters.Gallery/Gallery1.cs            |  262 ++++++
 .../FSpot.Exporters.Gallery/Gallery2.cs            |  267 ++++++
 .../FSpot.Exporters.Gallery/GalleryAccount.cs      |   76 +--
 .../GalleryAccountManager.cs                       |   35 +-
 .../FSpot.Exporters.Gallery/GalleryAddAlbum.cs     |   38 +-
 .../FSpot.Exporters.Gallery/GalleryExceptions.cs   |   51 ++
 .../FSpot.Exporters.Gallery/GalleryExport.cs       |   21 +-
 .../FSpot.Exporters.Gallery/GalleryRemote.cs       |  947 +-------------------
 .../Exporters/FSpot.Exporters.Gallery/Makefile.am  |    4 +
 .../FSpotExporters.UnitTests.csproj                |    1 +
 14 files changed, 1128 insertions(+), 1105 deletions(-)
---
diff --git a/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery.csproj b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery.csproj
index 71fd75d..36c2e3d 100644
--- a/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery.csproj
+++ b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery.csproj
@@ -38,6 +38,10 @@
     <Compile Include="FSpot.Exporters.Gallery\GalleryAccountManager.cs" />
     <Compile Include="FSpot.Exporters.Gallery\AccountDialog.cs" />
     <Compile Include="FSpot.Exporters.Gallery\GalleryAddAlbum.cs" />
+    <Compile Include="FSpot.Exporters.Gallery\GalleryExceptions.cs" />
+    <Compile Include="FSpot.Exporters.Gallery\Gallery.cs" />
+    <Compile Include="FSpot.Exporters.Gallery\Gallery1.cs" />
+    <Compile Include="FSpot.Exporters.Gallery\Gallery2.cs" />
   </ItemGroup>
   <ItemGroup>
     <EmbeddedResource Include="Resources\GalleryExport.addin.xml">
diff --git a/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/AccountDialog.cs b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/AccountDialog.cs
index 3b4598d..c98e249 100644
--- a/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/AccountDialog.cs
+++ b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/AccountDialog.cs
@@ -29,22 +29,13 @@
 
 
 using System;
-using System.Net;
-using System.IO;
-using System.Text;
-using System.Collections;
-using System.Collections.Specialized;
-using System.Web;
+
 using Mono.Unix;
-using FSpot;
-using FSpot.Core;
-using FSpot.Filters;
-using FSpot.Widgets;
-using FSpot.Utils;
-using FSpot.UI.Dialog;
-using FSpot.Extensions;
+
 using Hyena;
 using Hyena.Widgets;
+
+
 namespace FSpot.Exporters.Gallery
 {
 	public class AccountDialog {
diff --git a/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/FormClient.cs b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/FormClient.cs
index 5b92362..b224103 100644
--- a/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/FormClient.cs
+++ b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/FormClient.cs
@@ -4,10 +4,12 @@
 // Author:
 //   Larry Ewing <lewing novell com>
 //   Stephane Delcroix <sdelcroix src gnome org>
+//   Stephen Shaw <sshaw decriptor com>
 //
 // Copyright (C) 2004-2008 Novell, Inc.
 // Copyright (C) 2004, 2006 Larry Ewing
 // Copyright (C) 2008 Stephane Delcroix
+//  Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany.
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -30,18 +32,20 @@
 //
 
 using System;
-using System.Net;
+using System.Collections.Generic;
 using System.IO;
+using System.Net;
 using System.Text;
-using System.Collections;
-using System.Collections.Generic;
-using System.Collections.Specialized;
 using System.Web;
-using Hyena;
+
 using FSpot.Core;
+using Mono.Unix;
+
 
-namespace FSpot.Exporters.Gallery {
-	public class FormClient {
+namespace FSpot.Exporters.Gallery
+{
+	public class FormClient
+	{
 		private struct FormItem {
 			public string Name;
 			public object Value;
@@ -223,23 +227,13 @@ namespace FSpot.Exporters.Gallery {
 			Items.Clear ();
 			multipart = false;
 		}
-	
-		public HttpWebResponse Submit (string url)
-		{
-			return Submit (url, null);
-		}
-	
-		public HttpWebResponse Submit (string url, FSpot.ProgressItem item)
+
+		public HttpWebResponse Submit (string url, FSpot.ProgressItem progress_item = null)
 		{
-			return Submit (new Uri (url), item);
+			return Submit (new Uri (url), progress_item);
 		}
 		
-		public HttpWebResponse Submit (Uri uri)
-		{
-			return Submit (uri, null);
-		}
-	
-		public HttpWebResponse Submit (Uri uri, FSpot.ProgressItem progress_item) 
+		public HttpWebResponse Submit (Uri uri, FSpot.ProgressItem progress_item = null)
 		{
 			this.Progress = progress_item;
 			Request = (HttpWebRequest) WebRequest.Create (uri);
@@ -324,7 +318,7 @@ namespace FSpot.Exporters.Gallery {
 					return Submit (uri, progress_item);
 				}
 				
-				throw new WebException (Mono.Unix.Catalog.GetString ("Unhandled exception"), e);
+				throw new WebException (Catalog.GetString ("Unhandled exception"), e);
 			}
 	
 			return response;
diff --git a/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/Gallery.cs b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/Gallery.cs
new file mode 100644
index 0000000..207aaa2
--- /dev/null
+++ b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/Gallery.cs
@@ -0,0 +1,472 @@
+//  Gallery.cs
+// 
+//  Author:
+//       Stephen Shaw <sshaw decriptor com>
+// 
+//  Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany.
+// 
+//  Permission is hereby granted, free of charge, to any person obtaining
+//  a copy of this software and associated documentation files (the
+//  "Software"), to deal in the Software without restriction, including
+//  without limitation the rights to use, copy, modify, merge, publish,
+//  distribute, sublicense, and/or sell copies of the Software, and to
+//  permit persons to whom the Software is furnished to do so, subject to
+//  the following conditions:
+// 
+//  The above copyright notice and this permission notice shall be
+//  included in all copies or substantial portions of the Software.
+// 
+//  THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND,
+//  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+//  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+//  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+//  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+//  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+//  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//  
+
+/* These classes are based off the documentation at
+ *
+ * http://codex.gallery2.org/index.php/Gallery_Remote:Protocol
+ */
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Text;
+
+using Mono.Unix;
+
+using Hyena;
+using Hyena.Widgets;
+
+namespace FSpot.Exporters.Gallery
+{
+	public abstract class Gallery
+	{
+		#region Properties
+		public Uri Uri { get; protected set; }
+		public string Name { get; set; }
+		public string AuthToken { get; set; }
+		public GalleryVersion Version { get; protected set; }
+		public List<Album> Albums { get; protected set; }
+		#endregion
+
+		public bool expect_continue = true;
+		protected CookieContainer cookies = null;
+		public FSpot.ProgressItem Progress = null;
+
+		public abstract void Login (string username, string passwd);
+		public abstract List<Album> FetchAlbums ();
+		public abstract List<Album> FetchAlbumsPrune ();
+		public abstract bool MoveAlbum (Album album, string end_name);
+		public abstract int AddItem (Album album, string path, string filename, string caption, string description, bool autorotate);
+		//public abstract Album AlbumProperties (string album);
+		public abstract bool NewAlbum (string parent_name, string name, string title, string description);
+		public abstract List<Image> FetchAlbumImages (Album album, bool include_ablums);
+		public abstract string GetAlbumUrl (Album album);
+
+		public Gallery (string name)
+		{
+			Name = name;
+			cookies = new CookieContainer ();
+			Albums = new List<Album> ();
+		}
+
+		public static GalleryVersion DetectGalleryVersion (string url)
+		{
+			//Figure out if the url is for G1 or G2
+			Log.Debug ("Detecting Gallery version");
+
+			GalleryVersion version;
+
+			if (url.EndsWith (Gallery1.script_name))
+				version = GalleryVersion.Version1;
+			else if (url.EndsWith (Gallery2.script_name))
+				version = GalleryVersion.Version2;
+			else {
+				//check what script is available on the server
+				FormClient client = new FormClient ();
+
+				try {
+					client.Submit (new Uri (Gallery.FixUrl (url, Gallery1.script_name)));
+					version = GalleryVersion.Version1;
+
+				} catch (System.Net.WebException) {
+					try {
+						client.Submit (new Uri (Gallery.FixUrl (url, Gallery2.script_name)));
+						version = GalleryVersion.Version2;
+
+					} catch (System.Net.WebException) {
+						//Uh oh, neither version detected
+						version = GalleryVersion.VersionUnknown;
+					}
+				}
+			}
+
+			Log.Debug ("Detected: " + version.ToString ());
+			return version;
+		}
+
+		public bool IsConnected ()
+		{
+			bool retVal = true;
+			//Console.WriteLine ("^^^^^^^Checking IsConnected");
+			foreach (Cookie cookie in cookies.GetCookies(Uri)) {
+				bool isExpired = cookie.Expired;
+				//Console.WriteLine (cookie.Name + " " + (isExpired ? "expired" : "valid"));
+				if (isExpired)
+					retVal = false;
+			}
+			//return cookies.GetCookies(Uri).Count > 0;
+			return retVal;
+		}
+
+		/// <summary>
+		/// Reads until it finds the start of the response
+		/// </summary>
+		/// <returns>
+		/// The response
+		/// </returns>
+		/// <param name='response'>
+		/// Response.
+		/// </param>
+		protected StreamReader findResponse (HttpWebResponse response)
+		{
+			StreamReader reader = new StreamReader (response.GetResponseStream (), Encoding.UTF8);
+			if (reader == null)
+				throw new GalleryException (Catalog.GetString ("Error reading server response"));
+
+			string line;
+			string full_response = null;
+			while ((line = reader.ReadLine ()) != null) {
+				full_response += line;
+				if (line.IndexOf ("#__GR2PROTO__", 0) > -1)
+					break;
+			}
+
+			if (line == null)
+				// failed to find the response
+				throw new GalleryException (Catalog.GetString ("Server returned response without Gallery content"), full_response);
+			return reader;
+		}
+
+		protected string [] GetNextLine (StreamReader reader)
+		{
+			char [] value_split = new char[1] {'='};
+			bool haveLine = false;
+			string[] array = null;
+			while (!haveLine) {
+				string line = reader.ReadLine ();
+				//Console.WriteLine ("READING: " + line);
+				if (line != null) {
+					array = line.Split (value_split, 2);
+					haveLine = !LineIgnored (array);
+				} else
+					//end of input
+					return null;
+			}
+			return array;
+		}
+
+		private bool LineIgnored (string[] line)
+		{
+			if (line [0].StartsWith ("debug") || line [0].StartsWith ("can_create_root"))
+				return true;
+			return false;
+		}
+
+		protected bool ParseLogin (HttpWebResponse response)
+		{
+			string [] data;
+			StreamReader reader = null;
+			ResultCode status = ResultCode.UnknownResponse;
+			string status_text = "Error: Unable to parse server response";
+
+			try {
+				reader = findResponse (response);
+				while ((data = GetNextLine (reader)) != null) {
+					if (data [0] == "status")
+						status = (ResultCode)int.Parse (data [1]);
+					else if (data [0].StartsWith ("status_text")) {
+						status_text = data [1];
+						Log.DebugFormat ("StatusText : {0}", data [1]);
+					} else if (data [0].StartsWith ("server_version")) {
+						//FIXME we should use the to determine what capabilities the server has
+					} else if (data [0].StartsWith ("auth_token"))
+						AuthToken = data [1];
+					else
+						Log.DebugFormat ("Unparsed Line in ParseLogin(): {0}={1}", data [0], data [1]);
+				}
+
+				//Console.WriteLine ("Found: {0} cookies", response.Cookies.Count);
+				if (status != ResultCode.Success) {
+					Log.Debug (status_text);
+					throw new GalleryCommandException (status_text, status);
+				}
+				return true;
+			} finally {
+				if (reader != null)
+					reader.Close ();
+				response.Close ();
+			}
+		}
+
+		public List<Album> ParseFetchAlbums (HttpWebResponse response)
+		{
+			//Console.WriteLine ("in ParseFetchAlbums()");
+			string [] data;
+			StreamReader reader = null;
+			ResultCode status = ResultCode.UnknownResponse;
+			string status_text = "Error: Unable to parse server response";
+			Albums = new List<Album> ();
+
+			try {
+				Album current_album = null;
+				reader = findResponse (response);
+				while ((data = GetNextLine (reader)) != null) {
+					//Console.WriteLine ("Parsing Line: {0}={1}", data[0], data[1]);
+					if (data [0] == "status")
+						status = (ResultCode)int.Parse (data [1]);
+					else if (data [0].StartsWith ("status_text")) {
+						status_text = data [1];
+						Log.DebugFormat ("StatusText : {0}", data [1]);
+					} else if (data [0].StartsWith ("album.name")) {
+						//this is the URL name
+						int ref_num = -1;
+						if (this.Version == GalleryVersion.Version1) {
+							string [] segments = data [0].Split (new char[1]{'.'});
+							ref_num = int.Parse (segments [segments.Length - 1]);
+						} else
+							ref_num = int.Parse (data [1]);
+						current_album = new Album (this, data [1], ref_num);
+						Albums.Add (current_album);
+						//Console.WriteLine ("current_album: " + data[1]);
+					} else if (data [0].StartsWith ("album.title"))
+						//this is the display name
+						current_album.Title = data [1];
+					else if (data [0].StartsWith ("album.summary"))
+						current_album.Summary = data [1];
+					else if (data [0].StartsWith ("album.parent"))
+						//FetchAlbums and G2 FetchAlbumsPrune return ints
+						//G1 FetchAlbumsPrune returns album names (and 0 for root albums)
+						try {
+							current_album.ParentRefNum = int.Parse (data [1]);
+						} catch (System.FormatException) {
+							current_album.ParentRefNum = LookupAlbum (data [1]).RefNum;
+						}
+						//Console.WriteLine ("album.parent data[1]: " + data[1]);
+					else if (data [0].StartsWith ("album.resize_size"))
+						current_album.ResizeSize = int.Parse (data [1]);
+					else if (data [0].StartsWith ("album.thumb_size"))
+						current_album.ThumbSize = int.Parse (data [1]);
+					else if (data [0].StartsWith ("album.info.extrafields")) {
+						//ignore, this is the album description
+					} else if (data [0].StartsWith ("album.perms.add") && data [1] == "true")
+						current_album.Perms |= AlbumPermission.Add;
+					else if (data [0].StartsWith ("album.perms.write") && data [1] == "true")
+						current_album.Perms |= AlbumPermission.Write;
+					else if (data [0].StartsWith ("album.perms.del_item") && data [1] == "true")
+						current_album.Perms |= AlbumPermission.Delete;
+					else if (data [0].StartsWith ("album.perms.del_alb") && data [1] == "true")
+						current_album.Perms |= AlbumPermission.DeleteAlbum;
+					else if (data [0].StartsWith ("album.perms.create_sub") && data [1] == "true")
+						current_album.Perms |= AlbumPermission.CreateSubAlbum;
+					else if (data [0].StartsWith ("album_count"))
+					if (Albums.Count != int.Parse (data [1]))
+						Log.Warning ("Parsed album count does not match album_count.  Something is amiss");
+					else if (data [0].StartsWith ("auth_token"))
+						AuthToken = data [1];
+					else
+						Log.DebugFormat ("Unparsed Line in ParseFetchAlbums(): {0}={1}", data [0], data [1]);
+
+				}
+				//Console.WriteLine ("Found: {0} cookies", response.Cookies.Count);
+				if (status != ResultCode.Success) {
+					Log.Debug (status_text);
+					throw new GalleryCommandException (status_text, status);
+				}
+
+				//Console.WriteLine (After parse albums.Count + " albums parsed");
+				return Albums;
+			} finally {
+				if (reader != null)
+					reader.Close ();
+				response.Close ();
+			}
+		}
+
+		public int ParseAddItem (HttpWebResponse response)
+		{
+			string [] data;
+			StreamReader reader = null;
+			ResultCode status = ResultCode.UnknownResponse;
+			string status_text = "Error: Unable to parse server response";
+			int item_id = 0;
+			try {
+				reader = findResponse (response);
+				while ((data = GetNextLine (reader)) != null) {
+					if (data [0] == "status")
+						status = (ResultCode)int.Parse (data [1]);
+					else if (data [0].StartsWith ("status_text")) {
+						status_text = data [1];
+						Log.DebugFormat ("StatusText : {0}", data [1]);
+					} else if (data [0].StartsWith ("auth_token"))
+						AuthToken = data [1];
+					else if (data [0].StartsWith ("item_name"))
+						item_id = int.Parse (data [1]);
+					else
+						Log.DebugFormat ("Unparsed Line in ParseAddItem(): {0}={1}", data [0], data [1]);
+				}
+				//Console.WriteLine ("Found: {0} cookies", response.Cookies.Count);
+				if (status != ResultCode.Success) {
+					Log.Debug (status_text);
+					throw new GalleryCommandException (status_text, status);
+				}
+
+				return item_id;
+			} finally {
+				if (reader != null)
+					reader.Close ();
+				response.Close ();
+			}
+		}
+
+		public bool ParseNewAlbum (HttpWebResponse response)
+		{
+			return ParseBasic (response);
+		}
+
+		public bool ParseMoveAlbum (HttpWebResponse response)
+		{
+			return ParseBasic (response);
+		}
+
+		/*
+		public Album ParseAlbumProperties (HttpWebResponse response)
+		{
+			string [] data;
+			StreamReader reader = null;
+			ResultCode status = ResultCode.UnknownResponse;
+			string status_text = "Error: Unable to parse server response";
+			try {
+
+				reader = findResponse (response);
+				while ((data = GetNextLine (reader)) != null) {
+					if (data[0] == "status") {
+						status = (ResultCode) int.Parse (data [1]);
+					} else if (data[0].StartsWith ("status_text")) {
+						status_text = data[1];
+						Log.Debug ("StatusText : {0}", data[1]);
+					} else if (data[0].StartsWith ("auto-resize")) {
+						//ignore
+					} else {
+						Log.Debug ("Unparsed Line in ParseBasic(): {0}={1}", data[0], data[1]);
+					}
+				}
+				//Console.WriteLine ("Found: {0} cookies", response.Cookies.Count);
+				if (status != ResultCode.Success) {
+					Log.Debug (status_text);
+					throw new GalleryCommandException (status_text, status);
+				}
+
+				return true;
+			} finally {
+				if (reader != null)
+					reader.Close ();
+
+				response.Close ();
+			}
+		}
+		*/
+
+		private bool ParseBasic (HttpWebResponse response)
+		{
+			string [] data;
+			StreamReader reader = null;
+			ResultCode status = ResultCode.UnknownResponse;
+			string status_text = "Error: Unable to parse server response";
+			try {
+				reader = findResponse (response);
+				while ((data = GetNextLine (reader)) != null) {
+					if (data [0] == "status")
+						status = (ResultCode)int.Parse (data [1]);
+					else if (data [0].StartsWith ("status_text")) {
+						status_text = data [1];
+						Log.DebugFormat ("StatusText : {0}", data [1]);
+					} else if (data [0].StartsWith ("auth_token"))
+						AuthToken = data [1];
+					else
+						Log.DebugFormat ("Unparsed Line in ParseBasic(): {0}={1}", data [0], data [1]);
+				}
+				//Console.WriteLine ("Found: {0} cookies", response.Cookies.Count);
+				if (status != ResultCode.Success) {
+					Log.Debug (status_text + " Status: " + status);
+					throw new GalleryCommandException (status_text, status);
+				}
+
+				return true;
+			} finally {
+				if (reader != null)
+					reader.Close ();
+				response.Close ();
+			}
+		}
+
+		public Album LookupAlbum (string name)
+		{
+			Album match = null;
+
+			foreach (Album album in Albums) {
+				if (album.Name == name) {
+					match = album;
+					break;
+				}
+			}
+			return match;
+		}
+
+		public Album LookupAlbum (int ref_num)
+		{
+			// FIXME: this is really not the best way to do this
+			Album match = null;
+
+			foreach (Album album in Albums) {
+				if (album.RefNum == ref_num) {
+					match = album;
+					break;
+				}
+			}
+			return match;
+		}
+
+		public static string FixUrl (string url, string end)
+		{
+			string fixedUrl = url;
+			if (!url.EndsWith (end)) {
+				if (!url.EndsWith ("/"))
+					fixedUrl = url + "/";
+				fixedUrl = fixedUrl + end;
+			}
+			return fixedUrl;
+
+		}
+
+		public void PopupException (GalleryCommandException e, Gtk.Dialog d)
+		{
+			Log.DebugFormat ("{0} : {1} ({2})", e.Message, e.ResponseText, e.Status);
+			HigMessageDialog md =
+				new HigMessageDialog (d,
+						      Gtk.DialogFlags.Modal |
+					Gtk.DialogFlags.DestroyWithParent,
+						      Gtk.MessageType.Error, Gtk.ButtonsType.Ok,
+						      Catalog.GetString ("Error while creating new album"),
+						      String.Format (Catalog.GetString ("The following error was encountered while attempting to perform the requested operation:\n{0} ({1})"), e.Message, e.Status));
+			md.Run ();
+			md.Destroy ();
+		}
+	}
+
+
+}
diff --git a/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/Gallery1.cs b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/Gallery1.cs
new file mode 100644
index 0000000..c663d65
--- /dev/null
+++ b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/Gallery1.cs
@@ -0,0 +1,262 @@
+//  Gallery1.cs
+// 
+//  Author:
+//       Stephen Shaw <sshaw decriptor com>
+// 
+//  Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany.
+// 
+//  Permission is hereby granted, free of charge, to any person obtaining
+//  a copy of this software and associated documentation files (the
+//  "Software"), to deal in the Software without restriction, including
+//  without limitation the rights to use, copy, modify, merge, publish,
+//  distribute, sublicense, and/or sell copies of the Software, and to
+//  permit persons to whom the Software is furnished to do so, subject to
+//  the following conditions:
+// 
+//  The above copyright notice and this permission notice shall be
+//  included in all copies or substantial portions of the Software.
+// 
+//  THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND,
+//  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+//  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+//  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+//  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+//  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+//  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+/* These classes are based off the documentation at
+ *
+ * http://codex.gallery2.org/index.php/Gallery_Remote:Protocol
+ */
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+
+using Hyena;
+
+namespace FSpot.Exporters.Gallery
+{
+	public class Gallery1 : Gallery
+	{
+		public const string script_name = "gallery_remote2.php";
+
+		public Gallery1 (string url) : this (url, url)
+		{
+		}
+
+		public Gallery1 (string name, string url) : base (name)
+		{
+			Uri = new Uri (FixUrl (url, script_name));
+			Version = GalleryVersion.Version1;
+		}
+
+		public override void Login (string username, string passwd)
+		{
+			//Console.WriteLine ("Gallery1: Attempting to login");
+			FormClient client = new FormClient (cookies);
+
+			client.Add ("cmd", "login");
+			client.Add ("protocol_version", "2.3");
+			client.Add ("uname", username);
+			client.Add ("password", passwd);
+
+			ParseLogin (client.Submit (Uri));
+		}
+
+		public override List<Album> FetchAlbums ()
+		{
+			FormClient client = new FormClient (cookies);
+
+			client.Add ("cmd", "fetch-albums");
+			client.Add ("protocol_version", "2.3");
+
+			return ParseFetchAlbums (client.Submit (Uri));
+		}
+
+		public override bool MoveAlbum (Album album, string end_name)
+		{
+			FormClient client = new FormClient (cookies);
+
+			client.Add ("cmd", "move-album");
+			client.Add ("protocol_version", "2.7");
+			client.Add ("set_albumName", album.Name);
+			client.Add ("set_destalbumName", end_name);
+
+			return ParseMoveAlbum (client.Submit (Uri));
+		}
+
+		public override int AddItem (Album album,
+				     string path,
+				     string filename,
+				     string caption,
+				     string description,
+				     bool autorotate)
+		{
+			FormClient client = new FormClient (cookies);
+
+			client.Add ("cmd", "add-item");
+			client.Add ("protocol_version", "2.9");
+			client.Add ("set_albumName", album.Name);
+			client.Add ("caption", caption);
+			client.Add ("userfile_name", filename);
+			client.Add ("force_filename", filename);
+			client.Add ("auto_rotate", autorotate ? "yes" : "no");
+			client.Add ("userfile", new FileInfo (path));
+			client.Add ("extrafield.Description", description);
+			client.expect_continue = expect_continue;
+
+			return ParseAddItem (client.Submit (Uri, Progress));
+		}
+
+		/*
+		public override Album AlbumProperties (string album)
+		{
+			FormClient client = new FormClient (cookies);
+			client.Add ("cmd", "album-properties");
+			client.Add ("protocol_version", "2.3");
+			client.Add ("set_albumName", album);
+
+			return ParseAlbumProperties (client.Submit (uri));
+		}
+		*/
+
+		public override bool NewAlbum (string parent_name,
+				      string name,
+				      string title,
+				      string description)
+		{
+			FormClient client = new FormClient (cookies);
+			client.Multipart = true;
+			client.Add ("cmd", "new-album");
+			client.Add ("protocol_version", "2.8");
+			client.Add ("set_albumName", parent_name);
+			client.Add ("newAlbumName", name);
+			client.Add ("newAlbumTitle", title);
+			client.Add ("newAlbumDesc", description);
+
+			return ParseNewAlbum (client.Submit (Uri));
+		}
+
+		public override List<Image> FetchAlbumImages (Album album, bool include_ablums)
+		{
+			FormClient client = new FormClient (cookies);
+			client.Add ("cmd", "fetch-album-images");
+			client.Add ("protocol_version", "2.3");
+			client.Add ("set_albumName", album.Name);
+			client.Add ("albums_too", include_ablums ? "yes" : "no");
+
+			album.Images = ParseFetchAlbumImages (client.Submit (Uri), album);
+			return album.Images;
+		}
+
+		public override List<Album> FetchAlbumsPrune ()
+		{
+			FormClient client = new FormClient (cookies);
+			client.Add ("cmd", "fetch-albums-prune");
+			client.Add ("protocol_version", "2.3");
+			client.Add ("check_writable", "no");
+			List<Album> a = ParseFetchAlbums (client.Submit (Uri));
+			a.Sort ();
+			return a;
+		}
+
+		public List<Image> ParseFetchAlbumImages (HttpWebResponse response, Album album)
+		{
+			string [] data;
+			StreamReader reader = null;
+			ResultCode status = ResultCode.UnknownResponse;
+			string status_text = "Error: Unable to parse server response";
+			try {
+				Image current_image = null;
+				reader = findResponse (response);
+				while ((data = GetNextLine (reader)) != null) {
+					if (data [0] == "status")
+						status = (ResultCode)int.Parse (data [1]);
+					else if (data [0].StartsWith ("status_text")) {
+						status_text = data [1];
+						Log.DebugFormat ("StatusText : {0}", data [1]);
+					} else if (data [0].StartsWith ("image.name")) {
+						current_image = new Image (album, data [1]);
+						album.Images.Add (current_image);
+					} else if (data [0].StartsWith ("image.raw_width"))
+						current_image.RawWidth = int.Parse (data [1]);
+					else if (data [0].StartsWith ("image.raw_height"))
+						current_image.RawHeight = int.Parse (data [1]);
+					else if (data [0].StartsWith ("image.raw_height"))
+						current_image.RawHeight = int.Parse (data [1]);
+					else if (data [0].StartsWith ("image.raw_filesize")) {
+					} else if (data [0].StartsWith ("image.capturedate.year")) {
+					} else if (data [0].StartsWith ("image.capturedate.mon")) {
+					} else if (data [0].StartsWith ("image.capturedate.mday")) {
+					} else if (data [0].StartsWith ("image.capturedate.hours")) {
+					} else if (data [0].StartsWith ("image.capturedate.minutes")) {
+					} else if (data [0].StartsWith ("image.capturedate.seconds")) {
+					} else if (data [0].StartsWith ("image.hidden")) {
+					} else if (data [0].StartsWith ("image.resizedName"))
+						current_image.ResizedName = data [1];
+					else if (data [0].StartsWith ("image.resized_width"))
+						current_image.ResizedWidth = int.Parse (data [1]);
+					else if (data [0].StartsWith ("image.resized_height"))
+						current_image.ResizedHeight = int.Parse (data [1]);
+					else if (data [0].StartsWith ("image.thumbName"))
+						current_image.ThumbName = data [1];
+					else if (data [0].StartsWith ("image.thumb_width"))
+						current_image.ThumbWidth = int.Parse (data [1]);
+					else if (data [0].StartsWith ("image.thumb_height"))
+						current_image.ThumbHeight = int.Parse (data [1]);
+					else if (data [0].StartsWith ("image.caption"))
+						current_image.Caption = data [1];
+					else if (data [0].StartsWith ("image.extrafield.Description"))
+						current_image.Description = data [1];
+					else if (data [0].StartsWith ("image.clicks"))
+						try {
+							current_image.Clicks = int.Parse (data [1]);
+						} catch (System.FormatException) {
+							current_image.Clicks = 0;
+						}
+					else if (data [0].StartsWith ("baseurl"))
+						album.BaseURL = data [1];
+					else if (data [0].StartsWith ("image_count"))
+					if (album.Images.Count != int.Parse (data [1]))
+						Log.Warning ("Parsed image count for " + album.Name + "(" + album.Images.Count + ") does not match image_count (" + data [1] + ").  Something is amiss");
+					else
+						Log.DebugFormat ("Unparsed Line in ParseFetchAlbumImages(): {0}={1}", data [0], data [1]);
+				}
+				//Console.WriteLine ("Found: {0} cookies", response.Cookies.Count);
+				if (status != ResultCode.Success) {
+					Log.Debug (status_text);
+					throw new GalleryCommandException (status_text, status);
+				}
+
+
+				//Set the Urls for downloading the images.
+				string baseUrl = album.BaseURL + "/";
+				foreach (Image image in album.Images) {
+					image.Url = baseUrl + image.Name;
+				}
+
+				return album.Images;
+			} finally {
+				if (reader != null)
+					reader.Close ();
+
+				response.Close ();
+			}
+		}
+
+		public override string GetAlbumUrl (Album album)
+		{
+			string url = Uri.ToString ();
+			url = url.Remove (url.Length - script_name.Length, script_name.Length);
+
+			string path = album.Name;
+
+			url = url + path;
+			url = url.Replace (" ", "+");
+			return url;
+		}
+	}
+}
diff --git a/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/Gallery2.cs b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/Gallery2.cs
new file mode 100644
index 0000000..02f0edc
--- /dev/null
+++ b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/Gallery2.cs
@@ -0,0 +1,267 @@
+//  Gallery2.cs
+// 
+//  Author:
+//       Stephen Shaw <sshaw decriptor com>
+// 
+//  Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany.
+// 
+//  Permission is hereby granted, free of charge, to any person obtaining
+//  a copy of this software and associated documentation files (the
+//  "Software"), to deal in the Software without restriction, including
+//  without limitation the rights to use, copy, modify, merge, publish,
+//  distribute, sublicense, and/or sell copies of the Software, and to
+//  permit persons to whom the Software is furnished to do so, subject to
+//  the following conditions:
+// 
+//  The above copyright notice and this permission notice shall be
+//  included in all copies or substantial portions of the Software.
+// 
+//  THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND,
+//  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+//  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+//  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+//  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+//  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+//  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+/* These classes are based off the documentation at
+ *
+ * http://codex.gallery2.org/index.php/Gallery_Remote:Protocol
+ */
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+
+using Hyena;
+
+namespace FSpot.Exporters.Gallery
+{
+	public class Gallery2 : Gallery
+	{
+		public const string script_name = "main.php";
+
+		public Gallery2 (string url) : this (url, url)
+		{
+		}
+
+		public Gallery2 (string name, string url) : base (name)
+		{
+			Uri = new Uri (FixUrl (url, script_name));
+			Version = GalleryVersion.Version2;
+		}
+
+		public override void Login (string username, string passwd)
+		{
+			Log.Debug ("Gallery2: Attempting to login");
+			FormClient client = new FormClient (cookies);
+
+			client.Add ("g2_form[cmd]", "login");
+			client.Add ("g2_form[protocol_version]", "2.10");
+			client.Add ("g2_form[uname]", username);
+			client.Add ("g2_form[password]", passwd);
+			AddG2Specific (client);
+
+			ParseLogin (client.Submit (Uri));
+		}
+
+		public override List<Album> FetchAlbums ()
+		{
+			//FetchAlbums doesn't exist for G2, we have to use FetchAlbumsPrune()
+			return FetchAlbumsPrune ();
+		}
+
+		public override bool MoveAlbum (Album album, string end_name)
+		{
+			FormClient client = new FormClient (cookies);
+
+			client.Add ("g2_form[cmd]", "move-album");
+			client.Add ("g2_form[protocol_version]", "2.10");
+			client.Add ("g2_form[set_albumName]", album.Name);
+			client.Add ("g2_form[set_destalbumName]", end_name);
+			AddG2Specific (client);
+
+			return ParseMoveAlbum (client.Submit (Uri));
+		}
+
+		public override int AddItem (Album album,
+				     string path,
+				     string filename,
+				     string caption,
+				     string description,
+				     bool autorotate)
+		{
+			FormClient client = new FormClient (cookies);
+
+			client.Add ("g2_form[cmd]", "add-item");
+			client.Add ("g2_form[protocol_version]", "2.10");
+			client.Add ("g2_form[set_albumName]", album.Name);
+			client.Add ("g2_form[caption]", caption);
+			client.Add ("g2_form[userfile_name]", filename);
+			client.Add ("g2_form[force_filename]", filename);
+			client.Add ("g2_form[auto_rotate]", autorotate ? "yes" : "no");
+			client.Add ("g2_form[extrafield.Description]", description);
+			client.Add ("g2_userfile", new FileInfo (path));
+			client.expect_continue = expect_continue;
+			AddG2Specific (client);
+
+			return ParseAddItem (client.Submit (Uri, Progress));
+		}
+
+		/*
+		public override Album AlbumProperties (string album)
+		{
+			FormClient client = new FormClient (cookies);
+			client.Add ("cmd", "album-properties");
+			client.Add ("protocol_version", "2.3");
+			client.Add ("set_albumName", album);
+
+			return ParseAlbumProperties (client.Submit (uri));
+		}
+		*/
+
+		public override bool NewAlbum (string parent_name,
+				      string name,
+				      string title,
+				      string description)
+		{
+			FormClient client = new FormClient (cookies);
+			client.Multipart = true;
+			client.Add ("g2_form[cmd]", "new-album");
+			client.Add ("g2_form[protocol_version]", "2.10");
+			client.Add ("g2_form[set_albumName]", parent_name);
+			client.Add ("g2_form[newAlbumName]", name);
+			client.Add ("g2_form[newAlbumTitle]", title);
+			client.Add ("g2_form[newAlbumDesc]", description);
+			AddG2Specific (client);
+
+			return ParseNewAlbum (client.Submit (Uri));
+		}
+
+		public override List<Image> FetchAlbumImages (Album album, bool include_ablums)
+		{
+			FormClient client = new FormClient (cookies);
+			client.Add ("g2_form[cmd]", "fetch-album-images");
+			client.Add ("g2_form[protocol_version]", "2.10");
+			client.Add ("g2_form[set_albumName]", album.Name);
+			client.Add ("g2_form[albums_too]", include_ablums ? "yes" : "no");
+			AddG2Specific (client);
+
+			album.Images = ParseFetchAlbumImages (client.Submit (Uri), album);
+			return album.Images;
+		}
+
+		public override List<Album> FetchAlbumsPrune ()
+		{
+			FormClient client = new FormClient (cookies);
+			client.Add ("g2_form[cmd]", "fetch-albums-prune");
+			client.Add ("g2_form[protocol_version]", "2.10");
+			client.Add ("g2_form[check_writable]", "no");
+			AddG2Specific (client);
+
+			List<Album> a = ParseFetchAlbums (client.Submit (Uri));
+			a.Sort ();
+			return a;
+		}
+
+		private void AddG2Specific (FormClient client)
+		{
+			if (AuthToken != null && AuthToken != String.Empty)
+				client.Add ("g2_authToken", AuthToken);
+			client.Add ("g2_controller", "remote.GalleryRemote");
+		}
+
+		public List<Image> ParseFetchAlbumImages (HttpWebResponse response, Album album)
+		{
+			string [] data;
+			StreamReader reader = null;
+			ResultCode status = ResultCode.UnknownResponse;
+			string status_text = "Error: Unable to parse server response";
+			try {
+				Image current_image = null;
+				string baseUrl = Uri.ToString () + "?g2_view=core.DownloadItem&g2_itemId=";
+				reader = findResponse (response);
+				while ((data = GetNextLine (reader)) != null) {
+					if (data [0] == "status")
+						status = (ResultCode)int.Parse (data [1]);
+					else if (data [0].StartsWith ("status_text")) {
+						status_text = data [1];
+						Log.DebugFormat ("StatusText : {0}", data [1]);
+					} else if (data [0].StartsWith ("image.name")) {
+						//for G2 this is the number used to download the image.
+						current_image = new Image (album, "awaiting 'title'");
+						album.Images.Add (current_image);
+						current_image.Url = baseUrl + data [1];
+					} else if (data [0].StartsWith ("image.title"))
+						//for G2 the "title" is the name"
+						current_image.Name = data [1];
+					else if (data [0].StartsWith ("image.raw_width"))
+						current_image.RawWidth = int.Parse (data [1]);
+					else if (data [0].StartsWith ("image.raw_height"))
+						current_image.RawHeight = int.Parse (data [1]);
+					else if (data [0].StartsWith ("image.raw_height"))
+						current_image.RawHeight = int.Parse (data [1]);
+					//ignore these for now
+					else if (data [0].StartsWith ("image.raw_filesize")) {
+					} else if (data [0].StartsWith ("image.forceExtension")) {
+					} else if (data [0].StartsWith ("image.capturedate.year")) {
+					} else if (data [0].StartsWith ("image.capturedate.mon")) {
+					} else if (data [0].StartsWith ("image.capturedate.mday")) {
+					} else if (data [0].StartsWith ("image.capturedate.hours")) {
+					} else if (data [0].StartsWith ("image.capturedate.minutes")) {
+					} else if (data [0].StartsWith ("image.capturedate.seconds")) {
+					} else if (data [0].StartsWith ("image.hidden")) {
+					} else if (data [0].StartsWith ("image.resizedName"))
+						current_image.ResizedName = data [1];
+					else if (data [0].StartsWith ("image.resized_width"))
+						current_image.ResizedWidth = int.Parse (data [1]);
+					else if (data [0].StartsWith ("image.resized_height"))
+						current_image.ResizedHeight = int.Parse (data [1]);
+					else if (data [0].StartsWith ("image.thumbName"))
+						current_image.ThumbName = data [1];
+					else if (data [0].StartsWith ("image.thumb_width"))
+						current_image.ThumbWidth = int.Parse (data [1]);
+					else if (data [0].StartsWith ("image.thumb_height"))
+						current_image.ThumbHeight = int.Parse (data [1]);
+					else if (data [0].StartsWith ("image.caption"))
+						current_image.Caption = data [1];
+					else if (data [0].StartsWith ("image.extrafield.Description"))
+						current_image.Description = data [1];
+					else if (data [0].StartsWith ("image.clicks"))
+						try {
+							current_image.Clicks = int.Parse (data [1]);
+						} catch (System.FormatException) {
+							current_image.Clicks = 0;
+						}
+					else if (data [0].StartsWith ("baseurl"))
+						album.BaseURL = data [1];
+					else if (data [0].StartsWith ("image_count"))
+					if (album.Images.Count != int.Parse (data [1]))
+						Log.Warning ("Parsed image count for " + album.Name + "(" + album.Images.Count + ") does not match image_count (" + data [1] + ").  Something is amiss");
+					else
+						Log.DebugFormat ("Unparsed Line in ParseFetchAlbumImages(): {0}={1}", data [0], data [1]);
+				}
+				Log.DebugFormat ("Found: {0} cookies", response.Cookies.Count);
+				if (status != ResultCode.Success) {
+					Log.Debug (status_text);
+					throw new GalleryCommandException (status_text, status);
+				}
+
+				return album.Images;
+
+			} finally {
+				if (reader != null)
+					reader.Close ();
+
+				response.Close ();
+			}
+		}
+
+		public override string GetAlbumUrl (Album album)
+		{
+			return Uri.ToString () + "?g2_view=core.ShowItem&g2_itemId=" + album.Name;
+		}
+	}
+}
diff --git a/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/GalleryAccount.cs b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/GalleryAccount.cs
index 6b1a757..b66427e 100644
--- a/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/GalleryAccount.cs
+++ b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/GalleryAccount.cs
@@ -27,23 +27,9 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-using System;
-using System.Net;
-using System.IO;
-using System.Text;
-using System.Collections;
-using System.Collections.Specialized;
-using System.Web;
 using Mono.Unix;
-using FSpot;
-using FSpot.Core;
-using FSpot.Filters;
-using FSpot.Widgets;
-using FSpot.Utils;
-using FSpot.UI.Dialog;
-using FSpot.Extensions;
+
 using Hyena;
-using Hyena.Widgets;
 
 namespace FSpot.Exporters.Gallery
 {
@@ -51,16 +37,15 @@ namespace FSpot.Exporters.Gallery
 		public GalleryAccount (string name, string url, string username, string password) : this (name, url, username, password, GalleryVersion.VersionUnknown) {}
 		public GalleryAccount (string name, string url, string username, string password, GalleryVersion version)
 		{
-			this.name = name;
+			this.Name = name;
 			this.username = username;
 			this.password = password;
 			this.Url = url;
 
-			if (version != GalleryVersion.VersionUnknown) {
-				this.version = version;
-			} else {
-				this.version = Gallery.DetectGalleryVersion(Url);
-			}
+			if (version != GalleryVersion.VersionUnknown)
+				this.Version = version;
+			else
+				this.Version = Gallery.DetectGalleryVersion(Url);
 		}
 
 		public const string EXPORT_SERVICE = "gallery/";
@@ -71,42 +56,38 @@ namespace FSpot.Exporters.Gallery
 			//System.Console.WriteLine ("GalleryAccount.Connect()");
 			Gallery gal = null;
 
-			if (version == GalleryVersion.VersionUnknown)
-				this.version = Gallery.DetectGalleryVersion(Url);
+			if (Version == GalleryVersion.VersionUnknown)
+				this.Version = Gallery.DetectGalleryVersion(Url);
 
-			if (version == GalleryVersion.Version1) {
+			if (Version == GalleryVersion.Version1)
 				gal = new Gallery1 (url, url);
-			} else if (version == GalleryVersion.Version2) {
+			else if (Version == GalleryVersion.Version2)
 				gal = new Gallery2 (url, url);
-			} else {
+			else
 				throw new GalleryException (Catalog.GetString("Cannot connect to a Gallery for which the version is unknown.\nPlease check that you have Remote plugin 1.0.8 or later"));
-			}
 
 			Log.Debug ("Gallery created: " + gal);
 
 			gal.Login (username, password);
 
-			gallery = gal;
+			Gallery = gal;
 			connected = true;
 
-			gallery.expect_continue = Preferences.Get<bool> (LIGHTTPD_WORKAROUND_KEY);
+			Gallery.expect_continue = Preferences.Get<bool> (LIGHTTPD_WORKAROUND_KEY);
 
-			return gallery;
+			return Gallery;
 		}
 
-		GalleryVersion version;
-		public GalleryVersion Version{
-			get {
-				return version;
-			}
-		}
+		public GalleryVersion Version{ get; private set; }
+		public Gallery Gallery { get; private set; }
+		public string Name { get; set; }
 
 		private bool connected;
 		public bool Connected {
 			get {
 				bool retVal = false;
-				if(gallery != null) {
-					retVal = gallery.IsConnected ();
+				if(Gallery != null) {
+					retVal = Gallery.IsConnected ();
 				}
 				if (connected != retVal) {
 					Log.Warning ("Connected and retVal for IsConnected() don't agree");
@@ -118,24 +99,7 @@ namespace FSpot.Exporters.Gallery
 		public void MarkChanged ()
 		{
 			connected = false;
-			gallery = null;
-		}
-
-		Gallery gallery;
-		public Gallery Gallery {
-			get {
-				return gallery;
-			}
-		}
-
-		string name;
-		public string Name {
-			get {
-				return name;
-			}
-			set {
-				name = value;
-			}
+			Gallery = null;
 		}
 
 		string url;
diff --git a/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/GalleryAccountManager.cs b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/GalleryAccountManager.cs
index c32dca6..5271941 100644
--- a/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/GalleryAccountManager.cs
+++ b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/GalleryAccountManager.cs
@@ -28,25 +28,11 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-
-using System;
-using System.Net;
-using System.IO;
-using System.Text;
-using System.Collections;
 using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Web;
-using Mono.Unix;
-using FSpot;
-using FSpot.Core;
-using FSpot.Filters;
-using FSpot.Widgets;
-using FSpot.Utils;
-using FSpot.UI.Dialog;
-using FSpot.Extensions;
+using System.IO;
+
 using Hyena;
-using Hyena.Widgets;
+
 namespace FSpot.Exporters.Gallery
 {
 	public class GalleryAccountManager
@@ -63,7 +49,6 @@ namespace FSpot.Exporters.Gallery
 			if (instance == null) {
 				instance = new GalleryAccountManager ();
 			}
-
 			return instance;
 		}
 
@@ -76,12 +61,7 @@ namespace FSpot.Exporters.Gallery
 			ReadAccounts ();
 		}
 
-		public void MarkChanged ()
-		{
-			MarkChanged (true, null);
-		}
-
-		public void MarkChanged (bool write, GalleryAccount changed_account)
+		public void MarkChanged (bool write = true, GalleryAccount changed_account = null)
 		{
 			if (write)
 				WriteAccounts ();
@@ -95,12 +75,7 @@ namespace FSpot.Exporters.Gallery
 			return accounts;
 		}
 
-		public void AddAccount (GalleryAccount account)
-		{
-			AddAccount (account, true);
-		}
-
-		public void AddAccount (GalleryAccount account, bool write)
+		public void AddAccount (GalleryAccount account, bool write = true)
 		{
 			accounts.Add (account);
 			MarkChanged (write, account);
diff --git a/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/GalleryAddAlbum.cs b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/GalleryAddAlbum.cs
index c86a647..b7bd0ac 100644
--- a/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/GalleryAddAlbum.cs
+++ b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/GalleryAddAlbum.cs
@@ -27,24 +27,12 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-
 using System;
-using System.Net;
-using System.IO;
-using System.Text;
-using System.Collections;
-using System.Collections.Specialized;
-using System.Web;
+
 using Mono.Unix;
-using FSpot;
-using FSpot.Core;
-using FSpot.Filters;
-using FSpot.Widgets;
-using FSpot.Utils;
-using FSpot.UI.Dialog;
-using FSpot.Extensions;
-using Hyena;
+
 using Hyena.Widgets;
+
 namespace FSpot.Exporters.Gallery
 {
 	public class GalleryAddAlbum
@@ -102,9 +90,9 @@ namespace FSpot.Exporters.Gallery
 				for (int i=0; i < album.Parents.Count; i++) {
 					label_builder.Append ("  ");
 				}
-				label_builder.Append (album.Title);
 
-                album_optionmenu.AppendText(label_builder.ToString());
+				label_builder.Append (album.Title);
+				album_optionmenu.AppendText(label_builder.ToString());
 			}
 
 			album_optionmenu.Sensitive = true;
@@ -113,19 +101,17 @@ namespace FSpot.Exporters.Gallery
 
 		private void HandleChanged (object sender, EventArgs args)
 		{
-			if (gallery.Version == GalleryVersion.Version1) {
-				if (gallery.Albums.Count == 0 || album_optionmenu.Active <= 0) {
+			if (gallery.Version == GalleryVersion.Version1)
+				if (gallery.Albums.Count == 0 || album_optionmenu.Active <= 0)
 					parent = String.Empty;
-				} else {
+				else
 					parent = ((Album) gallery.Albums [album_optionmenu.Active-1]).Name;
-				}
-			} else {
-				if (gallery.Albums.Count == 0 || album_optionmenu.Active < 0) {
+			else
+				if (gallery.Albums.Count == 0 || album_optionmenu.Active < 0)
 					parent = String.Empty;
-				} else {
+				else
 					parent = ((Album) gallery.Albums [album_optionmenu.Active]).Name;
-				}
-			}
+
 			name = name_entry.Text;
 			description = description_entry.Text;
 			title = title_entry.Text;
diff --git a/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/GalleryExceptions.cs b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/GalleryExceptions.cs
new file mode 100644
index 0000000..9475a95
--- /dev/null
+++ b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/GalleryExceptions.cs
@@ -0,0 +1,51 @@
+//  GalleryExceptions.cs
+// 
+//  Author:
+//       Stephen Shaw <sshaw decriptor com>
+// 
+//  Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany.
+// 
+//  Permission is hereby granted, free of charge, to any person obtaining
+//  a copy of this software and associated documentation files (the
+//  "Software"), to deal in the Software without restriction, including
+//  without limitation the rights to use, copy, modify, merge, publish,
+//  distribute, sublicense, and/or sell copies of the Software, and to
+//  permit persons to whom the Software is furnished to do so, subject to
+//  the following conditions:
+// 
+//  The above copyright notice and this permission notice shall be
+//  included in all copies or substantial portions of the Software.
+// 
+//  THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND,
+//  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+//  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+//  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+//  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+//  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+//  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//  
+
+namespace FSpot.Exporters.Gallery
+{
+	public class GalleryException : System.Exception
+	{
+		public string ResponseText { get; private set; }
+
+		public GalleryException (string text) : base (text) { }
+
+		public GalleryException (string text, string full_response) : base (text)
+		{
+			ResponseText = full_response;
+		}
+	}
+
+	public class GalleryCommandException : GalleryException
+	{
+		public ResultCode Status { get; private set; }
+
+		public GalleryCommandException (string status_text, ResultCode result) : base (status_text)
+		{
+			Status = result;
+		}
+	}
+}
diff --git a/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/GalleryExport.cs b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/GalleryExport.cs
index dfaaf06..25506ab 100644
--- a/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/GalleryExport.cs
+++ b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/GalleryExport.cs
@@ -30,21 +30,15 @@
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
+
 using System;
-using System.Net;
-using System.IO;
-using System.Text;
-using System.Collections;
 using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Web;
+
 using Mono.Unix;
 
-using FSpot;
 using FSpot.Core;
 using FSpot.Filters;
 using FSpot.Widgets;
-using FSpot.Utils;
 using FSpot.UI.Dialog;
 using FSpot.Extensions;
 
@@ -270,17 +264,12 @@ namespace FSpot.Exporters.Gallery
 			gallery_optionmenu.Active = pos;
 		}
 
-		private void Connect ()
-		{
-			Connect (null);
-		}
-
-		private void Connect (GalleryAccount selected)
+		private void Connect (GalleryAccount selected = null)
 		{
 			try {
 				if (accounts.Count != 0 && connect) {
 					if (selected == null)
-						account = (GalleryAccount)accounts [gallery_optionmenu.Active];
+						account = accounts [gallery_optionmenu.Active];
 					else
 						account = selected;
 
@@ -309,7 +298,7 @@ namespace FSpot.Exporters.Gallery
 
 		public void HandleAlbumAdded (string title)
 		{
-			GalleryAccount account = (GalleryAccount)accounts [gallery_optionmenu.Active];
+			GalleryAccount account = accounts [gallery_optionmenu.Active];
 			PopulateAlbumOptionMenu (account.Gallery);
 
 			// make the newly created album selected
diff --git a/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/GalleryRemote.cs b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/GalleryRemote.cs
index 473cfee..a225aa4 100644
--- a/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/GalleryRemote.cs
+++ b/src/Extensions/Exporters/FSpot.Exporters.Gallery/FSpot.Exporters.Gallery/GalleryRemote.cs
@@ -71,7 +71,6 @@ namespace FSpot.Exporters.Gallery
 		public int ThumbSize;
 		public List<Image> Images;
 		public string BaseURL = String.Empty;
-		Gallery gallery;
 		public AlbumPermission Perms = AlbumPermission.None;
 
 		public Album Parent {
@@ -99,21 +98,19 @@ namespace FSpot.Exporters.Gallery
 			}
 		}
 
-		public Gallery Gallery {
-			get { return gallery; }
-		}
+		public Gallery Gallery { get; private set; }
 
 		public Album (Gallery gallery, string name, int ref_num)
 		{
 			Name = name;
-			this.gallery = gallery;
+			Gallery = gallery;
 			this.RefNum = ref_num;
 			Images = new List<Image> ();
 		}
 
 		public void Rename (string name)
 		{
-			gallery.MoveAlbum (this, name);
+			Gallery.MoveAlbum (this, name);
 		}
 
 		public void Add (IPhoto item)
@@ -126,7 +123,7 @@ namespace FSpot.Exporters.Gallery
 			if (item == null)
 				Log.Warning ("NO PHOTO");
 
-			return gallery.AddItem (this,
+			return Gallery.AddItem (this,
 					 path,
 					 Path.GetFileName (item.DefaultVersion.Uri.LocalPath),
 					 item.Name,
@@ -136,7 +133,7 @@ namespace FSpot.Exporters.Gallery
 
 		public string GetUrl ()
 		{
-			return gallery.GetAlbumUrl(this);
+			return Gallery.GetAlbumUrl(this);
 		}
 
 		public int CompareTo (Object obj)
@@ -233,940 +230,6 @@ namespace FSpot.Exporters.Gallery
 		UnknownResponse = 1000
 	}
 
-	#region Exceptions
-	public class GalleryException : System.Exception {
-		public string ResponseText { get; private set; }
-
-		public GalleryException (string text) : base (text) { }
-
-		public GalleryException (string text, string full_response) : base (text)
-		{
-			ResponseText = full_response;
-		}
-	}
-
-	public class GalleryCommandException : GalleryException {
-		public ResultCode Status { get; private set; }
-
-		public GalleryCommandException (string status_text, ResultCode result) : base (status_text) {
-			Status = result;
-		}
-
-
-	}
-	#endregion
-
-	public abstract class Gallery
-	{
-		#region Properties
-		protected Uri uri;
-		public Uri Uri{
-			get {
-				return uri;
-			}
-		}
-
-		protected string name;
-		public string Name {
-			get {
-				return name;
-			}
-			set {
-				name = value;
-			}
-		}
-
-		string auth_token;
-		public string AuthToken {
-			get {
-				return auth_token;
-			}
-			set {
-				auth_token = value;
-			}
-		}
-
-		protected GalleryVersion version;
-		public GalleryVersion Version {
-			get {
-				return version;
-			}
-		}
-
-		protected List<Album> albums;
-		public List<Album> Albums{
-			get {
-				return albums;
-			}
-		}
-		#endregion
-
-		public bool expect_continue = true;
-		protected CookieContainer cookies = null;
-		public FSpot.ProgressItem Progress = null;
-
-		public abstract void Login (string username, string passwd);
-		public abstract List<Album> FetchAlbums ();
-		public abstract List<Album> FetchAlbumsPrune ();
-		public abstract bool MoveAlbum (Album album, string end_name);
-		public abstract int AddItem (Album album, string path, string filename, string caption, string description, bool autorotate);
-		//public abstract Album AlbumProperties (string album);
-		public abstract bool NewAlbum (string parent_name, string name, string title, string description);
-		public abstract List<Image> FetchAlbumImages (Album album, bool include_ablums);
-
-		public abstract string GetAlbumUrl (Album album);
-
-		public Gallery (string name)
-		{
-			Name = name;
-			cookies = new CookieContainer ();
-			albums = new List<Album> ();
-		}
-
-		public static GalleryVersion DetectGalleryVersion (string url)
-		{
-			//Figure out if the url is for G1 or G2
-			Log.Debug ("Detecting Gallery version");
-
-			GalleryVersion version;
-
-			if (url.EndsWith (Gallery1.script_name)) {
-				version = GalleryVersion.Version1;
-			} else if (url.EndsWith (Gallery2.script_name)) {
-				version = GalleryVersion.Version2;
-			} else {
-				//check what script is available on the server
-				FormClient client = new FormClient ();
-
-				try {
-					client.Submit (new Uri (Gallery.FixUrl (url, Gallery1.script_name)));
-					version =  GalleryVersion.Version1;
-
-				} catch (System.Net.WebException) {
-					try {
-						client.Submit (new Uri (Gallery.FixUrl (url, Gallery2.script_name)));
-						version =  GalleryVersion.Version2;
-
-					} catch (System.Net.WebException) {
-						//Uh oh, neither version detected
-						version = GalleryVersion.VersionUnknown;
-					}
-				}
-			}
-
-			Log.Debug ("Detected: " + version.ToString());
-			return version;
-		}
-
-
-		public bool IsConnected ()
-		{
-
-			bool retVal = true;
-			//Console.WriteLine ("^^^^^^^Checking IsConnected");
-			foreach (Cookie cookie in cookies.GetCookies(Uri)) {
-				bool isExpired = cookie.Expired;
-				//Console.WriteLine (cookie.Name + " " + (isExpired ? "expired" : "valid"));
-				if (isExpired)
-					retVal = false;
-			}
-			//return cookies.GetCookies(Uri).Count > 0;
-			return retVal;
-		}
-
-		//Reads until it finds the start of the response
-		protected StreamReader findResponse (HttpWebResponse response)
-		{
-			StreamReader reader = new StreamReader (response.GetResponseStream (), Encoding.UTF8);
-			if (reader == null)
-				throw new GalleryException (Catalog.GetString ("Error reading server response"));
-
-			string line;
-			string full_response = null;
-			while ((line = reader.ReadLine ()) != null) {
-				full_response += line;
-				if (line.IndexOf ("#__GR2PROTO__", 0) > -1)
-					break;
-			}
-
-			if (line == null) {
-				// failed to find the response
-				throw new GalleryException (Catalog.GetString ("Server returned response without Gallery content"), full_response);
-			}
-			return reader;
-		}
-
-		protected string [] GetNextLine (StreamReader reader)
-		{
-			char [] value_split = new char [1] {'='};
-			bool haveLine = false;
-			string[] array = null;
-			while(!haveLine) {
-				string line = reader.ReadLine ();
-				//Console.WriteLine ("READING: " + line);
-				if (line != null) {
-					array = line.Split (value_split, 2);
-					haveLine = !LineIgnored (array);
-				}
-				else {
-					//end of input
-					return null;
-				}
-			}
-			return array;
-		}
-
-		private bool LineIgnored (string[] line)
-		{
-			if (line[0].StartsWith ("debug") || line[0].StartsWith ("can_create_root"))
-				return true;
-			return false;
-		}
-
-		protected bool ParseLogin (HttpWebResponse response)
-		{
-			string [] data;
-			StreamReader reader = null;
-			ResultCode status = ResultCode.UnknownResponse;
-			string status_text = "Error: Unable to parse server response";
-			try {
-				reader = findResponse (response);
-				while ((data = GetNextLine (reader)) != null) {
-					if (data[0] == "status") {
-						status = (ResultCode) int.Parse (data [1]);
-					} else if (data[0].StartsWith ("status_text")) {
-						status_text = data[1];
-						Log.DebugFormat ("StatusText : {0}", data[1]);
-					} else if (data[0].StartsWith ("server_version")) {
-						//FIXME we should use the to determine what capabilities the server has
-					} else if (data[0].StartsWith ("auth_token")) {
-						AuthToken = data[1];
-					} else {
-						Log.DebugFormat ("Unparsed Line in ParseLogin(): {0}={1}", data[0], data[1]);
-					}
-				}
-
-				//Console.WriteLine ("Found: {0} cookies", response.Cookies.Count);
-				if (status != ResultCode.Success) {
-					Log.Debug (status_text);
-					throw new GalleryCommandException (status_text, status);
-				}
-				return true;
-			} finally {
-				if (reader != null)
-					reader.Close ();
-				response.Close ();
-			}
-		}
-
-		public List<Album> ParseFetchAlbums (HttpWebResponse response)
-		{
-			//Console.WriteLine ("in ParseFetchAlbums()");
-			string [] data;
-			StreamReader reader = null;
-			ResultCode status = ResultCode.UnknownResponse;
-			string status_text = "Error: Unable to parse server response";
-			albums = new List<Album> ();
-			try {
-
-				Album current_album = null;
-				reader = findResponse (response);
-				while ((data = GetNextLine (reader)) != null) {
-					//Console.WriteLine ("Parsing Line: {0}={1}", data[0], data[1]);
-					if (data[0] == "status") {
-						status = (ResultCode) int.Parse (data [1]);
-					} else if (data[0].StartsWith ("status_text")) {
-						status_text = data[1];
-						Log.DebugFormat ("StatusText : {0}", data[1]);
-					} else if (data[0].StartsWith ("album.name")) {
-						//this is the URL name
-						int ref_num = -1;
-						if (this.Version == GalleryVersion.Version1) {
-							string [] segments = data[0].Split (new char[1]{'.'});
-							ref_num = int.Parse (segments[segments.Length -1]);
-						} else {
-							ref_num = int.Parse (data[1]);
-						}
-						current_album = new Album (this, data[1], ref_num);
-						Albums.Add (current_album);
-						//Console.WriteLine ("current_album: " + data[1]);
-					} else if (data[0].StartsWith ("album.title")) {
-						//this is the display name
-						current_album.Title = data[1];
-					} else if (data[0].StartsWith ("album.summary")) {
-						current_album.Summary = data[1];
-					} else if (data[0].StartsWith ("album.parent")) {
-						//FetchAlbums and G2 FetchAlbumsPrune return ints
-						//G1 FetchAlbumsPrune returns album names (and 0 for root albums)
-						try {
-							current_album.ParentRefNum = int.Parse (data[1]);
-						} catch (System.FormatException) {
-							current_album.ParentRefNum = LookupAlbum (data[1]).RefNum;
-						}
-						//Console.WriteLine ("album.parent data[1]: " + data[1]);
-					} else if (data[0].StartsWith ("album.resize_size")) {
-						current_album.ResizeSize = int.Parse (data[1]);
-					} else if (data[0].StartsWith ("album.thumb_size")) {
-						current_album.ThumbSize = int.Parse (data[1]);
-					} else if (data[0].StartsWith ("album.info.extrafields")) {
-						//ignore, this is the album description
-					} else if (data[0].StartsWith ("album.perms.add")) {
-						if (data[1] == "true")
-							current_album.Perms |= AlbumPermission.Add;
-					} else if (data[0].StartsWith ("album.perms.write")) {
-						if (data[1] == "true")
-							current_album.Perms |= AlbumPermission.Write;
-					} else if (data[0].StartsWith ("album.perms.del_item")) {
-						if (data[1] == "true")
-							current_album.Perms |= AlbumPermission.Delete;
-					} else if (data[0].StartsWith ("album.perms.del_alb")) {
-						if (data[1] == "true")
-							current_album.Perms |= AlbumPermission.DeleteAlbum;
-					} else if (data[0].StartsWith ("album.perms.create_sub")) {
-						if (data[1] == "true")
-							current_album.Perms |= AlbumPermission.CreateSubAlbum;
-					} else if (data[0].StartsWith ("album_count")) {
-						if (Albums.Count != int.Parse (data[1]))
-							Log.Warning ("Parsed album count does not match album_count.  Something is amiss");
-					} else if (data[0].StartsWith ("auth_token")) {
-						AuthToken = data [1];
-					} else {
-						Log.DebugFormat ("Unparsed Line in ParseFetchAlbums(): {0}={1}", data[0], data[1]);
-					}
-				}
-				//Console.WriteLine ("Found: {0} cookies", response.Cookies.Count);
-				if (status != ResultCode.Success) {
-					Log.Debug (status_text);
-					throw new GalleryCommandException (status_text, status);
-				}
-
-				//Console.WriteLine (After parse albums.Count + " albums parsed");
-				return Albums;
-			} finally {
-				if (reader != null)
-					reader.Close ();
-				response.Close ();
-			}
-		}
-
-		public int ParseAddItem (HttpWebResponse response)
-		{
-			string [] data;
-			StreamReader reader = null;
-			ResultCode status = ResultCode.UnknownResponse;
-			string status_text = "Error: Unable to parse server response";
-			int item_id = 0;
-			try {
-				reader = findResponse (response);
-				while ((data = GetNextLine (reader)) != null) {
-					if (data[0] == "status") {
-						status = (ResultCode) int.Parse (data [1]);
-					} else if (data[0].StartsWith ("status_text")) {
-						status_text = data[1];
-						Log.DebugFormat ("StatusText : {0}", data[1]);
-					} else if (data[0].StartsWith ("auth_token")) {
-						AuthToken = data[1];
-					} else if (data[0].StartsWith ("item_name")) {
-						item_id = int.Parse (data [1]);
-					} else {
-						Log.DebugFormat ("Unparsed Line in ParseAddItem(): {0}={1}", data[0], data[1]);
-					}
-				}
-				//Console.WriteLine ("Found: {0} cookies", response.Cookies.Count);
-				if (status != ResultCode.Success) {
-					Log.Debug (status_text);
-					throw new GalleryCommandException (status_text, status);
-				}
-
-				return item_id;
-			} finally {
-				if (reader != null)
-					reader.Close ();
-				response.Close ();
-			}
-		}
-
-		public bool ParseNewAlbum (HttpWebResponse response)
-		{
-			return ParseBasic (response);
-		}
-
-		public bool ParseMoveAlbum (HttpWebResponse response)
-		{
-			return ParseBasic (response);
-		}
-		/*
-		public Album ParseAlbumProperties (HttpWebResponse response)
-		{
-			string [] data;
-			StreamReader reader = null;
-			ResultCode status = ResultCode.UnknownResponse;
-			string status_text = "Error: Unable to parse server response";
-			try {
-
-				reader = findResponse (response);
-				while ((data = GetNextLine (reader)) != null) {
-					if (data[0] == "status") {
-						status = (ResultCode) int.Parse (data [1]);
-					} else if (data[0].StartsWith ("status_text")) {
-						status_text = data[1];
-						Log.Debug ("StatusText : {0}", data[1]);
-					} else if (data[0].StartsWith ("auto-resize")) {
-						//ignore
-					} else {
-						Log.Debug ("Unparsed Line in ParseBasic(): {0}={1}", data[0], data[1]);
-					}
-				}
-				//Console.WriteLine ("Found: {0} cookies", response.Cookies.Count);
-				if (status != ResultCode.Success) {
-					Log.Debug (status_text);
-					throw new GalleryCommandException (status_text, status);
-				}
-
-				return true;
-			} finally {
-				if (reader != null)
-					reader.Close ();
-
-				response.Close ();
-			}
-		}
-		*/
-
-		private bool ParseBasic (HttpWebResponse response)
-		{
-			string [] data;
-			StreamReader reader = null;
-			ResultCode status = ResultCode.UnknownResponse;
-			string status_text = "Error: Unable to parse server response";
-			try {
-				reader = findResponse (response);
-				while ((data = GetNextLine (reader)) != null) {
-					if (data[0] == "status") {
-						status = (ResultCode) int.Parse (data [1]);
-					} else if (data[0].StartsWith ("status_text")) {
-						status_text = data[1];
-						Log.DebugFormat ("StatusText : {0}", data[1]);
-					} else if (data[0].StartsWith ("auth_token")) {
-						AuthToken = data[1];
-					} else {
-						Log.DebugFormat ("Unparsed Line in ParseBasic(): {0}={1}", data[0], data[1]);
-					}
-				}
-				//Console.WriteLine ("Found: {0} cookies", response.Cookies.Count);
-				if (status != ResultCode.Success) {
-					Log.Debug (status_text + " Status: " + status);
-					throw new GalleryCommandException (status_text, status);
-				}
-
-				return true;
-			} finally {
-				if (reader != null)
-					reader.Close ();
-				response.Close ();
-			}
-		}
-
-		public Album LookupAlbum (string name)
-		{
-			Album match = null;
-
-			foreach (Album album in Albums) {
-				if (album.Name == name) {
-					match = album;
-					break;
-				}
-			}
-			return match;
-		}
-
-		public Album LookupAlbum (int ref_num)
-		{
-			// FIXME: this is really not the best way to do this
-			Album match = null;
-
-			foreach (Album album in Albums) {
-				if (album.RefNum == ref_num) {
-					match = album;
-					break;
-				}
-			}
-			return match;
-		}
-
-		public static string FixUrl(string url, string end)
-		{
-			string fixedUrl = url;
-			if (!url.EndsWith (end)) {
-				if (!url.EndsWith ("/"))
-					fixedUrl = url + "/";
-				fixedUrl = fixedUrl + end;
-			}
-			return fixedUrl;
-
-		}
-
-		public void PopupException (GalleryCommandException e, Gtk.Dialog d)
-		{
-			Log.DebugFormat ("{0} : {1} ({2})", e.Message, e.ResponseText, e.Status);
-			HigMessageDialog md =
-				new HigMessageDialog (d,
-						      Gtk.DialogFlags.Modal |
-						      Gtk.DialogFlags.DestroyWithParent,
-						      Gtk.MessageType.Error, Gtk.ButtonsType.Ok,
-						      Catalog.GetString ("Error while creating new album"),
-						      String.Format (Catalog.GetString ("The following error was encountered while attempting to perform the requested operation:\n{0} ({1})"), e.Message, e.Status));
-			md.Run ();
-			md.Destroy ();
-		}
-	}
-
-	public class Gallery1 : Gallery
-	{
-		public const string script_name = "gallery_remote2.php";
-		public Gallery1 (string url) : this (url, url) {}
-		public Gallery1 (string name, string url) : base (name)
-		{
-			uri = new Uri (FixUrl (url, script_name));
-			version = GalleryVersion.Version1;
-		}
-
-		public override void Login (string username, string passwd)
-		{
-			//Console.WriteLine ("Gallery1: Attempting to login");
-			FormClient client = new FormClient (cookies);
-
-			client.Add ("cmd", "login");
-			client.Add ("protocol_version", "2.3");
-			client.Add ("uname", username);
-			client.Add ("password", passwd);
-
-			ParseLogin (client.Submit (Uri));
-		}
-
-		public override List<Album> FetchAlbums ()
-		{
-			FormClient client = new FormClient (cookies);
-
-			client.Add ("cmd", "fetch-albums");
-			client.Add ("protocol_version", "2.3");
-
-			return ParseFetchAlbums (client.Submit (uri));
-		}
-
-
-		public override bool MoveAlbum (Album album, string end_name)
-		{
-			FormClient client = new FormClient (cookies);
-
-			client.Add ("cmd", "move-album");
-			client.Add ("protocol_version", "2.7");
-			client.Add ("set_albumName", album.Name);
-			client.Add ("set_destalbumName", end_name);
-
-			return ParseMoveAlbum (client.Submit (uri));
-		}
-
-		public override int AddItem (Album album,
-				     string path,
-				     string filename,
-				     string caption,
-				     string description,
-				     bool autorotate)
-		{
-			FormClient client = new FormClient (cookies);
-
-			client.Add ("cmd", "add-item");
-			client.Add ("protocol_version", "2.9");
-			client.Add ("set_albumName", album.Name);
-			client.Add ("caption", caption);
-			client.Add ("userfile_name", filename);
-			client.Add ("force_filename", filename);
-			client.Add ("auto_rotate", autorotate ? "yes" : "no");
-			client.Add ("userfile", new FileInfo (path));
-			client.Add ("extrafield.Description", description);
-			client.expect_continue = expect_continue;
-
-			return ParseAddItem (client.Submit (uri, Progress));
-		}
-
-		/*
-		public override Album AlbumProperties (string album)
-		{
-			FormClient client = new FormClient (cookies);
-			client.Add ("cmd", "album-properties");
-			client.Add ("protocol_version", "2.3");
-			client.Add ("set_albumName", album);
-
-			return ParseAlbumProperties (client.Submit (uri));
-		}
-		*/
-
-		public override bool NewAlbum (string parent_name,
-				      string name,
-				      string title,
-				      string description)
-		{
-			FormClient client = new FormClient (cookies);
-			client.Multipart = true;
-			client.Add ("cmd", "new-album");
-			client.Add ("protocol_version", "2.8");
-			client.Add ("set_albumName", parent_name);
-			client.Add ("newAlbumName", name);
-			client.Add ("newAlbumTitle", title);
-			client.Add ("newAlbumDesc", description);
-
-			return ParseNewAlbum (client.Submit (uri));
-		}
-
-		public override List<Image> FetchAlbumImages (Album album, bool include_ablums)
-		{
-			FormClient client = new FormClient (cookies);
-			client.Add ("cmd", "fetch-album-images");
-			client.Add ("protocol_version","2.3");
-			client.Add ("set_albumName", album.Name);
-			client.Add ("albums_too", include_ablums ? "yes" : "no");
-
-			album.Images = ParseFetchAlbumImages (client.Submit (uri), album);
-			return album.Images;
-		}
-
-		public override List<Album> FetchAlbumsPrune ()
-		{
-			FormClient client = new FormClient (cookies);
-			client.Add ("cmd", "fetch-albums-prune");
-			client.Add ("protocol_version", "2.3");
-			client.Add ("check_writable", "no");
-			List<Album> a = ParseFetchAlbums (client.Submit (uri));
-			a.Sort();
-			return a;
-		}
-
-		public List<Image> ParseFetchAlbumImages (HttpWebResponse response, Album album)
-		{
-			string [] data;
-			StreamReader reader = null;
-			ResultCode status = ResultCode.UnknownResponse;
-			string status_text = "Error: Unable to parse server response";
-			try {
-				Image current_image = null;
-				reader = findResponse (response);
-				while ((data = GetNextLine (reader)) != null) {
-					if (data[0] == "status") {
-						status = (ResultCode) int.Parse (data [1]);
-					} else if (data[0].StartsWith ("status_text")) {
-						status_text = data[1];
-						Log.DebugFormat ("StatusText : {0}", data[1]);
-					} else if (data[0].StartsWith ("image.name")) {
-						current_image = new Image (album, data[1]);
-						album.Images.Add (current_image);
-					} else if (data[0].StartsWith ("image.raw_width")) {
-						current_image.RawWidth = int.Parse (data[1]);
-					} else if (data[0].StartsWith ("image.raw_height")) {
-						current_image.RawHeight = int.Parse (data[1]);
-					} else if (data[0].StartsWith ("image.raw_height")) {
-						current_image.RawHeight = int.Parse (data[1]);
-					} else if (data[0].StartsWith ("image.raw_filesize")) {
-					} else if (data[0].StartsWith ("image.capturedate.year")) {
-					} else if (data[0].StartsWith ("image.capturedate.mon")) {
-					} else if (data[0].StartsWith ("image.capturedate.mday")) {
-					} else if (data[0].StartsWith ("image.capturedate.hours")) {
-					} else if (data[0].StartsWith ("image.capturedate.minutes")) {
-					} else if (data[0].StartsWith ("image.capturedate.seconds")) {
-					} else if (data[0].StartsWith ("image.hidden")) {
-					} else if (data[0].StartsWith ("image.resizedName")) {
-						current_image.ResizedName = data[1];
-					} else if (data[0].StartsWith ("image.resized_width")) {
-						current_image.ResizedWidth = int.Parse (data[1]);
-					} else if (data[0].StartsWith ("image.resized_height")) {
-						current_image.ResizedHeight = int.Parse (data[1]);
-					} else if (data[0].StartsWith ("image.thumbName")) {
-						current_image.ThumbName = data[1];
-					} else if (data[0].StartsWith ("image.thumb_width")) {
-						current_image.ThumbWidth = int.Parse (data[1]);
-					} else if (data[0].StartsWith ("image.thumb_height")) {
-						current_image.ThumbHeight = int.Parse (data[1]);
-					} else if (data[0].StartsWith ("image.caption")) {
-						current_image.Caption = data[1];
-					} else if (data[0].StartsWith ("image.extrafield.Description")) {
-						current_image.Description = data[1];
-					} else if (data[0].StartsWith ("image.clicks")) {
-						try {
-							current_image.Clicks = int.Parse (data[1]);
-						} catch (System.FormatException) {
-							current_image.Clicks = 0;
-						}
-					} else if (data[0].StartsWith ("baseurl")) {
-						album.BaseURL = data[1];
-					} else if (data[0].StartsWith ("image_count")) {
-						if (album.Images.Count != int.Parse (data[1]))
-							Log.Warning ("Parsed image count for " + album.Name + "(" + album.Images.Count + ") does not match image_count (" + data[1] + ").  Something is amiss");
-					} else {
-						Log.DebugFormat ("Unparsed Line in ParseFetchAlbumImages(): {0}={1}", data[0], data[1]);
-					}
-				}
-				//Console.WriteLine ("Found: {0} cookies", response.Cookies.Count);
-				if (status != ResultCode.Success) {
-					Log.Debug (status_text);
-					throw new GalleryCommandException (status_text, status);
-				}
-
-
-				//Set the Urls for downloading the images.
-				string baseUrl = album.BaseURL + "/";
-				foreach (Image image in album.Images) {
-					image.Url = baseUrl + image.Name;
-				}
-
-				return album.Images;
-			} finally {
-				if (reader != null)
-					reader.Close ();
-
-				response.Close ();
-			}
-		}
-
-		public override string GetAlbumUrl (Album album)
-		{
-			string url = Uri.ToString();
-			url = url.Remove (url.Length - script_name.Length, script_name.Length);
-
-			string path = album.Name;
-
-			url = url + path;
-			url = url.Replace (" ", "+");
-			return url;
-		}
-
-
-	}
-	public class Gallery2 : Gallery
-	{
-		public const string script_name = "main.php";
-
-		public Gallery2 (string url) : this (url, url) {}
-		public Gallery2 (string name, string url) : base (name)
-		{
-			this.uri = new Uri (FixUrl (url, script_name));
-			version = GalleryVersion.Version2;
-		}
-
-		public override void Login (string username, string passwd)
-		{
-			Log.Debug ("Gallery2: Attempting to login");
-			FormClient client = new FormClient (cookies);
-
-			client.Add ("g2_form[cmd]", "login");
-			client.Add ("g2_form[protocol_version]", "2.10");
-			client.Add ("g2_form[uname]", username);
-			client.Add ("g2_form[password]", passwd);
-			AddG2Specific (client);
-
-			ParseLogin (client.Submit (uri));
-		}
-
-		public override List<Album> FetchAlbums ()
-		{
-			//FetchAlbums doesn't exist for G2, we have to use FetchAlbumsPrune()
-			return FetchAlbumsPrune ();
-		}
-
-
-		public override bool MoveAlbum (Album album, string end_name)
-		{
-			FormClient client = new FormClient (cookies);
-
-			client.Add ("g2_form[cmd]", "move-album");
-			client.Add ("g2_form[protocol_version]", "2.10");
-			client.Add ("g2_form[set_albumName]", album.Name);
-			client.Add ("g2_form[set_destalbumName]", end_name);
-			AddG2Specific (client);
-
-			return ParseMoveAlbum (client.Submit (uri));
-		}
-
-		public override int AddItem (Album album,
-				     string path,
-				     string filename,
-				     string caption,
-				     string description,
-				     bool autorotate)
-		{
-			FormClient client = new FormClient (cookies);
-
-			client.Add ("g2_form[cmd]", "add-item");
-			client.Add ("g2_form[protocol_version]", "2.10");
-			client.Add ("g2_form[set_albumName]", album.Name);
-			client.Add ("g2_form[caption]", caption);
-			client.Add ("g2_form[userfile_name]", filename);
-			client.Add ("g2_form[force_filename]", filename);
-			client.Add ("g2_form[auto_rotate]", autorotate ? "yes" : "no");
-			client.Add ("g2_form[extrafield.Description]", description);
-			client.Add ("g2_userfile", new FileInfo (path));
-			client.expect_continue = expect_continue;
-			AddG2Specific (client);
-
-			return ParseAddItem (client.Submit (uri, Progress));
-		}
-
-		/*
-		public override Album AlbumProperties (string album)
-		{
-			FormClient client = new FormClient (cookies);
-			client.Add ("cmd", "album-properties");
-			client.Add ("protocol_version", "2.3");
-			client.Add ("set_albumName", album);
-
-			return ParseAlbumProperties (client.Submit (uri));
-		}
-		*/
-
-		public override bool NewAlbum (string parent_name,
-				      string name,
-				      string title,
-				      string description)
-		{
-			FormClient client = new FormClient (cookies);
-			client.Multipart = true;
-			client.Add ("g2_form[cmd]", "new-album");
-			client.Add ("g2_form[protocol_version]", "2.10");
-			client.Add ("g2_form[set_albumName]", parent_name);
-			client.Add ("g2_form[newAlbumName]", name);
-			client.Add ("g2_form[newAlbumTitle]", title);
-			client.Add ("g2_form[newAlbumDesc]", description);
-			AddG2Specific (client);
-
-			return ParseNewAlbum (client.Submit (uri));
-		}
-
-		public override List<Image> FetchAlbumImages (Album album, bool include_ablums)
-		{
-			FormClient client = new FormClient (cookies);
-			client.Add ("g2_form[cmd]", "fetch-album-images");
-			client.Add ("g2_form[protocol_version]","2.10");
-			client.Add ("g2_form[set_albumName]", album.Name);
-			client.Add ("g2_form[albums_too]", include_ablums ? "yes" : "no");
-			AddG2Specific (client);
-
-			album.Images = ParseFetchAlbumImages (client.Submit (uri), album);
-			return album.Images;
-		}
-
-		public override List<Album> FetchAlbumsPrune ()
-		{
-			FormClient client = new FormClient (cookies);
-			client.Add ("g2_form[cmd]", "fetch-albums-prune");
-			client.Add ("g2_form[protocol_version]", "2.10");
-			client.Add ("g2_form[check_writable]", "no");
-			AddG2Specific (client);
-
-			List<Album> a = ParseFetchAlbums (client.Submit (uri));
-			a.Sort();
-			return a;
-		}
-
-		private void AddG2Specific (FormClient client)
-		{
-			if (AuthToken != null && AuthToken != String.Empty)
-				client.Add("g2_authToken", AuthToken);
-			client.Add("g2_controller", "remote.GalleryRemote");
-		}
-
-		public List<Image> ParseFetchAlbumImages (HttpWebResponse response, Album album)
-		{
-			string [] data;
-			StreamReader reader = null;
-			ResultCode status = ResultCode.UnknownResponse;
-			string status_text = "Error: Unable to parse server response";
-			try {
-				Image current_image = null;
-				string baseUrl = Uri.ToString() + "?g2_view=core.DownloadItem&g2_itemId=";
-				reader = findResponse (response);
-				while ((data = GetNextLine (reader)) != null) {
-					if (data[0] == "status") {
-						status = (ResultCode) int.Parse (data [1]);
-					} else if (data[0].StartsWith ("status_text")) {
-						status_text = data[1];
-						Log.DebugFormat ("StatusText : {0}", data[1]);
-					} else if (data[0].StartsWith ("image.name")) {
-						//for G2 this is the number used to download the image.
-						current_image = new Image (album, "awaiting 'title'");
-						album.Images.Add (current_image);
-						current_image.Url = baseUrl + data[1];
-					} else if (data[0].StartsWith ("image.title")) {
-						//for G2 the "title" is the name"
-						current_image.Name = data[1];
-					} else if (data[0].StartsWith ("image.raw_width")) {
-						current_image.RawWidth = int.Parse (data[1]);
-					} else if (data[0].StartsWith ("image.raw_height")) {
-						current_image.RawHeight = int.Parse (data[1]);
-					} else if (data[0].StartsWith ("image.raw_height")) {
-						current_image.RawHeight = int.Parse (data[1]);
-					//ignore these for now
-					} else if (data[0].StartsWith ("image.raw_filesize")) {
-					} else if (data[0].StartsWith ("image.forceExtension")) {
-					} else if (data[0].StartsWith ("image.capturedate.year")) {
-					} else if (data[0].StartsWith ("image.capturedate.mon")) {
-					} else if (data[0].StartsWith ("image.capturedate.mday")) {
-					} else if (data[0].StartsWith ("image.capturedate.hours")) {
-					} else if (data[0].StartsWith ("image.capturedate.minutes")) {
-					} else if (data[0].StartsWith ("image.capturedate.seconds")) {
-					} else if (data[0].StartsWith ("image.hidden")) {
-					} else if (data[0].StartsWith ("image.resizedName")) {
-						current_image.ResizedName = data[1];
-					} else if (data[0].StartsWith ("image.resized_width")) {
-						current_image.ResizedWidth = int.Parse (data[1]);
-					} else if (data[0].StartsWith ("image.resized_height")) {
-						current_image.ResizedHeight = int.Parse (data[1]);
-					} else if (data[0].StartsWith ("image.thumbName")) {
-						current_image.ThumbName = data[1];
-					} else if (data[0].StartsWith ("image.thumb_width")) {
-						current_image.ThumbWidth = int.Parse (data[1]);
-					} else if (data[0].StartsWith ("image.thumb_height")) {
-						current_image.ThumbHeight = int.Parse (data[1]);
-					} else if (data[0].StartsWith ("image.caption")) {
-						current_image.Caption = data[1];
-					} else if (data[0].StartsWith ("image.extrafield.Description")) {
-						current_image.Description = data[1];
-					} else if (data[0].StartsWith ("image.clicks")) {
-						try {
-							current_image.Clicks = int.Parse (data[1]);
-						} catch (System.FormatException) {
-							current_image.Clicks = 0;
-						}
-					} else if (data[0].StartsWith ("baseurl")) {
-						album.BaseURL = data[1];
-					} else if (data[0].StartsWith ("image_count")) {
-						if (album.Images.Count != int.Parse (data[1]))
-							Log.Warning ("Parsed image count for " + album.Name + "(" + album.Images.Count + ") does not match image_count (" + data[1] + ").  Something is amiss");
-					} else {
-						Log.DebugFormat ("Unparsed Line in ParseFetchAlbumImages(): {0}={1}", data[0], data[1]);
-					}
-				}
-				Log.DebugFormat ("Found: {0} cookies", response.Cookies.Count);
-				if (status != ResultCode.Success) {
-					Log.Debug (status_text);
-					throw new GalleryCommandException (status_text, status);
-				}
-
-				return album.Images;
-
-			} finally {
-				if (reader != null)
-					reader.Close ();
-
-				response.Close ();
-			}
-		}
-
-		public override string GetAlbumUrl (Album album)
-		{
-			return Uri.ToString() + "?g2_view=core.ShowItem&g2_itemId=" + album.Name;
-		}
-
-	}
-
 	public enum GalleryVersion : byte
 	{
 		VersionUnknown = 0,
diff --git a/src/Extensions/Exporters/FSpot.Exporters.Gallery/Makefile.am b/src/Extensions/Exporters/FSpot.Exporters.Gallery/Makefile.am
index 4aa1ba9..b03736a 100644
--- a/src/Extensions/Exporters/FSpot.Exporters.Gallery/Makefile.am
+++ b/src/Extensions/Exporters/FSpot.Exporters.Gallery/Makefile.am
@@ -6,9 +6,13 @@ INSTALL_DIR = $(EXTENSIONS_INSTALL_DIR)
 SOURCES =  \
 	FSpot.Exporters.Gallery/AccountDialog.cs \
 	FSpot.Exporters.Gallery/FormClient.cs \
+	FSpot.Exporters.Gallery/Gallery.cs \
+	FSpot.Exporters.Gallery/Gallery1.cs \
+	FSpot.Exporters.Gallery/Gallery2.cs \
 	FSpot.Exporters.Gallery/GalleryAccount.cs \
 	FSpot.Exporters.Gallery/GalleryAccountManager.cs \
 	FSpot.Exporters.Gallery/GalleryAddAlbum.cs \
+	FSpot.Exporters.Gallery/GalleryExceptions.cs \
 	FSpot.Exporters.Gallery/GalleryExport.cs \
 	FSpot.Exporters.Gallery/GalleryRemote.cs
 
diff --git a/src/Extensions/Exporters/FSpotExporters.UnitTests/FSpotExporters.UnitTests.csproj b/src/Extensions/Exporters/FSpotExporters.UnitTests/FSpotExporters.UnitTests.csproj
index 94d70a1..7da149e 100644
--- a/src/Extensions/Exporters/FSpotExporters.UnitTests/FSpotExporters.UnitTests.csproj
+++ b/src/Extensions/Exporters/FSpotExporters.UnitTests/FSpotExporters.UnitTests.csproj
@@ -42,6 +42,7 @@
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <ItemGroup>
     <Folder Include="FSpot.Exporters.CD\" />
+    <Folder Include="FSpot.Exporters.Gallery\" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\FSpot.Exporters.CD\FSpot.Exporters.CD.csproj">



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]