Logo Search packages:      
Sourcecode: f-spot version File versions

SmugMugApi.cs

/*
 * SmugMugApi.cs
 *
 * Authors:
 *   Thomas Van Machelen <thomas.vanmachelen@gmail.com>
 *
 * Copyright (C) 2006 Thomas Van Machelen
 * This is free software. See COPYING for details.
 *
 */

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.IO;
using System.Xml;
using System.Collections.Specialized;

namespace SmugMugNet
{
      public struct Credentials
      {
            public string session_id;
            public int user_id;
            public string password_hash;

            public string SessionID {
                  get { return session_id; } 
                  set { session_id = value; }
            }

            public int UserID {
                  get { return user_id; } 
            }

            public string PasswordHash {
                  get { return password_hash; } 
            }

            public Credentials(string session_id, int user_id, string password_hash)
            {
                  this.session_id = session_id;
                  this.user_id = user_id;
                  this.password_hash = password_hash;
            }
      }

      public struct Category
      {
            public Category( string title, int id)
            {
                  this.title = title;
                  this.category_id = id;
            }

            private int category_id;
            public int CategoryID
            {
                  get { return category_id; }
                  set { category_id = value; }
            }

            private string title;
            public string Title
            {
                  get { return title; }
                  set { title = value; }
            }
      }

      public struct Album
      {
            public Album(string title, int id)
            {
                  this.album_id = id;
                  this.title = title;
            }

            private int album_id;
            public int AlbumID
            {
                  get { return album_id; }
                  set { album_id = value; }
            }

            private string title;
            public string Title
            {
                  get { return title; }
                  set { title = value; }
            }
      }

      public class SmugMugApi
      {
            private string username = String.Empty;
            private string password = String.Empty;
            private bool connected = false;

            private Credentials credentials;
            private const string VERSION = "1.1.1";
            private Category[] categories;

            public SmugMugApi (string email_address, string password)
            {
                  this.username = email_address;
                  this.password = password;
            }

            public bool Login ()
            {
                  if (this.username.Length == 0 | this.password.Length == 0)
                  {
                        throw new SmugMugException("There is no username or password.");
                  }

                  if (this.connected == false && this.credentials.UserID == 0)
                  {
                        try
                        {
                              this.credentials = SmugMugProxy.LoginWithPassword (this.username, this.password);
                              this.connected = true;
                        }
                        catch
                        {
                              return false;
                        }
                  }
                  else
                  {
                        LoginWithHash ();
                  }

                  return true;
            }

            private void LoginWithHash ()
            { 
                  try {
                        string session_id = SmugMugProxy.LoginWithHash (this.credentials.UserID, this.credentials.PasswordHash);
                        
                        if (session_id != null && session_id.Length > 0)
                        {
                              this.credentials.SessionID = session_id;
                        }
                        else
                        {
                              throw new SmugMugException ("SessionID was empty");
                        }
                  }
                  catch (Exception ex) {
                        throw new SmugMugException ("A login error occured, SessionID may be invalid.", ex.InnerException);
                  }
            }

            public void Logout () 
            {
                  if (!connected)
                        return; 

                  if (this.credentials.SessionID == null && this.credentials.SessionID.Length == 0)
                        return;

                  SmugMugProxy.Logout (this.credentials.SessionID);
                  connected = false;
                  this.credentials = new Credentials (null, 0, null);
            }

            public Category[] GetCategories ()
            {
                  if (this.categories == null)
                  {
                        try {
                              this.categories = SmugMugProxy.GetCategories (credentials.SessionID);
                        }
                        catch (Exception ex) {
                              throw new SmugMugException ("Could not retrieve Categories", ex.InnerException);
                        }
                  }
                  return this.categories;
            }

            public Album CreateAlbum (string title, int category_id, bool is_public)
            {
                  try {
                        return SmugMugProxy.CreateAlbum (title, category_id, credentials.SessionID, is_public);
                  }
                  catch (Exception ex) {
                        throw new SmugMugException ("Could not create album", ex.InnerException);
                  }
            }

            public Album[] GetAlbums ()
            {
                  try {
                        return SmugMugProxy.GetAlbums(credentials.SessionID);
                  }
                  catch (Exception ex) {
                        throw new SmugMugException ("Could not get albums", ex.InnerException);
                  }
            }

            public Uri GetAlbumUrl (int image_id)
            {
                  try {
                        return SmugMugProxy.GetAlbumUrl (image_id, credentials.SessionID);
                  }
                  catch (Exception ex) {
                        throw new SmugMugException ("Could not get album url", ex.InnerException);
                  }
            }

