banshee r4521 - in trunk/banshee: . src/Backends/Banshee.Unix/Banshee.IO.Unix src/Core/Banshee.Core/Banshee.Collection src/Core/Banshee.Core/Banshee.IO src/Core/Banshee.Core/Banshee.IO.SystemIO src/Core/Banshee.Core/Banshee.Streaming src/Core/Banshee.Services src/Core/Banshee.Services/Banshee.Collection src/Core/Banshee.Services/Banshee.Collection.Database src/Core/Banshee.Services/Banshee.Database src/Core/Banshee.ThickClient/Banshee.Gui src/Core/Banshee.ThickClient/Resources src/Libraries/Hyena/Hyena.Collections src/Libraries/Hyena/Hyena.Data.Sqlite
- From: gburt svn gnome org
- To: svn-commits-list gnome org
- Subject: banshee r4521 - in trunk/banshee: . src/Backends/Banshee.Unix/Banshee.IO.Unix src/Core/Banshee.Core/Banshee.Collection src/Core/Banshee.Core/Banshee.IO src/Core/Banshee.Core/Banshee.IO.SystemIO src/Core/Banshee.Core/Banshee.Streaming src/Core/Banshee.Services src/Core/Banshee.Services/Banshee.Collection src/Core/Banshee.Services/Banshee.Collection.Database src/Core/Banshee.Services/Banshee.Database src/Core/Banshee.ThickClient/Banshee.Gui src/Core/Banshee.ThickClient/Resources src/Libraries/Hyena/Hyena.Collections src/Libraries/Hyena/Hyena.Data.Sqlite
- Date: Fri, 12 Sep 2008 01:35:43 +0000 (UTC)
Author: gburt
Date: Fri Sep 12 01:35:43 2008
New Revision: 4521
URL: http://svn.gnome.org/viewvc/banshee?rev=4521&view=rev
Log:
2008-09-11 Gabriel Burt <gabriel burt gmail com>
* src/Core/Banshee.ThickClient/Banshee.Gui/GlobalActions.cs:
* src/Core/Banshee.ThickClient/Resources/core-ui-actions-layout.xml: Add
Rescan action that triggers rescan of the Music Library folder.
* src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseImportManager.cs:
Remove unnecessary DateAdded set.
* src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackInfo.cs:
* src/Core/Banshee.Core/Banshee.Collection/TrackInfo.cs: Add
FileModifiedStamp and LastSyncedStamp properties.
* src/Core/Banshee.Services/Makefile.am:
* src/Core/Banshee.Services/Banshee.Services.csproj:
* src/Core/Banshee.Services/Banshee.Collection/RescanPipeline.cs: New file
that scans all files in a Library's BaseDirectory, importing new items,
removing items no longer on disk, and identifying items that were renamed.
* src/Libraries/Hyena/Hyena.Collections/QueuePipelineElement.cs:
* src/Core/Banshee.Services/Banshee.Collection/ImportManager.cs: Factor a
lot of the counting of the ImportElement up into QueuePipelineElement.
* src/Core/Banshee.Services/Banshee.Database/BansheeDbFormatMigrator.cs:
Add the LastSynced and FileModified columns.
* src/Core/Banshee.Core/Banshee.IO.SystemIO/File.cs:
* src/Core/Banshee.Core/Banshee.IO/File.cs:
* src/Core/Banshee.Core/Banshee.IO/IFile.cs:
* src/Backends/Banshee.Unix/Banshee.IO.Unix/File.cs: Add GetModifiedTime
method.
* src/Core/Banshee.Core/Banshee.Streaming/StreamTagger.cs: Set
FileModified and LastSynced stamps.
* src/Libraries/Hyena/Hyena.Collections/QueuePipeline.cs: Make sure no
elements still have items left to process when considering if the pipeline
is finished/empty.
* src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelProvider.cs: Add
CreateFetchCommand method that returns a HyenaSqliteCommand useful for
fetching items from a model with a custom condition/limit/order.
Added:
trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/RescanPipeline.cs
Modified:
trunk/banshee/ChangeLog
trunk/banshee/src/Backends/Banshee.Unix/Banshee.IO.Unix/File.cs
trunk/banshee/src/Core/Banshee.Core/Banshee.Collection/TrackInfo.cs
trunk/banshee/src/Core/Banshee.Core/Banshee.IO.SystemIO/File.cs
trunk/banshee/src/Core/Banshee.Core/Banshee.IO/File.cs
trunk/banshee/src/Core/Banshee.Core/Banshee.IO/IFile.cs
trunk/banshee/src/Core/Banshee.Core/Banshee.Streaming/StreamTagger.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseImportManager.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackInfo.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/ImportManager.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.Database/BansheeDbFormatMigrator.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.Services.csproj
trunk/banshee/src/Core/Banshee.Services/Makefile.am
trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/GlobalActions.cs
trunk/banshee/src/Core/Banshee.ThickClient/Resources/core-ui-actions-layout.xml
trunk/banshee/src/Libraries/Hyena/Hyena.Collections/QueuePipeline.cs
trunk/banshee/src/Libraries/Hyena/Hyena.Collections/QueuePipelineElement.cs
trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelProvider.cs
Modified: trunk/banshee/src/Backends/Banshee.Unix/Banshee.IO.Unix/File.cs
==============================================================================
--- trunk/banshee/src/Backends/Banshee.Unix/Banshee.IO.Unix/File.cs (original)
+++ trunk/banshee/src/Backends/Banshee.Unix/Banshee.IO.Unix/File.cs Fri Sep 12 01:35:43 2008
@@ -40,6 +40,7 @@
private Stat buf;
private bool is_directory;
private bool is_regular_file;
+ private long mtime;
internal FileStat (string path)
{
@@ -49,6 +50,7 @@
is_directory &= (buf.st_mode & FilePermissions.S_IFDIR) == FilePermissions.S_IFDIR;
// FIXME: workaround for http://bugzilla.ximian.com/show_bug.cgi?id=76966
is_directory &= ! ((buf.st_mode & FilePermissions.S_IFSOCK) == FilePermissions.S_IFSOCK);
+ mtime = buf.st_mtime;
}
internal bool IsDirectory {
@@ -58,6 +60,10 @@
internal bool IsRegularFile {
get { return is_regular_file; }
}
+
+ internal long MTime {
+ get { return mtime; }
+ }
}
public class File : IFile
@@ -73,7 +79,7 @@
FileStat stat = new FileStat (uri.LocalPath);
return stat.IsRegularFile && !stat.IsDirectory;
}
-
+
public void Move (SafeUri from, SafeUri to)
{
Mono.Unix.Native.Stdlib.rename (from.LocalPath, to.LocalPath);
@@ -106,5 +112,11 @@
return -1;
}
}
+
+ public long GetModifiedTime (SafeUri uri)
+ {
+ FileStat stat = new FileStat (uri.LocalPath);
+ return stat.MTime;
+ }
}
}
Modified: trunk/banshee/src/Core/Banshee.Core/Banshee.Collection/TrackInfo.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Core/Banshee.Collection/TrackInfo.cs (original)
+++ trunk/banshee/src/Core/Banshee.Core/Banshee.Collection/TrackInfo.cs Fri Sep 12 01:35:43 2008
@@ -62,6 +62,7 @@
private SafeUri more_info_uri;
private string mimetype;
private long filesize;
+ private long file_mtime;
private string artist_name;
private string album_title;
@@ -89,6 +90,7 @@
private TimeSpan duration;
private DateTime release_date;
private DateTime date_added;
+ private DateTime last_synced;
private int play_count;
private int skip_count;
@@ -174,6 +176,16 @@
set { filesize = value; }
}
+ public virtual long FileModifiedStamp {
+ get { return file_mtime; }
+ set { file_mtime = value; }
+ }
+
+ public virtual DateTime LastSyncedStamp {
+ get { return last_synced; }
+ set { last_synced = value; }
+ }
+
[Exportable (ExportName = "artist")]
public virtual string ArtistName {
get { return artist_name; }
Modified: trunk/banshee/src/Core/Banshee.Core/Banshee.IO.SystemIO/File.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Core/Banshee.IO.SystemIO/File.cs (original)
+++ trunk/banshee/src/Core/Banshee.Core/Banshee.IO.SystemIO/File.cs Fri Sep 12 01:35:43 2008
@@ -63,6 +63,11 @@
return -1;
}
}
+
+ public long GetModifiedTime (SafeUri uri)
+ {
+ return Hyena.DateTimeUtil.FromDateTime (new System.IO.FileInfo (uri.LocalPath).LastWriteTime);
+ }
public System.IO.Stream OpenRead (SafeUri uri)
{
Modified: trunk/banshee/src/Core/Banshee.Core/Banshee.IO/File.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Core/Banshee.IO/File.cs (original)
+++ trunk/banshee/src/Core/Banshee.Core/Banshee.IO/File.cs Fri Sep 12 01:35:43 2008
@@ -43,7 +43,7 @@
{
return Provider.File.Exists (uri);
}
-
+
public static void Move (SafeUri from, SafeUri to)
{
Provider.File.Move (from, to);
@@ -59,6 +59,11 @@
return Provider.File.GetSize (uri);
}
+ public static long GetModifiedTime (SafeUri uri)
+ {
+ return Provider.File.GetModifiedTime (uri);
+ }
+
public static System.IO.Stream OpenRead (SafeUri uri)
{
return Provider.File.OpenRead (uri);
Modified: trunk/banshee/src/Core/Banshee.Core/Banshee.IO/IFile.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Core/Banshee.IO/IFile.cs (original)
+++ trunk/banshee/src/Core/Banshee.Core/Banshee.IO/IFile.cs Fri Sep 12 01:35:43 2008
@@ -39,6 +39,7 @@
void Move (SafeUri from, SafeUri to);
void Copy (SafeUri from, SafeUri to, bool overwrite);
long GetSize (SafeUri uri);
+ long GetModifiedTime (SafeUri uri);
System.IO.Stream OpenRead (SafeUri uri);
System.IO.Stream OpenWrite (SafeUri uri, bool overwrite);
Modified: trunk/banshee/src/Core/Banshee.Core/Banshee.Streaming/StreamTagger.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Core/Banshee.Streaming/StreamTagger.cs (original)
+++ trunk/banshee/src/Core/Banshee.Core/Banshee.Streaming/StreamTagger.cs Fri Sep 12 01:35:43 2008
@@ -112,6 +112,8 @@
track.Uri = new SafeUri (file.Name);
track.MimeType = file.MimeType;
track.FileSize = Banshee.IO.File.GetSize (track.Uri);
+ track.FileModifiedStamp = Banshee.IO.File.GetModifiedTime (track.Uri);
+ track.LastSyncedStamp = DateTime.Now;
track.BitRate = file.Properties.AudioBitrate;
track.Duration = file.Properties.Duration;
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 Fri Sep 12 01:35:43 2008
@@ -189,8 +189,6 @@
TagLib.File file = StreamTagger.ProcessUri (uri);
track = new DatabaseTrackInfo ();
StreamTagger.TrackInfoMerge (track, file);
-
- track.DateAdded = DateTime.Now;
track.PrimarySource = trackPrimarySourceChooser (track);
if (track.PrimarySource is Banshee.Library.LibrarySource) {
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackInfo.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackInfo.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackInfo.cs Fri Sep 12 01:35:43 2008
@@ -346,6 +346,18 @@
get { return base.FileSize; }
set { base.FileSize = value; }
}
+
+ [DatabaseColumn]
+ public override long FileModifiedStamp {
+ get { return base.FileModifiedStamp; }
+ set { base.FileModifiedStamp = value; }
+ }
+
+ [DatabaseColumn]
+ public override DateTime LastSyncedStamp {
+ get { return base.LastSyncedStamp; }
+ set { base.LastSyncedStamp = value; }
+ }
[DatabaseColumn ("Attributes")]
public override TrackMediaAttributes MediaAttributes {
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/ImportManager.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/ImportManager.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/ImportManager.cs Fri Sep 12 01:35:43 2008
@@ -52,40 +52,22 @@
{
this.manager = manager;
}
-
- private int processed_count;
- public int ProcessedCount {
- get { return processed_count; }
- }
-
- private int total_count;
- public int TotalCount {
- get { return total_count; }
- }
-
+
public override void Enqueue (string item)
{
- total_count++;
- manager.UpdateScannerProgress ();
base.Enqueue (item);
+ manager.UpdateScannerProgress ();
}
protected override string ProcessItem (string item)
{
try {
manager.OnImportRequested (item);
- processed_count++;
} catch (Exception e) {
Hyena.Log.Exception (e);
}
return null;
}
-
- public void Reset ()
- {
- processed_count = 0;
- total_count = 0;
- }
}
#endregion
@@ -160,8 +142,6 @@
if (!KeepUserJobHidden) {
user_job.Register ();
}
-
- import_element.Reset ();
}
}
@@ -179,8 +159,6 @@
user_job.CancelRequested -= OnCancelRequested;
user_job.Finish ();
user_job = null;
-
- import_element.Reset ();
}
}
Added: trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/RescanPipeline.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Collection/RescanPipeline.cs Fri Sep 12 01:35:43 2008
@@ -0,0 +1,208 @@
+//
+// RescanPipeline.cs
+//
+// Authors:
+// Gabriel Burt <gburt novell com>
+//
+// Copyright (C) 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.Data;
+
+using Mono.Unix;
+
+using Hyena.Collections;
+using Hyena.Data.Sqlite;
+
+using Banshee.Base;
+using Banshee.Sources;
+using Banshee.Collection.Database;
+using Banshee.Library;
+using Banshee.ServiceStack;
+
+namespace Banshee.Collection
+{
+ // Goals:
+ // 1. Add new files that are on disk but not in the library
+ // 2. Find the updated location of files that were moved
+ // 3. Update metadata for files that were changed since we last scanned/imported
+ // 4. Remove tracks that aren't on disk and weren't found to have moved
+ //
+ // Approach:
+ // 1. For each file in the source's directory, find oraphend db track if any, or add if new
+ // and update if modified; update the LastScannedAt stamp
+ // 2. Remove all db tracks from the database that weren't scanned (LastScannedAt < scan_started)
+ public class RescanPipeline : QueuePipeline<string>
+ {
+ private DateTime scan_started;
+ private PrimarySource psource;
+ private BatchUserJob job;
+ private TrackSyncPipelineElement track_sync;
+
+ public RescanPipeline (LibrarySource psource) : base ()
+ {
+ this.psource = psource;
+ scan_started = DateTime.Now;
+
+ AddElement (new Banshee.IO.DirectoryScannerPipelineElement ());
+ AddElement (track_sync = new TrackSyncPipelineElement (psource, scan_started));
+ Finished += OnFinished;
+
+ BuildJob ();
+ Enqueue (psource.BaseDirectory);
+ }
+
+ private void BuildJob ()
+ {
+ job = new BatchUserJob (Catalog.GetString ("Rescanning {0} of {1}"), "system-search", "gtk-find");
+ job.CanCancel = true;
+ job.CancelRequested += delegate { cancelled = true; Cancel (); };
+ track_sync.ProcessedItem += delegate {
+ job.Total = track_sync.TotalCount;
+ job.Completed = track_sync.ProcessedCount;
+ job.Status = track_sync.Status;
+ };
+ job.Register ();
+ }
+
+ private bool cancelled = false;
+ private void OnFinished (object o, EventArgs args)
+ {
+ job.Finish ();
+
+ if (cancelled) {
+ return;
+ }
+
+ //Hyena.Log.DebugFormat ("Have {0} items before delete", ServiceManager.DbConnection.Query<int>("select count(*) from coretracks where primarysourceid=?", psource.DbId));
+
+ // Delete tracks that are under the BaseDirectory (UriType = relative) and that weren't rescanned just now
+ ServiceManager.DbConnection.Execute (@"BEGIN;
+ DELETE FROM CorePlaylistEntries WHERE TrackID IN
+ (SELECT TrackID FROM CoreTracks WHERE PrimarySourceID = ? AND UriType = ? AND LastSyncedStamp IS NOT NULL AND LastSyncedStamp < ?);
+ DELETE FROM CoreSmartPlaylistEntries WHERE TrackID IN
+ (SELECT TrackID FROM CoreTracks WHERE PrimarySourceID = ? AND UriType = ? AND LastSyncedStamp IS NOT NULL AND LastSyncedStamp < ?);
+ DELETE FROM CoreTracks WHERE PrimarySourceID = ? AND UriType = ? AND LastSyncedStamp IS NOT NULL AND LastSyncedStamp < ?;
+ COMMIT",
+ psource.DbId, (int)TrackUriType.RelativePath, scan_started,
+ psource.DbId, (int)TrackUriType.RelativePath, scan_started,
+ psource.DbId, (int)TrackUriType.RelativePath, scan_started
+ );
+
+ // TODO prune artists/albums
+ psource.Reload ();
+ psource.NotifyTracksChanged ();
+ //Hyena.Log.DebugFormat ("Have {0} items after delete", ServiceManager.DbConnection.Query<int>("select count(*) from coretracks where primarysourceid=?", psource.DbId));
+ }
+ }
+
+ public class TrackSyncPipelineElement : QueuePipelineElement<string>
+ {
+ private PrimarySource psource;
+ private DateTime scan_started;
+ private HyenaSqliteCommand fetch_command, fetch_similar_command;
+
+ private string status;
+ public string Status {
+ get { return status; }
+ }
+
+ public TrackSyncPipelineElement (PrimarySource psource, DateTime scan_started) : base ()
+ {
+ this.psource = psource;
+ this.scan_started = scan_started;
+
+ fetch_command = DatabaseTrackInfo.Provider.CreateFetchCommand (
+ "CoreTracks.PrimarySourceID = ? AND (CoreTracks.Uri = ? OR CoreTracks.Uri = ?) LIMIT 1");
+
+ fetch_similar_command = DatabaseTrackInfo.Provider.CreateFetchCommand (
+ "CoreTracks.PrimarySourceID = ? AND CoreTracks.LastSyncedStamp < ? AND CoreTracks.MetadataHash = ?");
+ }
+
+ protected override string ProcessItem (string file_path)
+ {
+ if (!DatabaseImportManager.IsWhiteListedFile (file_path)) {
+ return null;
+ }
+
+ //Hyena.Log.DebugFormat ("Rescanning item {0}", file_path);
+ try {
+ string relative_path = Banshee.Base.Paths.MakePathRelative (file_path, psource.BaseDirectory);
+
+ IDataReader reader = ServiceManager.DbConnection.Query (fetch_command, psource.DbId, file_path, relative_path);
+ if (reader.Read () ) {
+ //Hyena.Log.DebugFormat ("Found it in the db!");
+ DatabaseTrackInfo track = DatabaseTrackInfo.Provider.Load (reader);
+
+ MergeIfModified (track);
+
+ // Either way, update the LastSyncStamp
+ track.LastSyncedStamp = DateTime.Now;
+ track.Save (false);
+ status = String.Format ("{0} - {1}", track.DisplayArtistName, track.DisplayTrackTitle);
+ } else {
+ // This URI is not in the database - try to find it based on MetadataHash in case it was simply moved
+ DatabaseTrackInfo track = new DatabaseTrackInfo ();
+ TagLib.File file = Banshee.Streaming.StreamTagger.ProcessUri (new SafeUri (file_path));
+ Banshee.Streaming.StreamTagger.TrackInfoMerge (track, file);
+
+ IDataReader similar_reader = ServiceManager.DbConnection.Query (fetch_similar_command, psource.DbId, scan_started, track.MetadataHash);
+ DatabaseTrackInfo similar_track = null;
+ while (similar_reader.Read ()) {
+ similar_track = DatabaseTrackInfo.Provider.Load (similar_reader);
+ if (!Banshee.IO.File.Exists (similar_track.Uri)) {
+ //Hyena.Log.DebugFormat ("Apparently {0} was moved to {1}", similar_track.Uri, file_path);
+ similar_track.Uri = new SafeUri (file_path);
+ MergeIfModified (similar_track);
+ similar_track.LastSyncedStamp = DateTime.Now;
+ similar_track.Save (false);
+ status = String.Format ("{0} - {1}", similar_track.DisplayArtistName, similar_track.DisplayTrackTitle);
+ break;
+ }
+ similar_track = null;
+ }
+
+ // If we still couldn't find it, try to import it
+ if (similar_track == null) {
+ //Hyena.Log.DebugFormat ("Couldn't find it, so queueing to import it");
+ ServiceManager.Get<Banshee.Library.LibraryImportManager> ().Enqueue (file_path);
+ }
+ }
+ } catch (Exception e) {
+ Hyena.Log.Exception (e);
+ }
+ return null;
+ }
+
+ private void MergeIfModified (TrackInfo track)
+ {
+ long mtime = Banshee.IO.File.GetModifiedTime (track.Uri);
+
+ // If the file was modified since we last scanned, parse the file's metadata
+ if (mtime > track.FileModifiedStamp) {
+ TagLib.File file = Banshee.Streaming.StreamTagger.ProcessUri (track.Uri);
+ Banshee.Streaming.StreamTagger.TrackInfoMerge (track, file, false);
+ }
+ }
+ }
+}
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Database/BansheeDbFormatMigrator.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Database/BansheeDbFormatMigrator.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Database/BansheeDbFormatMigrator.cs Fri Sep 12 01:35:43 2008
@@ -52,7 +52,7 @@
// NOTE: Whenever there is a change in ANY of the database schema,
// this version MUST be incremented and a migration method
// MUST be supplied to match the new version number
- protected const int CURRENT_VERSION = 21;
+ protected const int CURRENT_VERSION = 22;
protected const int CURRENT_METADATA_VERSION = 4;
#region Migration Driver
@@ -537,6 +537,19 @@
#endregion
+#region Version 22
+
+ [DatabaseVersion (22)]
+ private bool Migrate_22 ()
+ {
+ Execute ("ALTER TABLE CoreTracks ADD COLUMN LastSyncedStamp INTEGER DEFAULT NULL");
+ Execute ("ALTER TABLE CoreTracks ADD COLUMN FileModifiedStamp INTEGER DEFAULT NULL");
+ Execute ("UPDATE CoreTracks SET LastSyncedStamp = DateAddedStamp;");
+ return true;
+ }
+
+#endregion
+
#pragma warning restore 0169
#region Fresh database setup
@@ -623,7 +636,9 @@
DateAddedStamp INTEGER,
DateUpdatedStamp INTEGER,
MetadataHash TEXT,
- BPM INTEGER
+ BPM INTEGER,
+ LastSyncedStamp INTEGER,
+ FileModifiedStamp INTEGER
)
", (int)TrackMediaAttributes.Default, (int)StreamPlaybackError.None));
Execute("CREATE INDEX CoreTracksPrimarySourceIndex ON CoreTracks(ArtistID, AlbumID, PrimarySourceID, Disc, TrackNumber, Uri)");
@@ -797,7 +812,7 @@
NULL,
DateAddedStamp,
DateAddedStamp,
- NULL, NULL
+ NULL, NULL, DateAddedStamp, NULL
FROM Tracks
", (int)TrackMediaAttributes.Default, (int)StreamPlaybackError.None));
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Services.csproj
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Services.csproj (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Services.csproj Fri Sep 12 01:35:43 2008
@@ -233,6 +233,7 @@
<Compile Include="Banshee.Collection.Indexer\CollectionIndexer.cs" />
<Compile Include="Banshee.Configuration\DefaultApplicationHelper.cs" />
<Compile Include="Banshee.Collection.Indexer\IIndexerClient.cs" />
+ <Compile Include="Banshee.Collection\RescanPipeline.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Banshee.Services.addin.xml" />
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 Fri Sep 12 01:35:43 2008
@@ -39,6 +39,7 @@
Banshee.Collection/MemoryTrackListModel.cs \
Banshee.Collection/ModelHelper.cs \
Banshee.Collection/MoveOnInfoSaveJob.cs \
+ Banshee.Collection/RescanPipeline.cs \
Banshee.Collection/SelectAllSelection.cs \
Banshee.Collection/TrackListModel.cs \
Banshee.Configuration/DatabaseConfigurationClient.cs \
Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/GlobalActions.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/GlobalActions.cs (original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui/GlobalActions.cs Fri Sep 12 01:35:43 2008
@@ -57,6 +57,12 @@
Catalog.GetString ("Import Playlist..."), null,
Catalog.GetString ("Import a playlist"), OnImportPlaylist),
+ new ActionEntry ("RescanAction", null,
+ Catalog.GetString ("Rescan Music Library"), null,
+ Catalog.GetString ("Rescan the Music Library folder"), delegate {
+ new Banshee.Collection.RescanPipeline (ServiceManager.SourceManager.MusicLibrary);
+ }),
+
new ActionEntry ("OpenLocationAction", null,
Catalog.GetString ("Open _Location..."), "<control>L",
Catalog.GetString ("Open a remote location for playback"), OnOpenLocation),
Modified: trunk/banshee/src/Core/Banshee.ThickClient/Resources/core-ui-actions-layout.xml
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Resources/core-ui-actions-layout.xml (original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Resources/core-ui-actions-layout.xml Fri Sep 12 01:35:43 2008
@@ -84,6 +84,7 @@
</menu>
<menu name="ToolsMenu" action="ToolsMenuAction">
+ <menuitem name="Rescan" action="RescanAction"/>
</menu>
<menu name="HelpMenu" action="HelpMenuAction">
Modified: trunk/banshee/src/Libraries/Hyena/Hyena.Collections/QueuePipeline.cs
==============================================================================
--- trunk/banshee/src/Libraries/Hyena/Hyena.Collections/QueuePipeline.cs (original)
+++ trunk/banshee/src/Libraries/Hyena/Hyena.Collections/QueuePipeline.cs Fri Sep 12 01:35:43 2008
@@ -93,7 +93,7 @@
lock (sync) {
QueuePipelineElement<T> element = FirstElement;
while (element != null) {
- any_processing |= element.Processing;
+ any_processing |= element.Processing || element.ProcessedCount < element.TotalCount;
if (any_processing) {
break;
}
Modified: trunk/banshee/src/Libraries/Hyena/Hyena.Collections/QueuePipelineElement.cs
==============================================================================
--- trunk/banshee/src/Libraries/Hyena/Hyena.Collections/QueuePipelineElement.cs (original)
+++ trunk/banshee/src/Libraries/Hyena/Hyena.Collections/QueuePipelineElement.cs Fri Sep 12 01:35:43 2008
@@ -41,14 +41,25 @@
#pragma warning disable 0067
// FIXME: This is to mute gmcs: https://bugzilla.novell.com/show_bug.cgi?id=360455
public event EventHandler Finished;
+ public event EventHandler ProcessedItem;
#pragma warning restore 0067
-
+
private Queue<T> queue = new Queue<T> ();
private object monitor = new object ();
private AutoResetEvent thread_wait;
private bool processing = false;
private bool threaded = true;
private bool canceled = false;
+
+ private int processed_count;
+ public int ProcessedCount {
+ get { return processed_count; }
+ }
+
+ private int total_count;
+ public int TotalCount {
+ get { return total_count; }
+ }
protected abstract T ProcessItem (T item);
@@ -57,17 +68,32 @@
lock (this) {
canceled = false;
}
+
+ lock (queue) {
+ total_count = 0;
+ processed_count = 0;
+ }
EventHandler handler = Finished;
if (handler != null) {
handler (this, EventArgs.Empty);
}
}
+
+ protected void OnProcessedItem ()
+ {
+ EventHandler handler = ProcessedItem;
+ if (handler != null) {
+ handler (this, EventArgs.Empty);
+ }
+ }
protected virtual void OnCanceled ()
{
lock (queue) {
queue.Clear ();
+ total_count = 0;
+ processed_count = 0;
}
}
@@ -76,6 +102,7 @@
lock (this) {
lock (queue) {
queue.Enqueue (item);
+ total_count++;
}
if (!threaded) {
@@ -120,15 +147,16 @@
T item = null;
lock (queue) {
item = queue.Dequeue ();
+ processed_count++;
}
EnqueueDownstream (ProcessItem (item));
+ OnProcessedItem ();
}
} catch (ElementProcessCanceledException) {
OnCanceled ();
}
-
-
+
lock (this) {
processing = false;
}
Modified: trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelProvider.cs
==============================================================================
--- trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelProvider.cs (original)
+++ trunk/banshee/src/Libraries/Hyena/Hyena.Data.Sqlite/SqliteModelProvider.cs Fri Sep 12 01:35:43 2008
@@ -383,13 +383,18 @@
public IEnumerable<T> FetchAllMatching (string condition, params object [] vals)
{
- HyenaSqliteCommand fetch_matching_command = new HyenaSqliteCommand (String.Format ("{0} AND {1}", SelectCommand.Text, condition));
+ HyenaSqliteCommand fetch_matching_command = CreateFetchCommand (condition);
using (IDataReader reader = connection.Query (fetch_matching_command, vals)) {
while (reader.Read ()) {
yield return Load (reader);
}
}
}
+
+ public HyenaSqliteCommand CreateFetchCommand (string condition)
+ {
+ return new HyenaSqliteCommand (String.Format ("{0} AND {1}", SelectCommand.Text, condition));
+ }
public IEnumerable<T> FetchRange (int offset, int limit)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]