f-spot r4230 - in trunk/dpap-sharp: . DPAPService lib



Author: apart
Date: Thu Aug  7 18:55:26 2008
New Revision: 4230
URL: http://svn.gnome.org/viewvc/f-spot?rev=4230&view=rev

Log:
Client interface & fixes for browsing & downloading photos in iPhoto '08


Modified:
   trunk/dpap-sharp/ChangeLog
   trunk/dpap-sharp/DPAPService/DPAPService.addin.xml
   trunk/dpap-sharp/DPAPService/DPAPService.cs
   trunk/dpap-sharp/DPAPService/DPAPService.mdp
   trunk/dpap-sharp/DPAPService/Makefile.am
   trunk/dpap-sharp/lib/ContentCodeBag.cs
   trunk/dpap-sharp/lib/ContentFetcher.cs
   trunk/dpap-sharp/lib/ContentParser.cs
   trunk/dpap-sharp/lib/ContentWriter.cs
   trunk/dpap-sharp/lib/Database.cs
   trunk/dpap-sharp/lib/Discovery.cs
   trunk/dpap-sharp/lib/Photo.cs

Modified: trunk/dpap-sharp/DPAPService/DPAPService.addin.xml
==============================================================================
--- trunk/dpap-sharp/DPAPService/DPAPService.addin.xml	(original)
+++ trunk/dpap-sharp/DPAPService/DPAPService.addin.xml	Thu Aug  7 18:55:26 2008
@@ -12,6 +12,9 @@
 	<Extension path = "/FSpot/Services">
 		<Service class="DPAPService.DPAPService"/>
 	</Extension>
+	<Extension path = "/FSpot/Sidebar">
+		<SidebarPage sidebar_page_type="DPAPService.DPAPPage"/>
+	</Extension>
 </Addin>
 
 

Modified: trunk/dpap-sharp/DPAPService/DPAPService.cs
==============================================================================
--- trunk/dpap-sharp/DPAPService/DPAPService.cs	(original)
+++ trunk/dpap-sharp/DPAPService/DPAPService.cs	Thu Aug  7 18:55:26 2008
@@ -24,10 +24,135 @@
 using FSpot;
 using FSpot.Extensions;
 using FSpot.Utils;
+using FSpot.Widgets;
 using System.IO;
 using DPAP;
