[banshee] [MassStorage] Fix relative paths in playlists (bgo#560711)



commit 4fa8b4f3f5ab4341b92a7e37233d4cbbf335bd44
Author: Jeroen Budts <jeroen lightyear be>
Date:   Sat Apr 24 12:03:13 2010 +1000

    [MassStorage] Fix relative paths in playlists (bgo#560711)
    
    Signed-off-by: Alexander Kojevnikov <alexander kojevnikov com>

 .../Banshee.Library/Tests/FileNamePatternTests.cs  |   11 ++++-
 .../PlaylistFormatBase.cs                          |   15 ++----
 .../Banshee.Dap.MassStorage/MassStorageSource.cs   |    5 +-
 src/Libraries/Hyena/Hyena/Paths.cs                 |   44 ++++++++++++++++---
 4 files changed, 55 insertions(+), 20 deletions(-)
---
diff --git a/src/Core/Banshee.Services/Banshee.Library/Tests/FileNamePatternTests.cs b/src/Core/Banshee.Services/Banshee.Library/Tests/FileNamePatternTests.cs
index 35988e8..02ca142 100644
--- a/src/Core/Banshee.Services/Banshee.Library/Tests/FileNamePatternTests.cs
+++ b/src/Core/Banshee.Services/Banshee.Library/Tests/FileNamePatternTests.cs
@@ -55,7 +55,16 @@ namespace Banshee.Library.Tests
             Assert.AreEqual ("baz", Paths.MakePathRelative ("/foo/bar/baz", "/foo/bar/"));
             Assert.AreEqual ("",    Paths.MakePathRelative ("/foo/bar/baz", "/foo/bar/baz"));
             Assert.AreEqual (null,  Paths.MakePathRelative ("/foo/bar/baz", "foo"));
-            Assert.AreEqual (null,  Paths.MakePathRelative ("/fo", "/foo"));
+            Assert.AreEqual (null,  Paths.MakePathRelative ("foo/bar/baz", "/foo"));
+            Assert.AreEqual ("../foo",  Paths.MakePathRelative ("/foo", "/bar"));
+            Assert.AreEqual ("../foo/song.ogg",  Paths.MakePathRelative ("/foo/song.ogg", "/bar"));
+            Assert.AreEqual ("../../foo/song.ogg",  Paths.MakePathRelative ("/foo/song.ogg", "/bar/verylongdirectoryname"));
+            Assert.AreEqual ("",    Paths.MakePathRelative ("bar/foo/", "bar/foo/"));
+            Assert.AreEqual ("foo/song.ogg",    Paths.MakePathRelative ("bar/foo/song.ogg", "bar"));
+            Assert.AreEqual ("../song.ogg",     Paths.MakePathRelative ("bar/song.ogg", "bar/foo"));
+            Assert.AreEqual ("../foo/song.ogg", Paths.MakePathRelative ("bar/foo/song.ogg", "bar/other"));
+            Assert.AreEqual ("../../flap/foo/song.ogg", Paths.MakePathRelative ("bar/flap/foo/song.ogg", "bar/flop/other"));
+            Assert.AreEqual ("../../flap/foo/song.ogg", Paths.MakePathRelative ("/root/bar/flap/foo/song.ogg", "/root/bar/flop/other"));
         }
 
         [Test]
diff --git a/src/Core/Banshee.Services/Banshee.Playlists.Formats/PlaylistFormatBase.cs b/src/Core/Banshee.Services/Banshee.Playlists.Formats/PlaylistFormatBase.cs
index d4cfee5..fc0ebb1 100644
--- a/src/Core/Banshee.Services/Banshee.Playlists.Formats/PlaylistFormatBase.cs
+++ b/src/Core/Banshee.Services/Banshee.Playlists.Formats/PlaylistFormatBase.cs
@@ -79,18 +79,13 @@ namespace Banshee.Playlists.Formats
                 return uri.IsLocalPath ? uri.LocalPath : uri.AbsoluteUri;
             }
 
