banshee r5072 - in trunk/banshee: . src/Core/Banshee.Services src/Core/Banshee.Services/Banshee.Playlist src/Core/Banshee.Services/Banshee.Playlists.Formats src/Libraries/Mono.Media/Media.Playlists.Xspf
- From: gburt svn gnome org
- To: svn-commits-list gnome org
- Subject: banshee r5072 - in trunk/banshee: . src/Core/Banshee.Services src/Core/Banshee.Services/Banshee.Playlist src/Core/Banshee.Services/Banshee.Playlists.Formats src/Libraries/Mono.Media/Media.Playlists.Xspf
- Date: Thu, 26 Feb 2009 20:23:09 +0000 (UTC)
Author: gburt
Date: Thu Feb 26 20:23:09 2009
New Revision: 5072
URL: http://svn.gnome.org/viewvc/banshee?rev=5072&view=rev
Log:
2009-02-26 Gabriel Burt <gabriel burt gmail com>
* src/Core/Banshee.Services/Banshee.Playlist/PlaylistFileUtil.cs:
* src/Core/Banshee.Services/Banshee.Playlists.Formats/IPlaylistFormat.cs:
* src/Core/Banshee.Services/Banshee.Playlists.Formats/PlaylistFormatBase.cs:
* src/Core/Banshee.Services/Banshee.Playlists.Formats/PlaylistParser.cs:
* src/Core/Banshee.Services/Banshee.Playlists.Formats/XspfPlaylistFormat.cs:
* src/Core/Banshee.Services/Makefile.am:
* src/Libraries/Mono.Media/Media.Playlists.Xspf/Playlist.cs:
* src/Libraries/Mono.Media/Media.Playlists.Xspf/Track.cs:
Patch from John Millikin adding support for importing and exporting XSPF
playlist files (BGO #389537)
Added:
trunk/banshee/src/Core/Banshee.Services/Banshee.Playlists.Formats/XspfPlaylistFormat.cs
Modified:
trunk/banshee/ChangeLog
trunk/banshee/src/Core/Banshee.Services/Banshee.Playlist/PlaylistFileUtil.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.Playlists.Formats/IPlaylistFormat.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.Playlists.Formats/PlaylistFormatBase.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.Playlists.Formats/PlaylistParser.cs
trunk/banshee/src/Core/Banshee.Services/Makefile.am
trunk/banshee/src/Libraries/Mono.Media/Media.Playlists.Xspf/Playlist.cs
trunk/banshee/src/Libraries/Mono.Media/Media.Playlists.Xspf/Track.cs
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Playlist/PlaylistFileUtil.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Playlist/PlaylistFileUtil.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Playlist/PlaylistFileUtil.cs Thu Feb 26 20:23:09 2009
@@ -40,12 +40,14 @@
private static PlaylistFormatDescription [] export_formats = new PlaylistFormatDescription [] {
M3uPlaylistFormat.FormatDescription,
- PlsPlaylistFormat.FormatDescription
+ PlsPlaylistFormat.FormatDescription,
+ XspfPlaylistFormat.FormatDescription
};
public static readonly string [] PlaylistExtensions = new string [] {
M3uPlaylistFormat.FormatDescription.FileExtension,
- PlsPlaylistFormat.FormatDescription.FileExtension
+ PlsPlaylistFormat.FormatDescription.FileExtension,
+ XspfPlaylistFormat.FormatDescription.FileExtension
};
public static PlaylistFormatDescription [] ExportFormats {
@@ -197,7 +199,7 @@
}
ImportPlaylistWorker worker = new ImportPlaylistWorker (
- System.IO.Path.GetFileNameWithoutExtension (uri.LocalPath),
+ parser.Title,
uris.ToArray (), source, importer);
worker.Import ();
}
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Playlists.Formats/IPlaylistFormat.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Playlists.Formats/IPlaylistFormat.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Playlists.Formats/IPlaylistFormat.cs Thu Feb 26 20:23:09 2009
@@ -45,5 +45,6 @@
List<Dictionary<string, object>> Elements { get; }
Uri BaseUri { get; set; }
+ string Title { get; set; }
}
}
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Playlists.Formats/PlaylistFormatBase.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Playlists.Formats/PlaylistFormatBase.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Playlists.Formats/PlaylistFormatBase.cs Thu Feb 26 20:23:09 2009
@@ -40,6 +40,7 @@
private Dictionary<string, object> attributes = new Dictionary<string, object>();
private List<Dictionary<string, object>> elements = new List<Dictionary<string, object>>();
private Uri base_uri = new Uri(Environment.CurrentDirectory);
+ private string title = null;
public PlaylistFormatBase()
{
@@ -118,5 +119,10 @@
base_uri = value;
}
}
+
+ public virtual string Title {
+ get { return title; }
+ set { title = value; }
+ }
}
}
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Playlists.Formats/PlaylistParser.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Playlists.Formats/PlaylistParser.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Playlists.Formats/PlaylistParser.cs Thu Feb 26 20:23:09 2009
@@ -41,11 +41,13 @@
private static PlaylistFormatDescription [] playlist_formats = new PlaylistFormatDescription [] {
M3uPlaylistFormat.FormatDescription,
PlsPlaylistFormat.FormatDescription,
- AsxPlaylistFormat.FormatDescription
+ AsxPlaylistFormat.FormatDescription,
+ XspfPlaylistFormat.FormatDescription
};
private List<Dictionary<string, object>> elements;
private Uri base_uri = new Uri (Environment.CurrentDirectory);
+ private string title = null;
public PlaylistParser ()
{
@@ -134,6 +136,7 @@
stream.Dispose ();
elements = playlist.Elements;
+ Title = playlist.Title ?? Path.GetFileNameWithoutExtension (uri.LocalPath);
return true;
}
}
@@ -146,5 +149,10 @@
get { return base_uri; }
set { base_uri = value; }
}
+
+ public string Title {
+ get { return title; }
+ set { title = value; }
+ }
}
}
Added: trunk/banshee/src/Core/Banshee.Services/Banshee.Playlists.Formats/XspfPlaylistFormat.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Playlists.Formats/XspfPlaylistFormat.cs Thu Feb 26 20:23:09 2009
@@ -0,0 +1,92 @@
+//
+// XspfPlaylistFormat.cs
+//
+// Author:
+// John Millikin <jmillikin gmail com>
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.IO;
+using System.Collections.Generic;
+
+using Mono.Unix;
+
+using Banshee.Collection;
+using Banshee.Sources;
+using Xspf = Media.Playlists.Xspf;
+
+namespace Banshee.Playlists.Formats
+{
+ public class XspfPlaylistFormat : PlaylistFormatBase
+ {
+ public static readonly PlaylistFormatDescription FormatDescription = new PlaylistFormatDescription (
+ typeof (XspfPlaylistFormat),
+ MagicHandler,
+ Catalog.GetString ("XML Shareable Playlist Format version 1 (*.xspf)"),
+ "xspf",
+ new string [] {"application/xspf+xml"}
+ );
+
+ public static bool MagicHandler (StreamReader stream)
+ {
+ return Xspf.Playlist.Sniff (stream);
+ }
+
+ public XspfPlaylistFormat ()
+ {
+ }
+
+ public override void Load (StreamReader stream, bool validateHeader)
+ {
+ Xspf.Playlist playlist = new Xspf.Playlist ();
+ playlist.DefaultBaseUri = BaseUri;
+ playlist.Load (stream);
+ Title = playlist.Title;
+ foreach (Xspf.Track track in playlist.Tracks) {
+ Dictionary<string, object> element = AddElement ();
+ element["uri"] = track.GetLocationAt (0);
+ }
+ }
+
+ public override void Save (Stream stream, ITrackModelSource source)
+ {
+ Xspf.Playlist playlist = new Xspf.Playlist ();
+ playlist.Title = source.Name;
+ playlist.Date = DateTime.Now;
+ for (int ii = 0; ii < source.TrackModel.Count; ii++) {
+ TrackInfo track = source.TrackModel[ii];
+ Xspf.Track xtrack = new Xspf.Track ();
+ xtrack.AddLocation (new Uri (ExportUri (track.Uri), UriKind.RelativeOrAbsolute));
+ xtrack.Title = track.TrackTitle;
+ xtrack.Creator = track.ArtistName;
+ xtrack.Album = track.AlbumTitle;
+ if (track.TrackNumber >= 0) {
+ xtrack.TrackNumber = (uint)track.TrackNumber;
+ }
+ xtrack.Duration = track.Duration;
+ playlist.AddTrack (xtrack);
+ }
+ playlist.Save (stream);
+ }
+ }
+}
+// vi:tabstop=4:expandtab
Modified: trunk/banshee/src/Core/Banshee.Services/Makefile.am
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Makefile.am (original)
+++ trunk/banshee/src/Core/Banshee.Services/Makefile.am Thu Feb 26 20:23:09 2009
@@ -132,6 +132,7 @@
Banshee.Playlists.Formats/PlaylistFormatDescription.cs \
Banshee.Playlists.Formats/PlaylistParser.cs \
Banshee.Playlists.Formats/PlsPlaylistFormat.cs \
+ Banshee.Playlists.Formats/XspfPlaylistFormat.cs \
Banshee.Playlists.Formats/Tests/PlaylistFormatTests.cs \
Banshee.Preferences/Collection.cs \
Banshee.Preferences/Page.cs \
Modified: trunk/banshee/src/Libraries/Mono.Media/Media.Playlists.Xspf/Playlist.cs
==============================================================================
--- trunk/banshee/src/Libraries/Mono.Media/Media.Playlists.Xspf/Playlist.cs (original)
+++ trunk/banshee/src/Libraries/Mono.Media/Media.Playlists.Xspf/Playlist.cs Thu Feb 26 20:23:09 2009
@@ -56,22 +56,77 @@
{
}
- private void Load(XmlDocument doc)
+ private static XmlNamespaceManager BuildNamespaceManager (XmlDocument doc)
+ {
+ XmlNamespaceManager xmlns = new XmlNamespaceManager (doc.NameTable);
+ xmlns.AddNamespace ("xspf", XspfNamespace);
+ return xmlns;
+ }
+
+ private static XmlNode FindPlaylistNode (XmlDocument doc, XmlNamespaceManager xmlns)
+ {
+ XmlNode playlist_node = doc.SelectSingleNode ("/xspf:playlist", xmlns);
+ if (playlist_node == null) {
+ // Hack to work with files that don't have a namespace on the <playlist> node
+ xmlns.AddNamespace ("xspf", String.Empty);
+ playlist_node = doc.SelectSingleNode ("/xspf:playlist", xmlns);
+ }
+ return playlist_node;
+ }
+
+ private static bool Sniff (XmlDocument doc)
{
- XmlNamespaceManager xmlns = new XmlNamespaceManager(doc.NameTable);
- xmlns.AddNamespace("xspf", XspfNamespace);
+ XmlNamespaceManager xmlns = BuildNamespaceManager (doc);
+ XmlNode playlist_node = FindPlaylistNode (doc, xmlns);
- XmlNode playlist_node = doc.SelectSingleNode("/xspf:playlist", xmlns);
-
- if(playlist_node == null) {
- // Hack to work with files that don't have a namespace on the <playlist> node, like Last.fm
- xmlns.AddNamespace("xspf", String.Empty);
- playlist_node = doc.SelectSingleNode("/xspf:playlist", xmlns);
-
- if(playlist_node == null) {
- throw new ApplicationException("Not a valid XSPF playlist");
+ if (playlist_node != null) {
+ XmlAttribute version_attr = playlist_node.Attributes["version"];
+ if (!(version_attr == null || version_attr.Value == null)) {
+ try {
+ int version = Int32.Parse (version_attr.Value);
+ if (version == 0 || version == 1) { return true; }
+ } catch (FormatException) { }
}
}
+ return false;
+ }
+
+ public static bool Sniff (string path)
+ {
+ XmlDocument doc = new XmlDocument ();
+ doc.Load (path);
+ return Sniff (doc);
+ }
+
+ public static bool Sniff (XmlReader reader)
+ {
+ XmlDocument doc = new XmlDocument ();
+ doc.Load (reader);
+ return Sniff (doc);
+ }
+
+ public static bool Sniff (TextReader reader)
+ {
+ XmlDocument doc = new XmlDocument ();
+ doc.Load (reader);
+ return Sniff (doc);
+ }
+
+ public static bool Sniff (Stream stream)
+ {
+ XmlDocument doc = new XmlDocument ();
+ doc.Load (stream);
+ return Sniff (doc);
+ }
+
+ private void Load(XmlDocument doc)
+ {
+ XmlNamespaceManager xmlns = BuildNamespaceManager (doc);
+ XmlNode playlist_node = FindPlaylistNode (doc, xmlns);
+
+ if (playlist_node == null) {
+ throw new ApplicationException ("Not a valid XSPF playlist");
+ }
XmlAttribute version_attr = playlist_node.Attributes["version"];
if(version_attr == null || version_attr.Value == null) {
@@ -161,6 +216,10 @@
SaveBase(writer);
+ if (Date.Ticks > 0) {
+ writer.WriteElementString ("date", Date.ToUniversalTime ().ToString ("o"));
+ }
+
writer.WriteStartElement("trackList");
foreach(Track track in tracks) {
writer.WriteStartElement("track");
Modified: trunk/banshee/src/Libraries/Mono.Media/Media.Playlists.Xspf/Track.cs
==============================================================================
--- trunk/banshee/src/Libraries/Mono.Media/Media.Playlists.Xspf/Track.cs (original)
+++ trunk/banshee/src/Libraries/Mono.Media/Media.Playlists.Xspf/Track.cs Thu Feb 26 20:23:09 2009
@@ -89,8 +89,14 @@
writer.WriteElementString("album", album);
}
+ // Only write valid (ie non-0) track numbers
+ if (TrackNumber > 0) {
+ writer.WriteElementString ("trackNum", TrackNumber.ToString ());
+ }
+
foreach(Uri uri in locations) {
- writer.WriteElementString("location", uri.AbsoluteUri);
+ string escaped = uri.IsAbsoluteUri? uri.AbsoluteUri : Uri.EscapeUriString (uri.ToString ());
+ writer.WriteElementString ("location", escaped);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]