+using Gtk;
 
 namespace DPAPService {
+	
+	public class DPAPPageWidget : ScrolledWindow {
+		TreeView tree;
+		TreeStore list;
+		ServiceDiscovery sd;
+		Client client;
+		
+		public DPAPPageWidget()
+		{
+			Console.WriteLine ("DPAP Page widget ctor!");
+			tree = new TreeView ();
+			Add (tree);
+			TreeViewColumn artistColumn = new Gtk.TreeViewColumn ();
+			//artistColumn.Title = "Artist";
+ 
+			Gtk.CellRendererText artistNameCell = new Gtk.CellRendererText ();
+			artistNameCell.Visible = true;
+			artistColumn.PackStart (artistNameCell,false);
+			tree.AppendColumn(artistColumn);
+			//tree.AppendColumn ("Icon", new Gtk.CellRendererPixbuf (), "pixbuf", 0);  
+
+			
+			list = new TreeStore (typeof(string));
+			tree.Model = list;
+			
+			artistColumn.AddAttribute (artistNameCell, "text", 0);
+			//list.AppendValues("test");
+		
+			tree.Selection.Changed += OnSelectionChanged;
+		//	tree.ShowNow();
+		//	ShowAll();
+			sd = new DPAP.ServiceDiscovery();
+			sd.Found += OnServiceFound;		
+			sd.Start();	
+		}
+		
+		private void OnSelectionChanged (object o, EventArgs args)
+		{
+			Gtk.TreeSelection selection =  (Gtk.TreeSelection) o;
+			Gtk.TreeModel model;
+			Gtk.TreeIter iter;
+			string data;
+			if (selection.GetSelected (out model, out iter)) {
+				GLib.Value val = GLib.Value.Empty;
+                model.GetValue (iter, 0, ref val);
+                data = (string) val.Val;
+				
+				if ( list.IterDepth (iter) == 0 )
+					Connect (data);
+				else
+					ViewAlbum (data);
+                val.Dispose ();
+			}
+			
+		}
+		
+		private void ViewAlbum (string name)
+		{
+			Console.WriteLine ("View Album !");
+			Database d = client.Databases[0];
+			Directory.CreateDirectory ("/tmp/" + client.Databases[0].Name);
+			foreach (DPAP.Photo ph in d.Photos)
+				{
+					if(ph != null)
+					{
+						Console.WriteLine ("\t\tFile: " + ph.Title + " format = " + ph.Format + "size=" + ph.Width +"x" +ph.Height + " ID=" + ph.Id);
+						d.DownloadPhoto (ph,"/tmp/" + client.Databases[0].Name + "/" + ph.FileName);
+					}
+				}
+		}
+		
+		private void Connect (string svcName)
+		{
+			Service service = sd.ServiceByName(svcName);
+			System.Console.WriteLine("Connecting to {0} at {1}:{2}", service.Name, service.Address, service.Port);
+	
+			client = new Client( service );
+			TreeIter iter;
+			//list.GetIterFromString( out iter, svcName);
+			list.GetIterFirst ( out iter );
+			foreach (Database d in client.Databases){
+				
+			//	list.AppendValues(iter,d.Name);
+				Console.WriteLine("Database " + d.Name);
+				
+				foreach (Album alb in d.Albums)
+					list.AppendValues (iter, alb.Name);
+					//Console.WriteLine("\tAlbum: "+alb.Name + ", id=" + alb.getId() + " number of items:" + alb.Photos.Count);
+			//	Console.WriteLine(d.Photos[0].FileName);
+								
+			}
+		}
+		
+		private void OnServiceFound(object o, ServiceArgs args)
+		{
+			Service service = args.Service;
+			Console.WriteLine("ServiceFound " + service.Name);
+			if(service.Name.Equals("f-spot photos")) return;
+			list.AppendValues(service.Name);
+/*			System.Console.WriteLine("Connecting to {0} at {1}:{2}", service.Name, service.Address, service.Port);
+		    
+			//client.Logout();
+			//Console.WriteLine("Press <enter> to exit...");
+*/
+			
+		}
+		
+	}
+	
+	public class DPAPPage : SidebarPage
+	{
+		//public DPAPPage () { }
+		private static DPAPPageWidget widget;
+		public DPAPPage() : base (new DPAPPageWidget(), "Shared items", "gtk-new") 
+		{
+			Console.WriteLine("Starting DPAP client...");
+		
+			widget = (DPAPPageWidget)SidebarWidget;
+		}
+		
+				
+	}
+	
 	public class DPAPService : IService
 	{
 		static ServiceDiscovery sd;

Modified: trunk/dpap-sharp/DPAPService/DPAPService.mdp
==============================================================================
--- trunk/dpap-sharp/DPAPService/DPAPService.mdp	(original)
+++ trunk/dpap-sharp/DPAPService/DPAPService.mdp	Thu Aug  7 18:55:26 2008
@@ -21,5 +21,8 @@
     <ProjectReference type="Gac" localcopy="True" refto="FSpot.Core, Version=0.0.0.0, Culture=neutral" />
     <ProjectReference type="Gac" localcopy="True" refto="FSpot.Utils, Version=0.0.0.0, Culture=neutral" />
     <ProjectReference type="Gac" localcopy="True" refto="f-spot, Version=0.4.3.1, Culture=neutral" />
+    <ProjectReference type="Assembly" localcopy="True" refto="../../src/FSpot.Widgets.dll" />
+    <ProjectReference type="Gac" localcopy="True" refto="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
+    <ProjectReference type="Gac" localcopy="True" refto="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
   </References>
 </Project>
\ No newline at end of file

Modified: trunk/dpap-sharp/DPAPService/Makefile.am
==============================================================================
--- trunk/dpap-sharp/DPAPService/Makefile.am	(original)
+++ trunk/dpap-sharp/DPAPService/Makefile.am	Thu Aug  7 18:55:26 2008
@@ -14,6 +14,7 @@
 REFS =					\
 	-r:../../src/f-spot.exe		\
 	-r:../../src/FSpot.Core.dll	\
+	-r:../../src/FSpot.Widgets.dll \
 	-r:../../src/FSpot.Utils.dll	\
 	-r:../lib/dpap-sharp.dll	
 #	$(LINK_BEAGLE)

Modified: trunk/dpap-sharp/lib/ContentCodeBag.cs
==============================================================================
--- trunk/dpap-sharp/lib/ContentCodeBag.cs	(original)
+++ trunk/dpap-sharp/lib/ContentCodeBag.cs	Thu Aug  7 18:55:26 2008
@@ -162,7 +162,7 @@
             bag.AddCode ("ppro", "dpap.protocolversion", ContentType.Long);
             bag.AddCode ("pret", "dpap.blah", ContentType.Container);
 			bag.AddCode ("avdb", "dpap.serverdatabases", ContentType.Container);
-			bag.AddCode ("aply", "dpap.databaseplaylists", ContentType.Container);
+			bag.AddCode ("aply", "dpap.databasecontainers", ContentType.Container);
 			bag.AddCode ("abpl", "dpap.baseplaylist", ContentType.Char);
 			bag.AddCode ("apso", "dpap.playlistsongs", ContentType.Container);
 			bag.AddCode ("pasp", "dpap.aspectratio", ContentType.String);

Modified: trunk/dpap-sharp/lib/ContentFetcher.cs
==============================================================================
--- trunk/dpap-sharp/lib/ContentFetcher.cs	(original)
+++ trunk/dpap-sharp/lib/ContentFetcher.cs	Thu Aug  7 18:55:26 2008
@@ -140,7 +140,7 @@
             HttpWebRequest request = (HttpWebRequest) WebRequest.Create (builder.Uri);
             request.PreAuthenticate = true;
             request.Timeout = System.Threading.Timeout.Infinite;
-            request.Headers.Add ("Accept-Encoding", "gzip");
+            //request.Headers.Add ("Accept-Encoding", "gzip");
 
             if (offset > 0) {
                 request.AddRange ("bytes", (int) offset);

Modified: trunk/dpap-sharp/lib/ContentParser.cs
==============================================================================
--- trunk/dpap-sharp/lib/ContentParser.cs	(original)
+++ trunk/dpap-sharp/lib/ContentParser.cs	Thu Aug  7 18:55:26 2008
@@ -114,23 +114,29 @@
 
         public static ContentNode Parse (ContentCodeBag bag, byte[] buffer, string root,
                                          ref int offset) {
-			//Console.WriteLine("Entering ContentNode Parse (...)");
+			
             ContentNode node = new ContentNode ();
-//System.Console.WriteLine("debug1!");
             int num = IPAddress.NetworkToHostOrder (BitConverter.ToInt32 (buffer, offset));
-	//		System.Console.WriteLine("debug2!");
-            ContentCode code = bag.Lookup (num);
+			ContentCode code;
+			// This is a fix for iPhoto '08 which gives wrong content-type for dpap.databasecontainers (aply)
+			if(num == 1634757753)
+			{
+				code = new ContentCode();
+				code.Name = "dpap.databasecontainers";
+				code.Type = ContentType.Container;
+			}
+			else
+				code = bag.Lookup (num);
+			if(code.Name.Equals("dpap.filedata"))
+				code.Type = ContentType.FileData;
 			
-			//System.Console.WriteLine("debug3!");
             if (code.Equals (ContentCode.Zero)) {
                 // probably a buggy server.  fallback to our internal code bag
 				Console.WriteLine("fallback to internal code bag");
 				Console.WriteLine("Code number: "+num);
 				throw new Exception("Content code not found!");
-                //code = ContentCodeBag.Default.Lookup (num);
             }
 			
-			//System.Console.WriteLine("debug!4");
             int length = IPAddress.NetworkToHostOrder (BitConverter.ToInt32 (buffer, offset + 4));
 
             if (code.Equals (ContentCode.Zero)) {
@@ -139,7 +145,8 @@
             }
 
             node.Name = code.Name;
-			//Console.WriteLine("Code=" +code.Type.ToString());
+			
+			Console.WriteLine("name = " + node.Name + "Code=" +code.Type.ToString() + " num=" +num);
             switch (code.Type) {
             case ContentType.Char:
                 node.Value = (byte) buffer[offset + 8];
@@ -170,13 +177,16 @@
             case ContentType.Container:
                 node.Value = ParseChildren (bag, buffer, offset + 8, length);
                 break;
+			case ContentType.FileData:
+				node.Value = offset+8;
+				break;
             default:
                 throw new ContentException (String.Format ("Unknown content type '{0}' for '{1}'",
                                                            code.Type, code.Name));
             }
 
             offset += length + 8;
-			//Console.WriteLine("Leaving ContentNode Parse (...)");
+			
             if (root != null) {
                 ContentNode rootNode = node.GetChild (root);
 

Modified: trunk/dpap-sharp/lib/ContentWriter.cs
==============================================================================
--- trunk/dpap-sharp/lib/ContentWriter.cs	(original)
+++ trunk/dpap-sharp/lib/ContentWriter.cs	Thu Aug  7 18:55:26 2008
@@ -78,10 +78,11 @@
                 writer.Write ((byte) version.Build);
                 break;
 			case ContentType.FileData:
+				// after "pfdt" we should send the file size and then immediately the file's contents 
 				
 				Console.WriteLine("ContentWriter FileData!");
 				ContentNode[] nodes = (ContentNode[]) node.Value;
-				//writer.Write(IPAddress.HostToNetworkOrder (0));
+				
 				Console.WriteLine(nodes[0].Value);
 				writer.Write(IPAddress.HostToNetworkOrder ((int)nodes[0].Value));
 				FileInfo info = new FileInfo ((string)nodes[1].Value);				

Modified: trunk/dpap-sharp/lib/Database.cs
==============================================================================
--- trunk/dpap-sharp/lib/Database.cs	(original)
+++ trunk/dpap-sharp/lib/Database.cs	Thu Aug  7 18:55:26 2008
@@ -218,7 +218,7 @@
                 nodes.Add (pl.ToNode (false));
             }
 
-            return new ContentNode ("dpap.databaseplaylists",
+            return new ContentNode ("dpap.databasecontainers",
                                     new ContentNode ("dmap.status", 200),
                                     new ContentNode ("dmap.updatetype", (byte) 0),
                                     new ContentNode ("dmap.specifiedtotalcount", nodes.Count),
@@ -273,16 +273,18 @@
 			albumsNode.Dump();
 			Console.WriteLine("after dump!");
 			
- //           if (IsUpdateResponse (albumsNode))
- //               return;
+            if (IsUpdateResponse (albumsNode))
+                return;
 
             // handle album additions/changes
             ArrayList plids = new ArrayList ();
-            
+			if(albumsNode.GetChild("dmap.listing")==null) return;
+			
             foreach (ContentNode albumNode in (ContentNode[]) albumsNode.GetChild ("dmap.listing").Value) {
-                Album pl = Album.FromNode (albumNode);
+                
 				// DEBUG
 				Console.WriteLine("foreach loop");
+				Album pl = Album.FromNode (albumNode);
                 if (pl != null) {
                     plids.Add (pl.Id);
                     Album existing = LookupAlbumById (pl.Id);
@@ -429,27 +431,66 @@
 
         public void DownloadPhoto (Photo photo, string dest) {
 
-            BinaryWriter writer = new BinaryWriter (File.Open (dest, FileMode.Create));
-
+/*            BinaryWriter writer = new BinaryWriter (File.Open (dest, FileMode.Create));
+			MemoryStream data = new MemoryStream ();
             try {
                 long len;
                 using (BinaryReader reader = new BinaryReader (StreamPhoto (photo, out len))) {
                     int count = 0;
                     byte[] buf = new byte[ChunkLength];
-                    
-			/*		count = reader.Read(buf,0,89);
+                
+					// Skip the header    
+					//count = reader.Read(buf,0,89);
+					
+					//if(count < 89)
+					//	count+=reader.Read(buf,0,89-count);
+					
+					while (true) {
+                    buf = reader.ReadBytes (8192);
+                    if (buf.Length == 0)
+                        break;
+
+                    data.Write (buf, 0, buf.Length);
+					//Console.Write(buf.);
+					}
 					
-					if(count < 89)
-						count+=reader.Read(buf,0,89-count);
-				*/	
-                    do {
+			*/		
+/*                    do {
                         count = reader.Read (buf, 0, ChunkLength);
                         writer.Write (buf, 0, count);
+						data.Write (buf, 0, count);
                     } while (count != 0);
+	*/				
+					/*data.Flush();
+					
+					ContentNode node = ContentParser.Parse(client.Bag, data.GetBuffer());
+					node.Dump();
+					reader.Close ();
+					
                 }
             } finally {
+				data.Close ();
+                
                 writer.Close ();
-            }
+            }*/
+			 byte[] photosData = client.Fetcher.Fetch (String.Format ("/databases/{0}/items",id), 
+			                                     String.Format("meta=dpap.filedata&query=('dmap.itemid:{0}')",photo.Id));
+			ContentNode node = ContentParser.Parse(client.Bag, photosData);
+			
+			// DEBUG
+			Console.WriteLine("About to dump the photo!");
+			node.Dump();
+			ContentNode fileDataNode = node.GetChild("dpap.filedata");
+			Console.WriteLine("Photo starts at index " + fileDataNode.Value);
+			BinaryWriter writer = new BinaryWriter (File.Open (dest, FileMode.Create));
+			int count = 0;
+			int off = System.Int32.Parse(fileDataNode.Value.ToString());
+			
+			//while ( count < photosData.Length - fileDataNode.Value)
+			
+			writer.Write(photosData, (int)off, (int)photosData.Length-off);
+			
+			Console.Write("Written " + count + " out of " + (photosData.Length-off));
         }
 
         public void AddPhoto (Photo photo) {

Modified: trunk/dpap-sharp/lib/Discovery.cs
==============================================================================
--- trunk/dpap-sharp/lib/Discovery.cs	(original)
+++ trunk/dpap-sharp/lib/Discovery.cs	Thu Aug  7 18:55:26 2008
@@ -123,6 +123,11 @@
             args.Service.Resolve ();
 		}
 		
+		public Service ServiceByName(string svcName)
+		{
+			return (Service)services[svcName];
+		}
+		
 		private void OnServiceResolved(object o, ServiceResolvedEventArgs args){
 				
 		        IResolvableService s = (IResolvableService)args.Service;

Modified: trunk/dpap-sharp/lib/Photo.cs
==============================================================================
--- trunk/dpap-sharp/lib/Photo.cs	(original)
+++ trunk/dpap-sharp/lib/Photo.cs	Thu Aug  7 18:55:26 2008
@@ -211,6 +211,10 @@
 			Console.WriteLine("Requested "+ ((thumb)?"thumb":"file") +", thumbnail=" + thumbnail + ", hires=" + path);
 			nodes.Add (new ContentNode ("dmap.itemkind", (byte)3));
 			nodes.Add (new ContentNode ("dmap.itemid", id));
+			
+			// pass the appropriate file path, depending on wether 
+			//we are sending the thumbnail or the hi-res image
+			
 			nodes.Add (new ContentNode ("dpap.filedata",
 			                                             new ContentNode ("dpap.imagefilesize", (thumb)?thumbsize:size),
 			                                             new ContentNode ("dpap.imagefilename", (thumb)?thumbnail:path),
@@ -218,18 +222,6 @@
 			
 			return (new ContentNode("dmap.listingitem", nodes));
 			
-			 /*
-			                 
-			                        
-			                                         new ContentNode ("dmap.listingitem",
-			                                                          new ContentNode ("dmap.itemid", id),
-//			                                         new ContentNode ("dmap.persistentid", (long) id),
-//			                                         new ContentNode ("dmap.itemname", name),
-//			                                         new ContentNode ("dmap.itemcount", photos.Count),
-			                                                          new ContentNode ("dpap.filedata",
-			                                                                           new ContentNode ("dpap.imagefilesize", size),
-			                                                                           new ContentNode ("dpap.imagefilename", fileName))))
-			                        );*/
 		}
         internal ContentNode ToNode (string[] fields) {
 
@@ -320,7 +312,7 @@
                 case "dpap.imagefilename":
 					photo.fileName = (string) field.Value;
 					break;
-                case "dpap.imagefilesize":
+               /* case "dpap.imagefilesize":
                     photo.size = (int) field.Value;
                     break;
                 case "dpap.imagepixelwidth":
@@ -328,7 +320,7 @@
 					break;
 				case "dpap.imagepixelheight":
 					photo.height = (int) field.Value;
-					break;
+					break;*/
                 default:
                     break;
                 }
@@ -376,6 +368,8 @@
 				case "dpap.imagelargefilesize":
 					val = size;
 					break;
+				// Apparently this has to be sent even with bogus data, 
+				// otherwise iPhoto '08 wont show the thumbnails
 				case "dpap.aspectratio":
 					val = "1.522581";
 					break;



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