            public int Upload (string path, int album_id)
            {
                  try {
                        return SmugMugProxy.Upload (path, album_id, credentials.SessionID);
                  }
                  catch (Exception ex) {
                        throw new SmugMugException ("Could not upload file", ex.InnerException);
                  }
            }
      }

      public class SmugMugProxy
      {
            // FIXME: this getting should be done over https
            private const string GET_URL = "https://api.SmugMug.com/hack/rest/";
            private const string POST_URL = "https://upload.SmugMug.com/hack/rest/";
            // key from massis
            private const string APIKEY = "umtr0zB2wzwTZDhF2BySidg0hY0le3K6";
            private const string VERSION = "1.1.1";

            // rest methods
            private const string LOGIN_WITHPASS_METHOD = "smugmug.login.withPassword";
            private const string LOGIN_WITHHASH_METHOD = "smugmug.login.withHash";
            private const string LOGOUT_METHOD = "smugmug.logout";
            private const string ALBUMS_CREATE_METHOD = "smugmug.albums.create";
            private const string ALBUMS_GET_URLS_METHOD = "smugmug.images.getURLs";
            private const string ALBUMS_GET_METHOD = "smugmug.albums.get";
            private const string CATEGORIES_GET_METHOD = "smugmug.categories.get";

            // parameter constants
            private const string EMAIL = "EmailAddress";
            private const string PASSWORD = "Password";
            private const string USER_ID = "UserID";
            private const string PASSWORD_HASH = "PasswordHash";
            private const string SESSION_ID = "SessionID";
            private const string CATEGORY_ID = "CategoryID";
            private const string IMAGE_ID = "ImageID";
            private const string TITLE = "Title";
            private const string ID = "id";

            public static Credentials LoginWithPassword (string username, string password)
            {
                  string url = FormatGetUrl (LOGIN_WITHPASS_METHOD, new SmugMugParam (EMAIL, username), new SmugMugParam (PASSWORD, password));
                  XmlDocument doc = GetResponseXml (url);

                  string sessionId = doc.SelectSingleNode ("/rsp/Login/SessionID").InnerText;
                  int userId = int.Parse (doc.SelectSingleNode ("/rsp/Login/UserID").InnerText);
                  string passwordHash = doc.SelectSingleNode ("/rsp/Login/PasswordHash").InnerText;
                  
                  return new Credentials (sessionId, userId, passwordHash);
            }

            public static string LoginWithHash (int user_id, string password_hash)
            {
                  string url = FormatGetUrl (LOGIN_WITHHASH_METHOD, new SmugMugParam (USER_ID, user_id), new SmugMugParam (PASSWORD_HASH, password_hash));
                  XmlDocument doc = GetResponseXml(url);

                  return doc.SelectSingleNode ("/rsp/Login/SessionID").InnerText;
            }

            public static void Logout (string session_id)
            {
                  string url = FormatGetUrl (LOGOUT_METHOD, new SmugMugParam (SESSION_ID, session_id));
                  GetResponseXml (url); 
            }

            public static Album[] GetAlbums (string session_id)
            {
                  string url = FormatGetUrl (ALBUMS_GET_METHOD, new SmugMugParam(SESSION_ID, session_id));
                  XmlDocument doc = GetResponseXml (url);
                  XmlNodeList albumNodes = doc.SelectNodes ("/rsp/Albums/Album");

                  Album[] albums = new Album[albumNodes.Count];

                  for (int i = 0; i < albumNodes.Count; i++)
                  {
                        XmlNode current = albumNodes[i];
                        albums[i] = new Album (current.SelectSingleNode (TITLE).InnerText, int.Parse (current.Attributes[ID].Value));
                  }
                  return albums;
            }

            public static Uri GetAlbumUrl (int image_id, string session_id)
            {
                  string url = FormatGetUrl(ALBUMS_GET_URLS_METHOD, new SmugMugParam(IMAGE_ID, image_id), new SmugMugParam(SESSION_ID, session_id));
                  XmlDocument doc = GetResponseXml(url);

                  string album_url = doc.SelectSingleNode("/rsp/ImageURLs/Image/AlbumURL").InnerText;

                  return new Uri(album_url);
            }

            public static Category[] GetCategories (string session_id)
            {
                  string url = FormatGetUrl(CATEGORIES_GET_METHOD, new SmugMugParam (SESSION_ID, session_id));
                  XmlDocument doc = GetResponseXml (url);

                  XmlNodeList categoryNodes = doc.SelectNodes ("/rsp/Categories/Category");
                  Category[] categories = new Category[categoryNodes.Count];

                  for (int i = 0; i < categoryNodes.Count; i++)
                  {
                        XmlNode current = categoryNodes[i];
                        categories[i] = new Category (current.SelectSingleNode (TITLE).InnerText, int.Parse (current.Attributes[ID].Value));
                  }
                  return categories;
            }

