banshee r4945 - in trunk/banshee: . src/Core/Banshee.Services src/Core/Banshee.Services/Banshee.Collection.Database src/Core/Banshee.Services/Banshee.Library src/Core/Banshee.Services/Banshee.PlayerMigration
- From: gburt svn gnome org
- To: svn-commits-list gnome org
- Subject: banshee r4945 - in trunk/banshee: . src/Core/Banshee.Services src/Core/Banshee.Services/Banshee.Collection.Database src/Core/Banshee.Services/Banshee.Library src/Core/Banshee.Services/Banshee.PlayerMigration
- Date: Sat, 24 Jan 2009 00:21:35 +0000 (UTC)
Author: gburt
Date: Sat Jan 24 00:21:35 2009
New Revision: 4945
URL: http://svn.gnome.org/viewvc/banshee?rev=4945&view=rev
Log:
2009-01-23 Gabriel Burt <gabriel burt gmail com>
* src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseImportManager.cs:
Move UpdateProgress out of ImportTrack method to avoid triggering the
Scanning.. user job when we're directly importing.
* src/Core/Banshee.Services/Banshee.Services.addin.xml:
* src/Core/Banshee.Services/Banshee.Library/ImportSourceManager.cs:
* src/Core/Banshee.Services/Makefile.am:
* src/Core/Banshee.Services/Banshee.PlayerMigration/RhythmboxPlayerImportSource.cs:
* src/Core/Banshee.Services/Banshee.PlayerMigration/AmarokPlayerImportSource.cs:
Patch from Paul Lange adding back Rhythmbox import support, and making the
migrators into extensions (though still in Core/) fixes (BGO #554511)
Added:
trunk/banshee/src/Core/Banshee.Services/Banshee.PlayerMigration/RhythmboxPlayerImportSource.cs
Modified:
trunk/banshee/ChangeLog
trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseImportManager.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.Library/ImportSourceManager.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.PlayerMigration/AmarokPlayerImportSource.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.Services.addin.xml
trunk/banshee/src/Core/Banshee.Services/Makefile.am
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseImportManager.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseImportManager.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseImportManager.cs Sat Jan 24 00:21:35 2009
@@ -128,6 +128,8 @@
if (track != null && track.TrackId > 0) {
UpdateProgress (String.Format ("{0} - {1}",
track.DisplayArtistName, track.DisplayTrackTitle));
+ } else {
+ UpdateProgress (null);
}
OnImportResult (track, path, null);
@@ -154,14 +156,12 @@
public DatabaseTrackInfo ImportTrack (SafeUri uri)
{
if (!IsWhiteListedFile (uri.LocalPath)) {
- UpdateProgress (null);
return null;
}
if (DatabaseTrackInfo.ContainsUri (uri, Paths.MakePathRelative (uri.AbsolutePath, BaseDirectory) ?? uri.AbsoluteUri, PrimarySourceIds)) {
// TODO add DatabaseTrackInfo.SyncedStamp property, and if the file has been
// updated since the last sync, fetch its metadata into the db.
- UpdateProgress (null);
return null;
}
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Library/ImportSourceManager.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Library/ImportSourceManager.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Library/ImportSourceManager.cs Sat Jan 24 00:21:35 2009
@@ -49,11 +49,7 @@
if (import_sources == null) {
import_sources = new List<IImportSource> ();
import_sources.Add (new HomeDirectoryImportSource ());
-
- if (AmarokPlayerImportSource.CanImport) {
- import_sources.Add (new AmarokPlayerImportSource ());
- }
-
+
foreach (IImportSource source in AddinManager.GetExtensionObjects ("/Banshee/Library/ImportSource")) {
if (source.CanImport) {
import_sources.Add (source);
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.PlayerMigration/AmarokPlayerImportSource.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.PlayerMigration/AmarokPlayerImportSource.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.PlayerMigration/AmarokPlayerImportSource.cs Sat Jan 24 00:21:35 2009
@@ -180,7 +180,7 @@
}
}
- public static new bool CanImport {
+ public override bool CanImport {
get { return Banshee.IO.File.Exists (new SafeUri (amarok_db_path)); }
}
Added: trunk/banshee/src/Core/Banshee.Services/Banshee.PlayerMigration/RhythmboxPlayerImportSource.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.PlayerMigration/RhythmboxPlayerImportSource.cs Sat Jan 24 00:21:35 2009
@@ -0,0 +1,360 @@
+//
+// RhythmboxPlayerImportSource.cs
+//
+// Author:
+// Sebastian DrÃge <slomo circular-chaos org>
+// Paul Lange <palango gmx de>
+//
+// Copyright (C) 2006 Sebastian DrÃge
+// Copyright (C) 2008 Paul Lange
+//
+// 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.Data;
+using System.IO;
+using System.Xml;
+
+using Mono.Unix;
+
+using Hyena.Data.Sqlite;
+
+using Banshee.Base;
+using Banshee.Collection.Database;
+using Banshee.Library;
+using Banshee.ServiceStack;
+using Banshee.Playlist;
+
+namespace Banshee.PlayerMigration
+{
+ public sealed class RhythmboxPlayerImportSource : ThreadPoolImportSource
+ {
+ private static readonly SafeUri rhythmbox_db_uri = new SafeUri (Banshee.Base.Paths.Combine (
+ Environment.GetFolderPath (Environment.SpecialFolder.Personal), ".gnome2", "rhythmbox", "rhythmdb.xml"
+ ));
+
+ private int count, processed;
+
+ protected override void ImportCore ()
+ {
+ LibraryImportManager import_manager = ServiceManager.Get<LibraryImportManager> ();
+
+ if (!IsValidXmlDocument (rhythmbox_db_uri)) {
+ LogError (SafeUri.UriToFilename (rhythmbox_db_uri), "Rhythmbox library is corrupted.");
+ return;
+ }
+
+ // Load Rhythmbox library
+ Stream stream_db = Banshee.IO.File.OpenRead (rhythmbox_db_uri);
+ XmlDocument xml_doc_db = new XmlDocument ();
+ xml_doc_db.Load (stream_db);
+ XmlElement db_root = xml_doc_db.DocumentElement;
+ stream_db.Close ();
+
+ if (db_root == null || !db_root.HasChildNodes || db_root.Name != "rhythmdb") {
+ LogError (SafeUri.UriToFilename (rhythmbox_db_uri), "Unable to open Rhythmbox library.");
+ return;
+ }
+
+ count = db_root.ChildNodes.Count;
+ processed = 0;
+
+ // Import Rhythmbox playlists if playlist file is available
+ SafeUri rhythmbox_playlists_uri = new SafeUri (Banshee.Base.Paths.Combine (
+ Environment.GetFolderPath (Environment.SpecialFolder.Personal),
+ ".gnome2", "rhythmbox", "playlists.xml"
+ ));
+
+ bool playlists_available = Banshee.IO.File.Exists (rhythmbox_playlists_uri);
+ XmlElement playlists_root = null;
+
+ if (playlists_available) {
+ if (IsValidXmlDocument (rhythmbox_playlists_uri)) {
+ Stream stream_playlists = Banshee.IO.File.OpenRead (rhythmbox_playlists_uri);
+ XmlDocument xml_doc_playlists = new XmlDocument ();
+ xml_doc_playlists.Load (stream_playlists);
+ playlists_root = xml_doc_playlists.DocumentElement;
+ stream_playlists.Close ();
+
+ if (playlists_root == null || !playlists_root.HasChildNodes || playlists_root.Name != "rhythmdb-playlists") {
+ playlists_available = false;
+ } else {
+ count += playlists_root.ChildNodes.Count;
+ }
+ } else {
+ LogError (SafeUri.UriToFilename (rhythmbox_playlists_uri), "Rhythmbox playlists are corrupted.");
+ playlists_available = false;
+ }
+ }
+
+ ImportSongs (import_manager, db_root.SelectNodes ("/rhythmdb/entry[ type='song']"));
+
+ //ImportPodcasts (import_manager, db_root.SelectNodes ("/rhythmdb/entry[ type='podcast-post']"));
+
+ if (playlists_available) {
+ ImportStaticPlaylists(playlists_root.SelectNodes ("/rhythmdb-playlists/playlist[ type='static']"));
+ }
+
+ import_manager.NotifyAllSources ();
+ }
+
+ private bool IsValidXmlDocument (SafeUri file)
+ {
+ XmlReaderSettings settings = new XmlReaderSettings ();
+ settings.ValidationType = ValidationType.None;
+ settings.ConformanceLevel = ConformanceLevel.Document;
+
+ XmlReader validator = XmlReader.Create (Banshee.IO.File.OpenRead (file), settings);
+
+ try {
+ while (validator.Read ()) {
+ }
+ } catch (Exception) {
+ return false;
+ }
+ return true;
+ }
+
+ private void ImportSongs (LibraryImportManager manager, XmlNodeList songs)
+ {
+ foreach (XmlElement song in songs) {
+ if (CheckForCanceled ()) {
+ break;
+ }
+
+ processed++;
+
+ string title = String.Empty,
+ genre = String.Empty,
+ artist = String.Empty,
+ album = String.Empty;
+ int year = 0,
+ rating = 0,
+ play_count = 0,
+ track_number = 0;
+ DateTime date_added = DateTime.Now,
+ last_played = DateTime.MinValue;
+ SafeUri uri = null;
+
+ foreach (XmlElement child in song.ChildNodes) {
+ if (child == null || child.InnerText == null || child.InnerText == String.Empty) {
+ continue;
+ }
+
+ try {
+ switch (child.Name) {
+ case "title":
+ title = child.InnerText;
+ break;
+ case "genre":
+ genre = child.InnerText;
+ break;
+ case "artist":
+ artist = child.InnerText;
+ break;
+ case "album":
+ album = child.InnerText;
+ break;
+ case "track-number":
+ track_number = Int32.Parse (child.InnerText);
+ break;
+ case "location":
+ uri = new SafeUri (child.InnerText);
+ break;
+ case "date":
+ if (child.InnerText != "0") {
+ year = (new DateTime (1, 1, 1).AddDays (Double.Parse (child.InnerText))).Year;
+ }
+ break;
+ case "rating":
+ rating = Int32.Parse (child.InnerText);
+ break;
+ case "play-count":
+ play_count = Int32.Parse (child.InnerText);
+ break;
+ case "last-played":
+ last_played = Hyena.DateTimeUtil.ToDateTime (Int64.Parse (child.InnerText));
+ break;
+ case "first-seen":
+ date_added = Hyena.DateTimeUtil.ToDateTime (Int64.Parse (child.InnerText));;
+ break;
+ }
+ } catch (Exception) {
+ // parsing InnerText failed
+ }
+ }
+
+ if (uri == null) {
+ continue;
+ }
+
+ UpdateUserJob (processed, count, artist, title);
+
+ try {
+ DatabaseTrackInfo track = manager.ImportTrack (uri);
+
+ if (track == null) {
+ LogError (SafeUri.UriToFilename (uri), Catalog.GetString ("Unable to import song."));
+ continue;
+ }
+
+ track.TrackTitle = title;
+ track.ArtistName = artist;
+ track.Genre = genre;
+ track.AlbumTitle = album;
+ track.TrackNumber = track_number;
+ track.Year = year;
+ track.DateAdded = date_added;
+
+ track.Rating = (rating >= 0 && rating <= 5) ? rating : 0;
+ track.PlayCount = (play_count >= 0) ? play_count : 0;
+ track.LastPlayed = last_played;
+
+ track.Save (false);
+ } catch (Exception e) {
+ LogError (SafeUri.UriToFilename (uri), e);
+ }
+ }
+ }
+
+ // Commented out for now - this method doesn't handle actually subscribing to the feeds
+ // (the most important task in migrating podcasts), and it looks like it imports podcast files
+ // into the Music Library.
+ /*private void ImportPodcasts(LibraryImportManager manager, XmlNodeList podcasts)
+ {
+ foreach (XmlElement entry in podcasts) {
+ if (CheckForCanceled ()) {
+ break;
+ }
+
+ processed++;
+
+ string title = String.Empty, feed = String.Empty;
+ SafeUri uri = null;
+
+ foreach (XmlElement child in entry.ChildNodes) {
+ if (child == null || child.InnerText == null || child.InnerText == String.Empty) {
+ continue;
+ }
+
+ try {
+ switch (child.Name) {
+ case "title":
+ title = child.InnerText;
+ break;
+ case "album":
+ feed = child.InnerText;
+ break;
+ case "mountpoint":
+ uri = new SafeUri (child.InnerText);
+ break;
+ }
+ } catch (Exception) {
+ // parsing InnerText failed
+ }
+ }
+
+ if (uri == null) {
+ continue;
+ }
+
+ UpdateUserJob (processed, count, "", title);
+
+ try {
+ DatabaseTrackInfo track = manager.ImportTrack (uri);
+
+ if (track == null) {
+ LogError (SafeUri.UriToFilename (uri), Catalog.GetString ("Unable to import podcast."));
+ continue;
+ }
+
+ track.TrackTitle = title;
+ track.AlbumTitle = feed;
+ track.Genre = "Podcast";
+
+ track.Save (false);
+ } catch (Exception e) {
+ LogError (SafeUri.UriToFilename (uri), e);
+ }
+ }
+ }*/
+
+ private void ImportStaticPlaylists(XmlNodeList playlists)
+ {
+ foreach (XmlElement list in playlists) {
+ if (CheckForCanceled ()) {
+ break;
+ }
+
+ processed++;
+
+ try {
+ string title = String.Empty;
+ if (list.HasAttribute ("name")) {
+ title = list.GetAttribute ("name");
+ }
+
+ UpdateUserJob (processed, count, "", title);
+
+ PlaylistSource playlist = new PlaylistSource (title, ServiceManager.SourceManager.MusicLibrary);
+ playlist.Save ();
+ ServiceManager.SourceManager.MusicLibrary.AddChildSource (playlist);
+
+
+ HyenaSqliteCommand insert_command = new HyenaSqliteCommand (String.Format (
+ @"INSERT INTO CorePlaylistEntries (PlaylistID, TrackID) VALUES ({0}, ?)", playlist.DbId));
+
+ foreach (XmlElement entry in list.ChildNodes) {
+ if (entry.Name != "location") {
+ continue;
+ }
+
+ int track_id = Banshee.Library.LibrarySource.GetTrackIdForUri (entry.InnerText);
+ if (track_id > 0) {
+ ServiceManager.DbConnection.Execute (insert_command, track_id);
+ }
+ }
+
+ playlist.Reload ();
+ playlist.NotifyUser ();
+ } catch (Exception e) {
+ LogError ("", e);
+ }
+ }
+ }
+
+ public override bool CanImport {
+ get { return Banshee.IO.File.Exists (rhythmbox_db_uri); }
+ }
+
+ public override string Name {
+ get { return Catalog.GetString ("Rhythmbox Music Player"); }
+ }
+
+ public override string [] IconNames {
+ get { return new string [] { "rhythmbox", "system-search" }; }
+ }
+
+ public override int SortOrder {
+ get { return 40; }
+ }
+ }
+}
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Services.addin.xml
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Services.addin.xml (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Services.addin.xml Sat Jan 24 00:21:35 2009
@@ -21,6 +21,11 @@
<ExtensionNode name="ImportSource"/>
</ExtensionPoint>
+ <Extension path="/Banshee/Library/ImportSource">
+ <ImportSource class="Banshee.PlayerMigration.RhythmboxPlayerImportSource"/>
+ <ImportSource class="Banshee.PlayerMigration.AmarokPlayerImportSource"/>
+ </Extension>
+
<ExtensionPoint path="/Banshee/MediaEngine/PlayerEngine">
<ExtensionNode name="PlayerEngine"/>
</ExtensionPoint>
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 Sat Jan 24 00:21:35 2009
@@ -116,6 +116,7 @@
Banshee.PlaybackController/PlaybackRepeatMode.cs \
Banshee.PlaybackController/PlaybackShuffleMode.cs \
Banshee.PlayerMigration/AmarokPlayerImportSource.cs \
+ Banshee.PlayerMigration/RhythmboxPlayerImportSource.cs \
Banshee.Playlist/AbstractPlaylistSource.cs \
Banshee.Playlist/PlaylistFileUtil.cs \
Banshee.Playlist/PlaylistSource.cs \
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]