-            // TODO replace with call to Paths.MakeRelativeTo
-            string base_uri = uri.IsLocalPath ? BaseUri.LocalPath : BaseUri.AbsoluteUri;
-            string relative_uri = uri.IsLocalPath ? uri.LocalPath : uri.AbsoluteUri;
-
-            if(relative_uri.StartsWith(base_uri)) {
-                relative_uri = relative_uri.Substring(base_uri.Length);
-                if(relative_uri[0] == Path.DirectorySeparatorChar) {
-                    relative_uri = relative_uri.Substring(1);
-                }
+            if (!uri.IsLocalPath) {
+                return uri.AbsoluteUri;
             }
 
-            return relative_uri;
+            var result = Paths.MakePathRelative (uri.LocalPath, new DirectoryInfo (BaseUri.LocalPath).FullName);
+
+            return result ?? uri.AbsoluteUri;
         }
 
         protected virtual TimeSpan SecondsStringToTimeSpan(string seconds)
diff --git a/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/MassStorageSource.cs b/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/MassStorageSource.cs
index c8de72e..8d0f7fd 100644
--- a/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/MassStorageSource.cs
+++ b/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/MassStorageSource.cs
@@ -164,7 +164,7 @@ namespace Banshee.Dap.MassStorage
                     "INSERT INTO CorePlaylistEntries (PlaylistID, TrackID) VALUES (?, ?)");
                 int [] psources = new int [] {DbId};
                 foreach (string playlist_path in PlaylistFiles) {
-                    IPlaylistFormat loaded_playlist = PlaylistFileUtil.Load (playlist_path, new Uri (BaseDirectory));
+                    IPlaylistFormat loaded_playlist = PlaylistFileUtil.Load (playlist_path, new Uri (PlaylistsPath));
                     if (loaded_playlist == null)
                         continue;
 
@@ -332,7 +332,8 @@ namespace Banshee.Dap.MassStorage
                     System.IO.Stream stream = null;
                     try {
                         stream = Banshee.IO.File.OpenWrite (playlist_path, true);
-                        playlist_format.BaseUri = new Uri (BaseDirectory);
+                        playlist_format.BaseUri = new Uri (PlaylistsPath);
+
                         playlist_format.Save (stream, from);
                     } catch (Exception e) {
                         Log.Exception (e);
diff --git a/src/Libraries/Hyena/Hyena/Paths.cs b/src/Libraries/Hyena/Hyena/Paths.cs
index ef4831f..1294d3a 100644
--- a/src/Libraries/Hyena/Hyena/Paths.cs
+++ b/src/Libraries/Hyena/Hyena/Paths.cs
@@ -27,9 +27,9 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-using System;
 using System.IO;
-using Mono.Unix;
+using System;
+using System.Text;
 
 namespace Hyena
 {
@@ -113,6 +113,12 @@ namespace Hyena
                 return null;
             }
 
+            if (Path.IsPathRooted (path) ^ Path.IsPathRooted (to))
+            {
+                // one path is absolute, one path is relative, impossible to compare
+                return null;
+            }
+
             if (path == to) {
                 return String.Empty;
             }
@@ -121,13 +127,37 @@ namespace Hyena
                 to = to + Path.DirectorySeparatorChar;
             }
 
-            if (path.Length < to.Length) {
-                return null;
+            if (path.StartsWith (to))
+            {
+                return path.Substring (to.Length);
+            }
+
+            return BuildRelativePath (path, to);
+        }
+
+        private static string BuildRelativePath (string path, string to)
+        {
+            var toParts = to.Split (Path.DirectorySeparatorChar);
+            var pathParts = path.Split (Path.DirectorySeparatorChar);
+
+            var i = 0;
+            while (i < toParts.Length && i < pathParts.Length && toParts [i] == pathParts [i]) {
+                i++;
+            }
+
+            var relativePath = new StringBuilder ();
+            for (int j = 0; j < toParts.Length - i - 1; j++) {
+                relativePath.Append ("..");
+                relativePath.Append (Path.DirectorySeparatorChar);
+            }
+
+            var required = new string [pathParts.Length - i];
+            for (int j = i; j < pathParts.Length; j++) {
+                required [j - i] = pathParts [j];
             }
+            relativePath.Append (String.Join (Path.DirectorySeparatorChar.ToString (), required));
 
-            return path.StartsWith (to)
-                ? path.Substring (to.Length)
-                : null;
+            return relativePath.ToString ();
         }
 
         public static string ApplicationData {



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