            public static Album CreateAlbum (string title, int category_id, string session_id)
            {
                  return CreateAlbum (title, category_id, session_id, true);   
            }

            public static Album CreateAlbum (string title, int category_id, string session_id, bool is_public)
            {
                  int public_int = is_public ? 1 : 0;
                  string url = FormatGetUrl (ALBUMS_CREATE_METHOD, new SmugMugParam (TITLE, title), new SmugMugParam (CATEGORY_ID, category_id), new SmugMugParam (SESSION_ID, session_id), new SmugMugParam ("Public", public_int));
                  XmlDocument doc = GetResponseXml (url);

                  int id = int.Parse(doc.SelectSingleNode("/rsp/Create/Album").Attributes[ID].Value);

                  return new Album(title, id);
            }

            public static int Upload (string path, int album_id, string session_id)
            {
                  FileInfo file = new FileInfo(path);

                  if (!file.Exists)
                        throw new ArgumentException("Image does not exist: " + file.FullName);

                  try
                  {
                        WebClient client = new WebClient ();
                        client.BaseAddress = "http://upload.smugmug.com";
                        client.Headers.Add ("Cookie:SMSESS=" + session_id);

                        NameValueCollection queryStringCollection = new NameValueCollection ();
                        queryStringCollection.Add ("AlbumID", album_id.ToString());
                        queryStringCollection.Add ("ResponseType", "REST");
                        client.QueryString = queryStringCollection;

                        byte[] responseArray = client.UploadFile ("http://upload.smugmug.com/photos/xmladd.mg", "POST", file.FullName);
                        string response = Encoding.ASCII.GetString (responseArray);

                        XmlDocument doc = new XmlDocument ();
                        doc.LoadXml (response);

                        return int.Parse (doc.SelectSingleNode ("/rsp/ImageID").InnerText);
                  }
                  catch (Exception ex)
                  {
                        throw new SmugMugUploadException ("Error uploading image: " + file.FullName, ex.InnerException);
                  }
            }

            private static string FormatGetUrl(string method_name, params SmugMugParam[] parameters)
            {
                  StringBuilder builder = new StringBuilder (string.Format ("{0}{1}/?method={2}", GET_URL, VERSION, method_name));

                  foreach (SmugMugParam param in parameters)
                        builder.Append (param.ToString ());

                  builder.Append (new SmugMugParam ("APIKey", APIKEY));
                  return builder.ToString();
            }

            private static XmlDocument GetResponseXml (string url)
            {
                  HttpWebRequest request = HttpWebRequest.Create (url) as HttpWebRequest;
                  request.Credentials = CredentialCache.DefaultCredentials;
                  WebResponse response = request.GetResponse ();

                  XmlDocument doc = new XmlDocument ();
                  doc.LoadXml (new StreamReader (response.GetResponseStream ()).ReadToEnd ());
                  CheckResponseXml (doc);

                  response.Close ();
                  return doc;
            }

            private static void CheckResponseXml (XmlDocument doc)
            {
                  if (doc.SelectSingleNode("/rsp").Attributes["stat"].Value == "ok")
                        return;

                  string message = doc.SelectSingleNode ("/rsp/err").Attributes["msg"].Value;
                  throw new SmugMugException (message);
            }

            private class SmugMugParam
            {
                  string name;
                  object value;

                  public SmugMugParam (string name, object value)
                  {
                        this.name = name;
                        this.value = value;
                  }

                  public string Name 
                  {
                        get {return name;}
                  }

                  public object Value
                  {
                        get {return value;}
                  }

                  public override string ToString()
                  {
                        return string.Format("&{0}={1}", Name, Value);
                  }
            }
      }

      public class SmugMugException : ApplicationException 
      {
            public SmugMugException(string message) : base (message) 
            {
                  Console.WriteLine (message);
            }

            public SmugMugException (string message, Exception innerException) : base (message, innerException) 
            {
                  Console.WriteLine (message, innerException.ToString());
            }
      }

      public sealed class SmugMugUploadException : ApplicationException 
      {
            public SmugMugUploadException (string message, Exception innerException) : base (message, innerException) 
            {
                  Console.WriteLine (message, innerException.ToString ());
            }
      }
}

Generated by  Doxygen 1.6.0   Back to index