Import patch



Hi all,

here's my initial import patch. It ended up being pretty short, for all the screwing around I did to get it working...

It does make a few simplifying assumptions:

- as discussed in another thread, it assumes that any items contained within an RDF Bag are tags

  - It scans xmp data in jpeg headers or an xmp 'sidecar' (foo.jpg.xmp)

  - any new tags created are *not* deleted if the import is canceled.

- new tags are created at the top level - you need to drag them to the right location in the tree. They are created as categories so children can be added if needed...

- it assumes that it is kosher to add a GetTagByName method to PhotoStore -- I haven't heard anything from my question about this yesterday.

If I haven't heard anything in a couple of days, I'm going to try to find a bug to attach this to...

Warren
diff -ur clean/f-spot-0.1.11/src/FileImportBackend.cs f-spot-0.1.11/src/FileImportBackend.cs
--- clean/f-spot-0.1.11/src/FileImportBackend.cs	2006-03-12 22:49:25.000000000 -0500
+++ f-spot-0.1.11/src/FileImportBackend.cs	2006-04-20 19:00:17.000000000 -0400
@@ -3,6 +3,8 @@
 using Gnome;
 using System.Collections;
 using System;
+using FSpot.Xmp;
+using FSpot;
 
 public class ImportException : System.Exception {
 	public ImportException (string msg) : base (msg)
@@ -142,8 +144,9 @@
 
 		// FIXME Need to get the EXIF info etc.
 		string path = (string) file_paths [this.count];
-		
+		string origPath = (string) file_paths [this.count];
 		try {
+						
 			if (copy) {
 				string dest = ChooseLocation (path);
 				System.IO.File.Copy (path, dest);
@@ -152,6 +155,36 @@
 			} else {
                 photo = store.Create (path, out thumbnail);
 			}
+
+			// check for Xmp headers in the jpeg file itself
+			try {
+				JpegFile jpegfile = new JpegFile(path);
+				JpegHeader jpegheader = jpegfile.Header;
+				XmpFile xmpfile = jpegheader.GetXmp();
+				if (xmpfile != null) {
+					string [] tagNames = xmpfile.Store.GetTagNames();
+					foreach (string tagName in tagNames) {
+						Tag t = store.GetTagByName(tagName);
+						photo.AddTag(t);
+					}
+					store.Commit(photo);
+				}
+			} catch (System.Exception e) {
+				System.Console.WriteLine ("Error reading XMP headers for {0}\n{1}", path, e.ToString ());
+			}
+
+			
+			// check for an xmp "sidecar" file
+			if (System.IO.File.Exists(origPath + ".xmp")) {
+				XmpFile sidecar = new XmpFile(System.IO.File.OpenRead(origPath + ".xmp"));
+				string [] tagNames = sidecar.Store.GetTagNames();
+				foreach (string tagName in tagNames) {
+					System.Console.WriteLine("adding tag for: " + tagName);
+					Tag t = store.GetTagByName(tagName);
+					photo.AddTag(t);
+				}
+				store.Commit(photo);
+			}
 			
 			if (tags != null) {
 				foreach (Tag t in tags) {
diff -ur clean/f-spot-0.1.11/src/MetadataStore.cs f-spot-0.1.11/src/MetadataStore.cs
--- clean/f-spot-0.1.11/src/MetadataStore.cs	2006-02-11 13:02:14.000000000 -0500
+++ f-spot-0.1.11/src/MetadataStore.cs	2006-04-20 18:38:56.000000000 -0400
@@ -189,6 +189,39 @@
 			}
 		}
 
+
+		// Note that this is a very incomplete implementation.  It currently returns an array
+		// containing all strings that appear in an RDF:Bag structure in the xmp file
+		// This will not work in general, but it does provide an easy way to import existing tags.
+		// 
+		// TODO: Implement proper XMP/RDF parsing here to only look for bags inside a dc:subject node
+		
+		public string []  GetTagNames() 
+		{
+			System.Collections.ArrayList tags = new System.Collections.ArrayList();
+			bool savingTags = false;
+			foreach (SemWeb.Statement stmt in this) {
+				if (stmt.Object.ToString() == "http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag";) {
+					savingTags = true;
+					continue;
+				}
+				if (savingTags) {
+					if (stmt.Object.ToString() == "_") {
+						savingTags = false;
+						continue;
+					}
+					string tag = stmt.Object.ToString();
+					// SemWeb puts quotes around the strings it returns, 
+					// so we need to remove them
+					if (tag.StartsWith("\"") && tag.EndsWith("\"")) {
+						tag = tag.Substring(1,tag.Length-2);
+					}
+					tags.Add(tag);
+				}
+			}
+			return  (string []) tags.ToArray (typeof (string));
+		}
+
 		public void Dump ()
 		{
 			foreach (SemWeb.Statement stmt in this) {
diff -ur clean/f-spot-0.1.11/src/PhotoStore.cs f-spot-0.1.11/src/PhotoStore.cs
--- clean/f-spot-0.1.11/src/PhotoStore.cs	2006-03-07 12:54:54.000000000 -0500
+++ f-spot-0.1.11/src/PhotoStore.cs	2006-04-20 18:47:18.000000000 -0400
@@ -635,6 +635,20 @@
 			   Thumbnail.PathForUri (new_uri, ThumbnailSize.Large));
 	}
 
+	// Lookup a tag by name --- needed for importing tags
+	// If the requested tag doesn't exist, a new top-level tag
+	// is created and returned.
+	
+	public Tag GetTagByName (string name) {
+	
+		Tag tag = tag_store.GetTagByName(name);
+		
+		if (tag == null) {
+			tag = tag_store.CreateCategory(null,name);
+		}
+		return tag;
+	}
+
 
 	// Constructor
 
diff -ur clean/f-spot-0.1.11/src/PreferenceDialog.cs f-spot-0.1.11/src/PreferenceDialog.cs
--- clean/f-spot-0.1.11/src/PreferenceDialog.cs	2006-02-20 18:38:14.000000000 -0500
+++ f-spot-0.1.11/src/PreferenceDialog.cs	2006-03-31 20:51:52.000000000 -0500
@@ -29,16 +29,21 @@
 		[Glade.Widget] private ComboBox destination_combo;
 		[Glade.Widget] private OptionMenu tag_option;
 		[Glade.Widget] private Button set_saver_button;
+		[Glade.Widget] private HScale slideshow_interval;
 		private static PreferenceDialog prefs = null;
 		int screensaver_tag;
+		bool loadingPrefs;
 		private const string SaverCommand = "f-spot-screensaver";
 
 		public PreferenceDialog () : base ("main_preferences")
 		{
+			loadingPrefs = true;
 			LoadPreference (Preferences.METADATA_EMBED_IN_IMAGE);
 			LoadPreference (Preferences.SCREENSAVER_TAG);
 			LoadPreference (Preferences.GNOME_SCREENSAVER_THEME);
-
+			LoadPreference (Preferences.SLIDESHOW_INTERVAL);
+			loadingPrefs = false;
+			
 			Gtk.CellRendererText name_cell = new Gtk.CellRendererText ();
 			Gtk.CellRendererText desc_cell = new Gtk.CellRendererText ();
 			
@@ -103,6 +108,11 @@
 			LoadPreference (args.Key);
 		}
 
+		void HandleSlideshowInterval (object sender, System.EventArgs args)
+		{
+			Preferences.Set (Preferences.SLIDESHOW_INTERVAL, slideshow_interval.Value);
+		}
+		
 		void MetadataToggled (object sender, System.EventArgs args)
 		{
 			Preferences.Set (Preferences.METADATA_EMBED_IN_IMAGE, metadata_check.Active);
@@ -135,7 +145,18 @@
 				string [] names = (string []) val;
 				set_saver_button.Sensitive = (names.Length != 1 || names [0] != SaverCommand);
 				break;
+			case Preferences.SLIDESHOW_INTERVAL:
+				double interval = 2;
+				if (val != null) {
+					interval = (double) val;
+				}
+				//if (loadingPrefs) {
+					slideshow_interval.Value = interval;
+				//}
+				break;
+								
 			}
+			
 		}
 
 		void HandleClose (object sender, EventArgs args)


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