[f-spot/taglib-metadata] Add XMP sidecar writing.
- From: Ruben Vermeersch <rubenv src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [f-spot/taglib-metadata] Add XMP sidecar writing.
- Date: Sat, 19 Jun 2010 17:14:03 +0000 (UTC)
commit f9c9b3256822d50a0dfd176f219aaa839cedbe64
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..dae4775 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]