[f-spot/taglib-metadata: 14/20] Add XMP sidecar writing.



commit 0b7bae1c7104868b89bbe116e03ec22d18511190
Author: Ruben Vermeersch <ruben savanne be>
Date:   Sat Jun 19 19:13:26 2010 +0200

    Add XMP sidecar writing.
    
    This includes adapting GIOTagLibFileAbstraction to make sure it handles
    creation of new files for writing.

 src/Utils/GIOTagLibFileAbstraction.cs        |   18 ++++++--
 src/Utils/SafeUriExtensions.cs               |    6 +++
 src/Utils/SidecarXmpExtensions.cs            |   13 ++++++
 src/Utils/Tests/SafeUriTests.cs              |    9 ++++
 src/Utils/Tests/SidecarXmpExtensionsTests.cs |   57 +++++++++++++++++++++++++-
 5 files changed, 98 insertions(+), 5 deletions(-)
---
diff --git a/src/Utils/GIOTagLibFileAbstraction.cs b/src/Utils/GIOTagLibFileAbstraction.cs
index ae7f478..e89bfa6 100644
--- a/src/Utils/GIOTagLibFileAbstraction.cs
+++ b/src/Utils/GIOTagLibFileAbstraction.cs
@@ -38,6 +38,8 @@ namespace FSpot.Utils
                     var file = FileFactory.NewForUri (Uri);
                     stream = new GioStream (file.Read (null));
                 }
+                if (!stream.CanRead)
+                    throw new Exception ("Can't read from this resource");
                 return stream;
             }
         }
@@ -45,9 +47,14 @@ namespace FSpot.Utils
         public Stream WriteStream {
             get {
                 if (stream == null) {
-                    CopyToTmp ();
-                    var file = FileFactory.NewForUri (tmp_write_uri);
-                    stream = new GioStream (file.OpenReadwrite (null));
+                    var file = FileFactory.NewForUri (Uri);
+                    if (!file.Exists) {
+                        stream = new GioStream (file.Create (GLib.FileCreateFlags.None, null));
+                    } else {
+                        CopyToTmp ();
+                        file = FileFactory.NewForUri (tmp_write_uri);
+                        stream = new GioStream (file.OpenReadwrite (null));
+                    }
                 }
                 if (!stream.CanWrite) {
                     throw new Exception ("Stream still open in reading mode!");
@@ -58,8 +65,8 @@ namespace FSpot.Utils
 
         private void CopyToTmp ()
         {
-            tmp_write_uri = CreateTmpFile ();
             var file = FileFactory.NewForUri (Uri);
+            tmp_write_uri = CreateTmpFile ();
             var tmp_file = FileFactory.NewForUri (tmp_write_uri);
 
             file.Copy (tmp_file, GLib.FileCopyFlags.AllMetadata | GLib.FileCopyFlags.Overwrite, null, null);
@@ -67,6 +74,9 @@ namespace FSpot.Utils
 
         private void CommitTmp ()
         {
+            if (tmp_write_uri == null)
+                return;
+
             var file = FileFactory.NewForUri (Uri);
             var tmp_file = FileFactory.NewForUri (tmp_write_uri);
 
diff --git a/src/Utils/SafeUriExtensions.cs b/src/Utils/SafeUriExtensions.cs
index bdc27cb..7547036 100644
--- a/src/Utils/SafeUriExtensions.cs
+++ b/src/Utils/SafeUriExtensions.cs
@@ -35,5 +35,11 @@ namespace FSpot
             var index = name.LastIndexOf ('.');
             return index > -1 ? name.Substring (0, index) : name;
         }
+
+        public static SafeUri ReplaceExtension (this SafeUri uri, string extension)
+        {
+
+            return uri.GetBaseUri ().Append (uri.GetFilenameWithoutExtension () + extension);
+        }
     }
 }
diff --git a/src/Utils/SidecarXmpExtensions.cs b/src/Utils/SidecarXmpExtensions.cs
index e682190..9b4af06 100644
--- a/src/Utils/SidecarXmpExtensions.cs
+++ b/src/Utils/SidecarXmpExtensions.cs
@@ -27,5 +27,18 @@ namespace FSpot.Utils
             xmp_tag.ReplaceFrom (tag);
         }
 
+        public static void SaveXmpSidecar (this TagLib.Image.File file, TagLib.File.IFileAbstraction resource)
+        {
+            var xmp_tag = file.GetTag (TagLib.TagTypes.XMP, false) as XmpTag;
+            if (xmp_tag == null)
+                return;
+
+            var xmp = xmp_tag.Render ();
+            using (var stream = resource.WriteStream) {
+                using (var writer = new StreamWriter (stream)) {
+                    writer.Write (xmp);
+                }
+            }
+        }
     }
 }
