Import patch
- From: Warren Baird <photogeekmtl gmail com>
- To: F-Spot list <f-spot-list gnome org>
- Subject: Import patch
- Date: Thu, 20 Apr 2006 19:22:56 -0400
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]