// // Mono.Google.Picasa.PicasaWeb.cs: // // Authors: // Gonzalo Paniagua Javier (gonzalo@ximian.com) // Stephane Delcroix (stephane@delcroix.org) // // (C) Copyright 2006 Novell, Inc. (http://www.novell.com) // (C) Copyright 2007 S. Delcroix // // 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. // // Check Picasa Web Albums Data Api at http://code.google.com/apis/picasaweb/gdata.html // using System; using System.Collections; using System.Globalization; using System.IO; using System.Net; using System.Text; using System.Xml; namespace Mono.Google.Picasa { public class PicasaWeb { GoogleConnection conn; string title; string user; string nickname; long quota_used; long quota_limit; public PicasaWeb (GoogleConnection conn) : this (conn, null) { } public PicasaWeb (GoogleConnection conn, string username) { if (conn == null) throw new ArgumentNullException ("conn"); if (conn.User == null && username == null) throw new ArgumentException ("The connection should be authenticated OR you should call this constructor with a non-null username argument"); this.conn = conn; this.user = username ?? conn.User; string received = conn.DownloadString (GDataApi.GetGalleryEntry (user)); XmlDocument doc = new XmlDocument (); doc.LoadXml (received); XmlNamespaceManager nsmgr = new XmlNamespaceManager (doc.NameTable); XmlUtil.AddDefaultNamespaces (nsmgr); XmlNode entry = doc.SelectSingleNode ("atom:entry", nsmgr); ParseGallery (entry, nsmgr); } public string Title { get { return title; } } public string User { get { return user; } } public string NickName { get { return nickname; } } public long QuotaUsed { get { return quota_used; } } public long QuotaLimit { get { return quota_limit; } } internal GoogleConnection Connection { get { return conn; } } public PicasaAlbum CreateAlbum (string title) { return CreateAlbum (title, null); } public PicasaAlbum CreateAlbum (string title, AlbumAccess access) { return CreateAlbum (title, null, access, DateTime.Now); } public PicasaAlbum CreateAlbum (string title, string description) { return CreateAlbum (title, description, AlbumAccess.Public); } public PicasaAlbum CreateAlbum (string title, string description, AlbumAccess access) { return CreateAlbum (title, description, access, DateTime.Now); } public PicasaAlbum CreateAlbum (string title, string description, AlbumAccess access, DateTime pubDate) { if (title == null) throw new ArgumentNullException ("title"); if (description == null) description = ""; if (access != AlbumAccess.Public && access != AlbumAccess.Private) throw new ArgumentException ("Invalid value.", "access"); // Check if pubDate can be in the past string url = GDataApi.GetPostURL (conn.User); if (url == null) throw new UnauthorizedAccessException ("You are not authorized to create albums."); string op_string = GetXmlForCreate (title, description, pubDate, access); byte [] op_bytes = Encoding.UTF8.GetBytes (op_string); HttpWebRequest request = conn.AuthenticatedRequest (url); request.ContentType = "application/atom+xml; charset=UTF-8"; request.Method = "POST"; Stream output_stream = request.GetRequestStream (); output_stream.Write (op_bytes, 0, op_bytes.Length); output_stream.Close (); HttpWebResponse response = (HttpWebResponse) request.GetResponse (); string received = ""; using (Stream stream = response.GetResponseStream ()) { StreamReader sr = new StreamReader (stream, Encoding.UTF8); received = sr.ReadToEnd (); } response.Close (); XmlDocument doc = new XmlDocument (); doc.LoadXml (received); XmlNamespaceManager nsmgr = new XmlNamespaceManager (doc.NameTable); XmlUtil.AddDefaultNamespaces (nsmgr); XmlNode entry = doc.SelectSingleNode ("atom:entry", nsmgr); return new PicasaAlbum (conn, null, entry, nsmgr); } /* (from gdata documentation...) Trip To Italy This was the recent trip I took to Italy. Italy public true 1152255600000 italy, vacation */ private static string GetXmlForCreate (string title, string desc, DateTime date, AlbumAccess access) { XmlUtil xml = new XmlUtil (); xml.WriteElementStringWithAttributes ("title", title, "type", "text"); xml.WriteElementStringWithAttributes ("summary", desc, "type", "text"); // location ? xml.WriteElementString ("access", access.ToString ().ToLower (CultureInfo.InvariantCulture), PicasaNamespaces.GPhoto); // commentingEnabled ? xml.WriteElementString ("timestamp", ((long)(date - new DateTime (1970, 1, 1)).TotalSeconds * 1000).ToString (), PicasaNamespaces.GPhoto); //keywords ? xml.WriteElementStringWithAttributes ("category", null, "scheme", "http://schemas.google.com/g/2005#kind", "term", "http://schemas.google.com/photos/2007#album"); return xml.GetDocumentString (); } /* "\n" + "\n" + " \n" + " {0}\n" + " {1}\n" + " deleteAlbum\n" + " \n" + ""; */ // static string GetXmlForDelete (string user, string aid) // { // XmlUtil xml = new XmlUtil (); // xml.WriteElementString ("user", user, PicasaNamespaces.GPhoto); // xml.WriteElementString ("id", aid, PicasaNamespaces.GPhoto); // xml.WriteElementString ("op", "deleteAlbum", PicasaNamespaces.GPhoto); // return xml.GetDocumentString (); // } public void DeleteAlbum (PicasaAlbum album) { if (album == null) throw new ArgumentNullException ("album"); DeleteAlbum (album.UniqueID); } public void DeleteAlbum (string unique_id) { //FIXME: implement this throw new System.NotImplementedException ("but I'll implemented if you say please..."); // if (unique_id == null) // throw new ArgumentNullException ("unique_id"); // // string url = GDataApi.GetPostURL (conn.User); // if (url == null) // throw new UnauthorizedAccessException ("You are not authorized to delete this album."); // string op_string = GetXmlForDelete (conn.User, unique_id); // byte [] op_bytes = Encoding.UTF8.GetBytes (op_string); // MultipartRequest request = new MultipartRequest (conn, url); //// request.Request.CookieContainer = conn.Cookies; // request.BeginPart (); // request.AddHeader ("Content-Disposition: form-data; name=\"xml\"\r\n"); // request.AddHeader ("Content-Type: text/plain; charset=utf8\r\n", true); // request.WriteContent (op_bytes); // request.EndPart (true); // string received = request.GetResponseAsString (); // // XmlDocument doc = new XmlDocument (); // doc.LoadXml (received); // XmlNode node = doc.SelectSingleNode ("/response/result"); // if (node == null) // throw new DeleteAlbumException ("Invalid response from server"); // // if (node.InnerText != "success") { // node = doc.SelectSingleNode ("/response/reason"); // if (node == null) // throw new DeleteAlbumException ("Unknown reason"); // // throw new DeleteAlbumException (node.InnerText); // } } public PicasaAlbumCollection GetAlbums () { string gallery_link = GDataApi.GetGalleryFeed (user); string received = conn.DownloadString (gallery_link); XmlDocument doc = new XmlDocument (); doc.LoadXml (received); XmlNamespaceManager nsmgr = new XmlNamespaceManager (doc.NameTable); XmlUtil.AddDefaultNamespaces (nsmgr); XmlNode feed = doc.SelectSingleNode ("atom:feed", nsmgr); PicasaAlbumCollection coll = new PicasaAlbumCollection (); foreach (XmlNode item in feed.SelectNodes ("atom:entry", nsmgr)) { coll.Add (new PicasaAlbum (conn, user, item, nsmgr)); } coll.SetReadOnly (); return coll; } private void ParseGallery (XmlNode nodeitem, XmlNamespaceManager nsmgr) { XmlNode node = nodeitem.SelectSingleNode ("atom:title", nsmgr); title = node.InnerText; node = nodeitem.SelectSingleNode ("gphoto:user", nsmgr); user = node.InnerText; node = nodeitem.SelectSingleNode ("gphoto:nickname", nsmgr); nickname = node.InnerText; node = nodeitem.SelectSingleNode ("gphoto:quotacurrent", nsmgr); quota_used = (node != null) ? (long) UInt64.Parse (node.InnerText) : -1; node = nodeitem.SelectSingleNode ("gphoto:quotalimit", nsmgr); quota_limit = (node != null) ? (long) UInt64.Parse (node.InnerText) : -1; } } }