diff --git a/src/Utils/Tests/SafeUriTests.cs b/src/Utils/Tests/SafeUriTests.cs
index 08c80b9..90b7554 100644
--- a/src/Utils/Tests/SafeUriTests.cs
+++ b/src/Utils/Tests/SafeUriTests.cs
@@ -61,6 +61,15 @@ namespace FSpot.Utils.Tests
                 Assert.AreEqual (suri.GetFilenameWithoutExtension (), test.FilenameWithoutExtension, String.Format("FilenameWithoutExtension for {0}", test.Uri));
             }
         }
+
+        [Test]
+        public void TestReplaceExtension ()
+        {
+            var uri = new SafeUri ("file:///test/image.jpg", true);
+            var goal = new SafeUri ("file:///test/image.xmp", true);
+
+            Assert.AreEqual (goal, uri.ReplaceExtension (".xmp"));
+        }
     }
 
     internal class SafeUriTest
diff --git a/src/Utils/Tests/SidecarXmpExtensionsTests.cs b/src/Utils/Tests/SidecarXmpExtensionsTests.cs
index 3aa5232..fdda372 100644
--- a/src/Utils/Tests/SidecarXmpExtensionsTests.cs
+++ b/src/Utils/Tests/SidecarXmpExtensionsTests.cs
@@ -73,9 +73,64 @@ namespace FSpot.Utils.Tests
             ImageTestHelper.DeleteTempFile (sidecar_uri);
         }
 
+        [Test]
+        public void TestSidecarWrite ()
+        {
+            var uri = ImageTestHelper.CreateTempFile ("taglib-sample.jpg");
+            var sidecar_uri = uri.ReplaceExtension (".xmp");
+            var res = new GIOTagLibFileAbstraction () { Uri = uri };
+            var sidecar_res = new GIOTagLibFileAbstraction () { Uri = sidecar_uri };
+            Assert.IsTrue (sidecar_uri.ToString ().EndsWith (".xmp"));
+
+            var sidecar_file = GLib.FileFactory.NewForUri (sidecar_uri);
+            Assert.IsFalse (sidecar_file.Exists);
+
+            var file = File.Create (res) as TagLib.Image.File;
+            Assert.IsTrue (file != null);
+
+            file.ImageTag.Keywords = new string [] { "Kirche Aarschot" };
+
+            // Validate writing of the sidecar
+            file.SaveXmpSidecar (sidecar_res);
+            Assert.IsTrue (sidecar_file.Exists);
+
+            var target = "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\"><rdf:RDF xm"
+                + "lns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\";>"
+                + "<rdf:Description MicrosoftPhoto:DateAcquired=\"2009-08-0"
+                + "4T20:42:36Z\" xmp:creatortool=\"Microsoft Windows Photo "
+                + "Gallery 6.0.6001.18000\" tiff:software=\"Microsoft Windo"
+                + "ws Photo Gallery 6.0.6001.18000\" tiff:Orientation=\"1\""
+                + " MicrosoftPhoto:Rating=\"1\" xmp:Rating=\"1\" xmlns:tiff"
+                + "=\"http://ns.adobe.com/tiff/1.0/\"; xmlns:xmp=\"http://ns";
+                + ".adobe.com/xap/1.0/\" xmlns:MicrosoftPhoto=\"http://ns.m";
+                + "icrosoft.com/photo/1.0/\"><MicrosoftPhoto:LastKeywordXMP"
+                + "><rdf:Bag><rdf:li>Kirche Sulzbach</rdf:li></rdf:Bag></Mi"
+                + "crosoftPhoto:LastKeywordXMP><dc:subject xmlns:dc=\"http:"
+                + "//purl.org/dc/elements/1.1/\"><rdf:Bag><rdf:li>Kirche Aa"
+                + "rschot</rdf:li></rdf:Bag></dc:subject></rdf:Description>"
+                + "</rdf:RDF></x:xmpmeta>";
+
+            string written;
+            var read_res = new GIOTagLibFileAbstraction () { Uri = sidecar_uri };
+            using (var stream = read_res.ReadStream) {
+                using (var reader = new System.IO.StreamReader (stream)) {
+                    written = reader.ReadToEnd ();
+                }
+            }
+            Assert.AreEqual (target, written);
+
+            // Check that the file is unchanged
+            file = File.Create (res) as TagLib.Image.File;
+            var keywords = file.ImageTag.Keywords;
+            Assert.AreEqual (new string [] { "Kirche Sulzbach" }, keywords);
+
+            ImageTestHelper.DeleteTempFile (uri);
+            ImageTestHelper.DeleteTempFile (sidecar_uri);
+        }
+
         SafeUri CopySidecarToTest (SafeUri uri)
         {
-            var target = uri.GetBaseUri ().Append (uri.GetFilenameWithoutExtension () + ".xmp");
+            var target = uri.ReplaceExtension (".xmp");
 
             var orig_uri = new SafeUri (Environment.CurrentDirectory + "/../tests/data/taglib-sample.xmp");
             var file = GLib.FileFactory.NewForUri (orig_uri);



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