[banshee] Make save-to-file and move-on-info-save jobs restartable
- From: Gabriel Burt <gburt src gnome org>
- To: svn-commits-list gnome org
- Subject: [banshee] Make save-to-file and move-on-info-save jobs restartable
- Date: Fri, 17 Apr 2009 00:13:20 -0400 (EDT)
commit efbab18f147eac2595dae9e6613bcfdfa75657f3
Author: Gabriel Burt <gabriel burt gmail com>
Date: Thu Apr 16 21:11:36 2009 -0500
Make save-to-file and move-on-info-save jobs restartable
2009-04-16 Gabriel Burt <gabriel burt gmail com>
* src/Core/Banshee.Core/Banshee.Base/Tests/TaglibReadWriteTests.cs:
* src/Core/Banshee.Core/Banshee.Streaming/StreamTagger.cs:
* src/Core/Banshee.Core/Banshee.Streaming/SaveTrackMetadataJob.cs:
* src/Core/Banshee.Core/Makefile.am: Remove old save job and move its
save-to-file logic into StreamTagger.
* src/Core/Banshee.Services/Makefile.am:
* src/Core/Banshee.Services/Banshee.Metadata/SaveTrackMetadataService.cs:
* src/Core/Banshee.Services/Banshee.Metadata/SaveTrackMetadataJob.cs: New
service and job that save-to-file and move-on-info-save if/when
appropriate.
* src/Core/Banshee.Services/Banshee.Preferences/PreferenceService.cs: the
SchemaPreferences are now created in SaveTrackMetadataServices; use them.
* src/Core/Banshee.Services/Banshee.ServiceStack/ServiceManager.cs: Start
the SaveTrackMetadataServices.
* src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/TrackEditorDialog.cs:
Get rid of the old write-to-file and move-on-info-save job queueing; now
happens based on the Updated and LastSynced stamps in the db.
* src/Libraries/Hyena/Hyena.Data.Sqlite/HyenaSqliteConnection.cs: Give
access to the underlying IDataReader from HyenaDataReader.
* src/Core/Banshee.Services/Banshee.Collection/MoveOnInfoSaveJob.cs:
Remove.
---
ChangeLog | 30 +++++
.../Banshee.Base/Tests/TaglibReadWriteTests.cs | 2 +-
.../Banshee.Streaming/SaveTrackMetadataJob.cs | 113 -----------------
.../Banshee.Core/Banshee.Streaming/StreamTagger.cs | 62 +++++++++
src/Core/Banshee.Core/Makefile.am | 1 -
.../Banshee.Collection/MoveOnInfoSaveJob.cs | 82 ------------
.../Banshee.Metadata/SaveTrackMetadataJob.cs | 131 ++++++++++++++++++++
.../Banshee.Metadata/SaveTrackMetadataService.cs | 126 +++++++++++++++++++
.../Banshee.Preferences/PreferenceService.cs | 9 +-
.../Banshee.ServiceStack/ServiceManager.cs | 1 +
src/Core/Banshee.Services/Makefile.am | 3 +-
.../Banshee.Gui.TrackEditor/TrackEditorDialog.cs | 18 ---
.../Hyena.Data.Sqlite/HyenaSqliteConnection.cs | 4 +
13 files changed, 359 insertions(+), 223 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index cebf856..aca54cc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,35 @@
2009-04-16 Gabriel Burt <gabriel burt gmail com>
+ * src/Core/Banshee.Core/Banshee.Base/Tests/TaglibReadWriteTests.cs:
+ * src/Core/Banshee.Core/Banshee.Streaming/StreamTagger.cs:
+ * src/Core/Banshee.Core/Banshee.Streaming/SaveTrackMetadataJob.cs:
+ * src/Core/Banshee.Core/Makefile.am: Remove old save job and move its
+ save-to-file logic into StreamTagger.
+
+ * src/Core/Banshee.Services/Makefile.am:
+ * src/Core/Banshee.Services/Banshee.Metadata/SaveTrackMetadataService.cs:
+ * src/Core/Banshee.Services/Banshee.Metadata/SaveTrackMetadataJob.cs: New
+ service and job that save-to-file and move-on-info-save if/when
+ appropriate.
+
+ * src/Core/Banshee.Services/Banshee.Preferences/PreferenceService.cs: the
+ SchemaPreferences are now created in SaveTrackMetadataServices; use them.
+
+ * src/Core/Banshee.Services/Banshee.ServiceStack/ServiceManager.cs: Start
+ the SaveTrackMetadataServices.
+
+ * src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/TrackEditorDialog.cs:
+ Get rid of the old write-to-file and move-on-info-save job queueing; now
+ happens based on the Updated and LastSynced stamps in the db.
+
+ * src/Libraries/Hyena/Hyena.Data.Sqlite/HyenaSqliteConnection.cs: Give
+ access to the underlying IDataReader from HyenaDataReader.
+
+ * src/Core/Banshee.Services/Banshee.Collection/MoveOnInfoSaveJob.cs:
+ Remove.
+
+2009-04-16 Gabriel Burt <gabriel burt gmail com>
+
Add a smart, priority-aware, resource-contention-avoiding job scheduler
Net result is BPM analysis will pause while importing, etc (BGO #577772).
Still need to convert Banshee.Kernel jobs.
diff --git a/src/Core/Banshee.Core/Banshee.Base/Tests/TaglibReadWriteTests.cs b/src/Core/Banshee.Core/Banshee.Base/Tests/TaglibReadWriteTests.cs
index fac2835..af568d4 100644
--- a/src/Core/Banshee.Core/Banshee.Base/Tests/TaglibReadWriteTests.cs
+++ b/src/Core/Banshee.Core/Banshee.Base/Tests/TaglibReadWriteTests.cs
@@ -121,7 +121,7 @@ namespace Banshee.Base.Tests
track.Year = 1999;
// Save changes
- new SaveTrackMetadataJob (track).Run ();
+ StreamTagger.SaveToFile (track);
// Read changes
file = StreamTagger.ProcessUri (uri);
diff --git a/src/Core/Banshee.Core/Banshee.Streaming/SaveTrackMetadataJob.cs b/src/Core/Banshee.Core/Banshee.Streaming/SaveTrackMetadataJob.cs
deleted file mode 100644
index 58dbf70..0000000
--- a/src/Core/Banshee.Core/Banshee.Streaming/SaveTrackMetadataJob.cs
+++ /dev/null
@@ -1,113 +0,0 @@
-//
-// SaveTrackMetadataJob.cs
-//
-// Author:
-// Aaron Bockover <abockover novell com>
-//
-// Copyright (C) 2006-2007 Novell, Inc.
-//
-// 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 Mono.Unix;
-
-using Banshee.Collection;
-using Banshee.Configuration.Schema;
-
-namespace Banshee.Streaming
-{
- public class SaveTrackMetadataJob : Banshee.Kernel.IInstanceCriticalJob
- {
- private TrackInfo track;
-
- public string Name {
- get { return String.Format (Catalog.GetString ("Saving tags for {0}"), track.TrackTitle); }
- }
-
- public SaveTrackMetadataJob (TrackInfo track)
- {
- this.track = track;
- }
-
- public void Run ()
- {
- if (!LibrarySchema.WriteMetadata.Get ()) {
- Console.WriteLine ("Skipping scheduled metadata write, preference disabled after scheduling");
- return;
- }
-
- // FIXME taglib# does not seem to handle writing metadata to video files well at all atm
- // so not allowing
- if ((track.MediaAttributes & TrackMediaAttributes.VideoStream) != 0) {
- Hyena.Log.DebugFormat ("Avoiding 100% cpu bug with taglib# by not writing metadata to video file {0}", track);
- return;
- }
-
- // Note: this should be kept in sync with the metadata read in StreamTagger.cs
- TagLib.File file = StreamTagger.ProcessUri (track.Uri);
- if (file == null) {
- return;
- }
-
- file.Tag.Performers = new string [] { track.ArtistName };
- file.Tag.PerformersSort = new string [] { track.ArtistNameSort };
- file.Tag.Album = track.AlbumTitle;
- file.Tag.AlbumSort = track.AlbumTitleSort;
- file.Tag.AlbumArtists = track.AlbumArtist == null ? new string [0] : new string [] {track.AlbumArtist};
- file.Tag.AlbumArtistsSort = (track.AlbumArtistSort == null ? new string [0] : new string [] {track.AlbumArtistSort});
- // Bug in taglib-sharp-2.0.3.0: Crash if you send it a genre of "{ null }"
- // on a song with both ID3v1 and ID3v2 metadata. It's happy with "{}", though.
- // (see http://forum.taglib-sharp.com/viewtopic.php?f=5&t=239 )
- file.Tag.Genres = (track.Genre == null) ? new string[] {} : new string [] { track.Genre };
- file.Tag.Title = track.TrackTitle;
- file.Tag.TitleSort = track.TrackTitleSort;
- file.Tag.Track = (uint)track.TrackNumber;
- file.Tag.TrackCount = (uint)track.TrackCount;
- file.Tag.Composers = new string [] { track.Composer };
- file.Tag.Conductor = track.Conductor;
- file.Tag.Grouping = track.Grouping;
- file.Tag.Copyright = track.Copyright;
- file.Tag.Comment = track.Comment;
- file.Tag.Disc = (uint)track.DiscNumber;
- file.Tag.DiscCount = (uint)track.DiscCount;
- file.Tag.Year = (uint)track.Year;
- file.Tag.BeatsPerMinute = (uint)track.Bpm;
-
- SaveIsCompilation (file.Tag, track.IsCompilation);
- file.Save ();
- }
-
- private static void SaveIsCompilation (TagLib.Tag tag, bool is_compilation)
- {
- TagLib.Id3v2.Tag id3v2_tag = tag as TagLib.Id3v2.Tag;
- if (id3v2_tag != null) {
- id3v2_tag.IsCompilation = is_compilation;
- return;
- }
-
- TagLib.Mpeg4.AppleTag apple_tag = tag as TagLib.Mpeg4.AppleTag;
- if (apple_tag != null) {
- apple_tag.IsCompilation = is_compilation;
- return;
- }
- }
- }
-}
diff --git a/src/Core/Banshee.Core/Banshee.Streaming/StreamTagger.cs b/src/Core/Banshee.Core/Banshee.Streaming/StreamTagger.cs
index f8fc1a5..153f02d 100644
--- a/src/Core/Banshee.Core/Banshee.Streaming/StreamTagger.cs
+++ b/src/Core/Banshee.Core/Banshee.Streaming/StreamTagger.cs
@@ -206,6 +206,68 @@ namespace Banshee.Streaming
}
return false;
}
+
+ private static void SaveIsCompilation (TagLib.Tag tag, bool is_compilation)
+ {
+ TagLib.Id3v2.Tag id3v2_tag = tag as TagLib.Id3v2.Tag;
+ if (id3v2_tag != null) {
+ id3v2_tag.IsCompilation = is_compilation;
+ return;
+ }
+
+ TagLib.Mpeg4.AppleTag apple_tag = tag as TagLib.Mpeg4.AppleTag;
+ if (apple_tag != null) {
+ apple_tag.IsCompilation = is_compilation;
+ return;
+ }
+ }
+
+ public static void SaveToFile (TrackInfo track)
+ {
+ // FIXME taglib# does not seem to handle writing metadata to video files well at all atm
+ // so not allowing
+ if ((track.MediaAttributes & TrackMediaAttributes.VideoStream) != 0) {
+ Hyena.Log.DebugFormat ("Avoiding 100% cpu bug with taglib# by not writing metadata to video file {0}", track);
+ return;
+ }
+
+ // Note: this should be kept in sync with the metadata read in StreamTagger.cs
+ TagLib.File file = ProcessUri (track.Uri);
+ if (file == null) {
+ return;
+ }
+
+ file.Tag.Performers = new string [] { track.ArtistName };
+ file.Tag.PerformersSort = new string [] { track.ArtistNameSort };
+ file.Tag.Album = track.AlbumTitle;
+ file.Tag.AlbumSort = track.AlbumTitleSort;
+ file.Tag.AlbumArtists = track.AlbumArtist == null ? new string [0] : new string [] {track.AlbumArtist};
+ file.Tag.AlbumArtistsSort = (track.AlbumArtistSort == null ? new string [0] : new string [] {track.AlbumArtistSort});
+ // Bug in taglib-sharp-2.0.3.0: Crash if you send it a genre of "{ null }"
+ // on a song with both ID3v1 and ID3v2 metadata. It's happy with "{}", though.
+ // (see http://forum.taglib-sharp.com/viewtopic.php?f=5&t=239 )
+ file.Tag.Genres = (track.Genre == null) ? new string[] {} : new string [] { track.Genre };
+ file.Tag.Title = track.TrackTitle;
+ file.Tag.TitleSort = track.TrackTitleSort;
+ file.Tag.Track = (uint)track.TrackNumber;
+ file.Tag.TrackCount = (uint)track.TrackCount;
+ file.Tag.Composers = new string [] { track.Composer };
+ file.Tag.Conductor = track.Conductor;
+ file.Tag.Grouping = track.Grouping;
+ file.Tag.Copyright = track.Copyright;
+ file.Tag.Comment = track.Comment;
+ file.Tag.Disc = (uint)track.DiscNumber;
+ file.Tag.DiscCount = (uint)track.DiscCount;
+ file.Tag.Year = (uint)track.Year;
+ file.Tag.BeatsPerMinute = (uint)track.Bpm;
+
+ SaveIsCompilation (file.Tag, track.IsCompilation);
+ file.Save ();
+
+ track.FileSize = Banshee.IO.File.GetSize (track.Uri);
+ track.FileModifiedStamp = Banshee.IO.File.GetModifiedTime (track.Uri);
+ track.LastSyncedStamp = DateTime.Now;
+ }
public static void TrackInfoMerge (TrackInfo track, StreamTag tag)
{
diff --git a/src/Core/Banshee.Core/Makefile.am b/src/Core/Banshee.Core/Makefile.am
index 70d8753..219235b 100644
--- a/src/Core/Banshee.Core/Makefile.am
+++ b/src/Core/Banshee.Core/Makefile.am
@@ -61,7 +61,6 @@ SOURCES = \
Banshee.Kernel/JobPriority.cs \
Banshee.Kernel/Scheduler.cs \
Banshee.Streaming/CommonTags.cs \
- Banshee.Streaming/SaveTrackMetadataJob.cs \
Banshee.Streaming/StreamPlaybackError.cs \
Banshee.Streaming/StreamTag.cs \
Banshee.Streaming/StreamTagger.cs
diff --git a/src/Core/Banshee.Services/Banshee.Collection/MoveOnInfoSaveJob.cs b/src/Core/Banshee.Services/Banshee.Collection/MoveOnInfoSaveJob.cs
deleted file mode 100644
index a81b12a..0000000
--- a/src/Core/Banshee.Services/Banshee.Collection/MoveOnInfoSaveJob.cs
+++ /dev/null
@@ -1,82 +0,0 @@
-//
-// MoveOnInfoSaveJob.cs
-//
-// Author:
-// Ruben Vermeersch <ruben savanne be>
-//
-// Copyright (C) 2006-2008 Novell, Inc.
-//
-// 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 Mono.Unix;
-
-using Banshee.Base;
-using Banshee.Collection.Database;
-using Banshee.Configuration.Schema;
-
-namespace Banshee.Collection
-{
- public class MoveOnInfoSaveJob : Banshee.Kernel.IInstanceCriticalJob
- {
- private DatabaseTrackInfo track;
-
- public string Name {
- get { return String.Format (Catalog.GetString ("Renaming {0}"), track.TrackTitle); }
- }
-
- public MoveOnInfoSaveJob (DatabaseTrackInfo track)
- {
- this.track = track;
- }
-
- public void Run ()
- {
- if (track == null) {
- return;
- }
-
- if (!LibrarySchema.MoveOnInfoSave.Get ()) {
- Hyena.Log.Debug ("Skipping scheduled rename, preference disabled after scheduling");
- return;
- }
-
- SafeUri old_uri = track.Uri;
- bool in_library = old_uri.AbsolutePath.StartsWith (track.PrimarySource.BaseDirectoryWithSeparator);
-
- if (!in_library) {
- return;
- }
-
- string new_filename = FileNamePattern.BuildFull (track.PrimarySource.BaseDirectory, track, Path.GetExtension (old_uri.ToString ()));
- SafeUri new_uri = new SafeUri (new_filename);
-
- if (!new_uri.Equals (old_uri) && !Banshee.IO.File.Exists (new_uri)) {
- Banshee.IO.File.Move (old_uri, new_uri);
- Banshee.IO.Utilities.TrimEmptyDirectories (old_uri);
- track.Uri = new_uri;
- track.Save ();
- }
- }
- }
-}
diff --git a/src/Core/Banshee.Services/Banshee.Metadata/SaveTrackMetadataJob.cs b/src/Core/Banshee.Services/Banshee.Metadata/SaveTrackMetadataJob.cs
new file mode 100644
index 0000000..bdcdac3
--- /dev/null
+++ b/src/Core/Banshee.Services/Banshee.Metadata/SaveTrackMetadataJob.cs
@@ -0,0 +1,131 @@
+//
+// SaveTrackMetadataJob.cs
+//
+// Authors:
+// Aaron Bockover <abockover novell com>
+// Gabriel Burt <gburt novell com>
+// Ruben Vermeersch <ruben savanne be>
+//
+// Copyright (C) 2006-2009 Novell, Inc.
+//
+// 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 Mono.Unix;
+
+using Hyena.Jobs;
+using Hyena.Data.Sqlite;
+
+using Banshee.Base;
+using Banshee.Streaming;
+using Banshee.Collection.Database;
+using Banshee.Library;
+using Banshee.ServiceStack;
+using Banshee.Configuration.Schema;
+using Banshee.Preferences;
+
+namespace Banshee.Metadata
+{
+ public class SaveTrackMetadataJob : DbIteratorJob
+ {
+ private LibrarySource source = ServiceManager.SourceManager.MusicLibrary;
+
+ public SaveTrackMetadataJob () : base (Catalog.GetString ("Saving Metadata to File"))
+ {
+ SetResources (Resource.Cpu, Resource.Disk, Resource.Database);
+ IsBackground = true;
+
+ CountCommand = new HyenaSqliteCommand (
+ "SELECT COUNT(*) FROM CoreTracks WHERE DateUpdatedStamp > LastSyncedStamp AND PrimarySourceID = ?",
+ source.DbId
+ );
+
+ SelectCommand = DatabaseTrackInfo.Provider.CreateFetchCommand (String.Format (
+ "DateUpdatedStamp > LastSyncedStamp AND PrimarySourceID = {0}", source.DbId)
+ );
+ }
+
+ public bool WriteEnabled { get; set; }
+ public bool RenameEnabled { get; set; }
+
+ private HyenaSqliteCommand update_synced_at;
+
+ protected override void IterateCore (HyenaDataReader reader)
+ {
+ DatabaseTrackInfo track = DatabaseTrackInfo.Provider.Load (reader.Reader);
+
+ bool wrote = false;
+ bool renamed = false;
+ try {
+ if (WriteEnabled) {
+ Hyena.Log.DebugFormat ("Saving metadata for {0}", track);
+ StreamTagger.SaveToFile (track);
+ wrote = true;
+ }
+
+ if (RenameEnabled) {
+ Hyena.Log.DebugFormat ("Updating file name for {0}", track);
+ renamed = RenameFile (track);
+ if (renamed && !wrote) {
+ track.LastSyncedStamp = DateTime.Now;
+ }
+ }
+ } catch (Exception) {
+ Hyena.Log.ErrorFormat ("Error writing to or renaming {0}", track);
+ } finally {
+ if (wrote || renamed) {
+ // Save the resulting changes to FileSize, LastSyncedStamp, possibly to Uri, etc
+ // TODO need to clear track model caches if URI changed
+ track.Save (false);
+ } else {
+ if (update_synced_at == null) {
+ update_synced_at = new HyenaSqliteCommand (
+ "UPDATE CoreTracks SET LastSyncedStamp = ? WHERE TrackID = ?");
+ }
+
+ ServiceManager.DbConnection.Execute (update_synced_at, DateTime.Now, track.TrackId);
+ }
+ }
+ }
+
+ private bool RenameFile (DatabaseTrackInfo track)
+ {
+ SafeUri old_uri = track.Uri;
+ bool in_library = old_uri.AbsolutePath.StartsWith (source.BaseDirectoryWithSeparator);
+
+ if (!in_library) {
+ return false;
+ }
+
+ string new_filename = FileNamePattern.BuildFull (source.BaseDirectory, track, System.IO.Path.GetExtension (old_uri.ToString ()));
+ SafeUri new_uri = new SafeUri (new_filename);
+
+ if (!new_uri.Equals (old_uri) && !Banshee.IO.File.Exists (new_uri)) {
+ Banshee.IO.File.Move (old_uri, new_uri);
+ Banshee.IO.Utilities.TrimEmptyDirectories (old_uri);
+ track.Uri = new_uri;
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/src/Core/Banshee.Services/Banshee.Metadata/SaveTrackMetadataService.cs b/src/Core/Banshee.Services/Banshee.Metadata/SaveTrackMetadataService.cs
new file mode 100644
index 0000000..aa4da0d
--- /dev/null
+++ b/src/Core/Banshee.Services/Banshee.Metadata/SaveTrackMetadataService.cs
@@ -0,0 +1,126 @@
+//
+// SaveTrackMetadataService.cs
+//
+// Author:
+// Gabriel Burt <gburt novell com>
+//
+// Copyright (C) 2009 Novell, Inc.
+//
+// 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 Mono.Unix;
+
+using Hyena.Jobs;
+using Hyena.Data.Sqlite;
+
+using Banshee.Streaming;
+using Banshee.Collection.Database;
+using Banshee.Sources;
+using Banshee.ServiceStack;
+using Banshee.Configuration.Schema;
+using Banshee.Preferences;
+
+namespace Banshee.Metadata
+{
+ public class SaveTrackMetadataService : IService
+ {
+ public static SchemaPreference<bool> WriteEnabled = new SchemaPreference<bool> (
+ LibrarySchema.WriteMetadata,
+ Catalog.GetString ("Write _metadata to files"),
+ Catalog.GetString ("Enable this option to save tags and other metadata inside supported audio files.")
+ );
+
+ public static SchemaPreference<bool> RenameEnabled = new SchemaPreference<bool> (
+ LibrarySchema.MoveOnInfoSave,
+ Catalog.GetString ("_Update file and folder names"),
+ Catalog.GetString ("Enabling this option ensures that files and folders are renamed according to the metadata.")
+ );
+
+ private SaveTrackMetadataJob job;
+ private object sync = new object ();
+ private bool inited = false;
+
+ public SaveTrackMetadataService ()
+ {
+ Banshee.ServiceStack.Application.RunTimeout (10000, delegate {
+ WriteEnabled.ValueChanged += OnEnabledChanged;
+ RenameEnabled.ValueChanged += OnEnabledChanged;
+ ServiceManager.SourceManager.MusicLibrary.TracksChanged += OnTracksChanged;
+ Save ();
+ inited = true;
+ return false;
+ });
+ }
+
+ public void Dispose ()
+ {
+ if (inited) {
+ ServiceManager.SourceManager.MusicLibrary.TracksChanged -= OnTracksChanged;
+
+ if (job != null) {
+ ServiceManager.JobScheduler.Cancel (job);
+ }
+ }
+ }
+
+ private void Save ()
+ {
+ if (!(WriteEnabled.Value || RenameEnabled.Value))
+ return;
+
+ lock (sync) {
+ if (job != null) {
+ job.WriteEnabled = WriteEnabled.Value;
+ job.RenameEnabled = RenameEnabled.Value;
+ return;
+ } else {
+ job = new SaveTrackMetadataJob ();
+ job.WriteEnabled = WriteEnabled.Value;
+ job.RenameEnabled = RenameEnabled.Value;
+ }
+ }
+
+ job.Finished += delegate { job = null; };
+ job.Register ();
+ }
+
+ private void OnTracksChanged (Source sender, TrackEventArgs args)
+ {
+ Save ();
+ }
+
+ private void OnEnabledChanged (Root pref)
+ {
+ if (WriteEnabled.Value || RenameEnabled.Value) {
+ Save ();
+ } else {
+ if (job != null) {
+ ServiceManager.JobScheduler.Cancel (job);
+ }
+ }
+ }
+
+ string IService.ServiceName {
+ get { return "SaveMetadataService"; }
+ }
+ }
+}
diff --git a/src/Core/Banshee.Services/Banshee.Preferences/PreferenceService.cs b/src/Core/Banshee.Services/Banshee.Preferences/PreferenceService.cs
index 07431f5..3a6b326 100644
--- a/src/Core/Banshee.Services/Banshee.Preferences/PreferenceService.cs
+++ b/src/Core/Banshee.Services/Banshee.Preferences/PreferenceService.cs
@@ -56,14 +56,9 @@ namespace Banshee.Preferences
policies.Add (new SchemaPreference<bool> (LibrarySchema.CopyOnImport,
Catalog.GetString ("Co_py files to media folders when importing")));
- policies.Add (new SchemaPreference<bool> (LibrarySchema.WriteMetadata,
- Catalog.GetString ("Write _metadata to files"),
- Catalog.GetString ("Enable this option to save tags and other metadata inside supported audio files.")));
+ policies.Add (Banshee.Metadata.SaveTrackMetadataService.WriteEnabled);
+ policies.Add (Banshee.Metadata.SaveTrackMetadataService.RenameEnabled);
- policies.Add (new SchemaPreference<bool> (LibrarySchema.MoveOnInfoSave,
- Catalog.GetString ("_Update file and folder names"),
- Catalog.GetString ("Enabling this option ensures that files and folders are renamed according to the metadata.")));
-
// Misc section
general.Add (new Section ("misc", Catalog.GetString ("Miscellaneous"), 20));
}
diff --git a/src/Core/Banshee.Services/Banshee.ServiceStack/ServiceManager.cs b/src/Core/Banshee.Services/Banshee.ServiceStack/ServiceManager.cs
index 0dcdd24..752798b 100644
--- a/src/Core/Banshee.Services/Banshee.ServiceStack/ServiceManager.cs
+++ b/src/Core/Banshee.Services/Banshee.ServiceStack/ServiceManager.cs
@@ -102,6 +102,7 @@ namespace Banshee.ServiceStack
RegisterService<JobScheduler> ();
RegisterService<Banshee.Hardware.HardwareManager> ();
RegisterService<Banshee.Collection.Indexer.CollectionIndexerService> ();
+ RegisterService<Banshee.Metadata.SaveTrackMetadataService> ();
}
public static void DefaultInitialize ()
diff --git a/src/Core/Banshee.Services/Makefile.am b/src/Core/Banshee.Services/Makefile.am
index adfbef4..a458bcb 100644
--- a/src/Core/Banshee.Services/Makefile.am
+++ b/src/Core/Banshee.Services/Makefile.am
@@ -41,7 +41,6 @@ SOURCES = \
Banshee.Collection/ImportManager.cs \
Banshee.Collection/MemoryTrackListModel.cs \
Banshee.Collection/ModelHelper.cs \
- Banshee.Collection/MoveOnInfoSaveJob.cs \
Banshee.Collection/RescanPipeline.cs \
Banshee.Collection/SelectAllSelection.cs \
Banshee.Collection/TrackListModel.cs \
@@ -110,6 +109,8 @@ SOURCES = \
Banshee.Metadata/IMetadataProvider.cs \
Banshee.Metadata/MetadataService.cs \
Banshee.Metadata/MetadataServiceJob.cs \
+ Banshee.Metadata/SaveTrackMetadataJob.cs \
+ Banshee.Metadata/SaveTrackMetadataService.cs \
Banshee.Networking/Network.cs \
Banshee.Networking/NetworkManager.cs \
Banshee.PlaybackController/IBasicPlaybackController.cs \
diff --git a/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/TrackEditorDialog.cs b/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/TrackEditorDialog.cs
index d0cba97..099bb66 100644
--- a/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/TrackEditorDialog.cs
+++ b/src/Core/Banshee.ThickClient/Banshee.Gui.TrackEditor/TrackEditorDialog.cs
@@ -543,29 +543,11 @@ namespace Banshee.Gui.TrackEditor
TrackInfo.ExportableMerge (track, track.SourceTrack);
track.SourceTrack.Save ();
- if (LibrarySchema.WriteMetadata.Get ()) {
- SaveToFile (track.SourceTrack);
- }
-
- if (LibrarySchema.MoveOnInfoSave.Get ()) {
- MoveSavedFile (track.SourceTrack);
- }
-
if (track.SourceTrack == ServiceManager.PlayerEngine.CurrentTrack) {
ServiceManager.PlayerEngine.TrackInfoUpdated ();
}
}
- private void SaveToFile (TrackInfo track)
- {
- Scheduler.Schedule (new Banshee.Streaming.SaveTrackMetadataJob (track), JobPriority.Highest);
- }
-
- private void MoveSavedFile (TrackInfo track)
- {
- Scheduler.Schedule (new MoveOnInfoSaveJob (track as DatabaseTrackInfo), JobPriority.Highest);
- }
-
#endregion
#region Static Helpers
diff --git a/src/Libraries/Hyena/Hyena.Data.Sqlite/HyenaSqliteConnection.cs b/src/Libraries/Hyena/Hyena.Data.Sqlite/HyenaSqliteConnection.cs
index 5019598..e3c059d 100644
--- a/src/Libraries/Hyena/Hyena.Data.Sqlite/HyenaSqliteConnection.cs
+++ b/src/Libraries/Hyena/Hyena.Data.Sqlite/HyenaSqliteConnection.cs
@@ -39,6 +39,10 @@ namespace Hyena.Data.Sqlite
{
private IDataReader reader;
private bool read = false;
+
+ public IDataReader Reader {
+ get { return reader; }
+ }
public HyenaDataReader (IDataReader reader)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]