banshee r4151 - in trunk/banshee: . build/m4/shamrock data src/Clients src/Clients/Halie/Halie src/Core src/Core/Banshee.Core src/Core/Banshee.Core/Banshee.Base src/Core/Banshee.Core/Banshee.IO src/Core/Banshee.Services src/Core/Banshee.Services/Banshee.Base src/Core/Banshee.Services/Banshee.Collection src/Core/Banshee.Services/Banshee.Collection.Database src/Core/Banshee.Services/Banshee.Library src/Core/Banshee.Services/Banshee.ServiceStack src/Core/Banshee.ThickClient/Banshee.Gui.Widgets src/Core/Banshee.ThickClient/Banshee.Library.Gui src/Dap src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage src/Extensions/Banshee.FileSystemQueue/Banshee.FileSystemQueue src/Extensions/Banshee.Podcasting/Banshee.Podcasting src/Libraries src/Libraries/Hyena src/Libraries/Hyena/Hyena.Collections src/Libraries/Hyena/Hyena.Collections/Tests src/Libraries/Hyena/Hyena.CommandLine
- From: abock svn gnome org
- To: svn-commits-list gnome org
- Subject: banshee r4151 - in trunk/banshee: . build/m4/shamrock data src/Clients src/Clients/Halie/Halie src/Core src/Core/Banshee.Core src/Core/Banshee.Core/Banshee.Base src/Core/Banshee.Core/Banshee.IO src/Core/Banshee.Services src/Core/Banshee.Services/Banshee.Base src/Core/Banshee.Services/Banshee.Collection src/Core/Banshee.Services/Banshee.Collection.Database src/Core/Banshee.Services/Banshee.Library src/Core/Banshee.Services/Banshee.ServiceStack src/Core/Banshee.ThickClient/Banshee.Gui.Widgets src/Core/Banshee.ThickClient/Banshee.Library.Gui src/Dap src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage src/Extensions/Banshee.FileSystemQueue/Banshee.FileSystemQueue src/Extensions/Banshee.Podcasting/Banshee.Podcasting src/Libraries src/Libraries/Hyena src/Libraries/Hyena/Hyena.Collections src/Libraries/Hyena/Hyena.Collections/Tests src/Libraries/Hyena/Hyena.CommandLine
- Date: Mon, 16 Jun 2008 20:32:09 +0000 (UTC)
Author: abock
Date: Mon Jun 16 20:32:09 2008
New Revision: 4151
URL: http://svn.gnome.org/viewvc/banshee?rev=4151&view=rev
Log:
2008-06-16 Aaron Bockover <abock gnome org>
* src/Extensions/Banshee.FileSystemQueue/Banshee.FileSystemQueue/FileSystemQueueSource.cs:
Lots of bug fixes with FSQ behavior around starting a new instance with
items in the queue, queueing items remotely, and playing back from the
queue automaticaly when --play-enqueued is passed
* src/Core/Banshee.Services/Banshee.Collection/ImportManager.cs: Major
update to use the new QueuePipeline and DirectoryScannerPipelineElement
for improved parallelism, fixed threading issues, and more readable and
reliable code
* src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseImportManager.cs:
Added an ImportResult event; small API cleanup
* src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseImportResultHandler.cs:
New delegate and args class that the DatabaseImportManager uses for the
new result event
* src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseTrackInfo.cs:
Remove unnecessary casting
* src/Libraries/Hyena/Hyena.Collections/QueuePipeline.cs: Container class
for the async queue pipeline; links elements together
* src/Libraries/Hyena/Hyena.Collections/QueuePipelineElement.cs: Base
element class for the pipeline; items pushed into the element's queue are
processed async and then pushed to the downstream element in the pipeline,
which may run in its own thread; this allows for good parallelism in an
easy, safe way (i.e. walk a directory tree while processing results from
earlier in the walk at the same time)
* src/Libraries/Hyena/Hyena.Collections/WriteLineElement.cs: A simple
sync element that dumps results to stdout
* src/Libraries/Hyena/Hyena.Collections/Tests/QueuePipelineTests.cs:
Some unit tests for QP/QPE
* src/Core/Banshee.Services/Banshee.Library/HomeDirectoryImportSource.cs:
* src/Core/Banshee.Services/Banshee.Library/LibraryImportManager.cs:
* src/Core/Banshee.ThickClient/Banshee.Library.Gui/FileImportSource.cs:
* src/Core/Banshee.ThickClient/Banshee.Library.Gui/FolderImportSource.cs:
* src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/MassStorageSource.cs:
* src/Extensions/Banshee.Podcasting/Banshee.Podcasting/PodcastImportManager.cs:
Updated to reflect small API changes in base ImportManager class
* src/Core/Banshee.Services/Banshee.Base/ThreadAssist.cs:
* src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/ConnectedMessageBar.cs:
* src/Core/Banshee.Services/Banshee.ServiceStack/Application.cs: Remove
EventHandler override for doing Invoke/ProxyToMain; just use InvokeHandler
* src/Core/Banshee.Core/Banshee.IO/DirectoryScannerPipelineElement.cs:
Moved the directory scanning code from ImportManager to a nice
QueuePipelineElement so it can be reused inside threaded queue pipelines
* src/Core/Banshee.Core/Banshee.Base/ApplicationContext.cs:
* src/Libraries/Hyena/Hyena.CommandLine/CommandLineParser.cs: Remove the
notion of --enqueue and just assume anything that does not start with --
is a 'file'
* src/Clients/Halie/Halie/Client.cs: handle files after all commands are
handled, so the remote process can get an idea of what is coming
* src/Clients/banshee-1.in: Added --redirect-log argument that dumps
stdin/error to ~/.config/banshee-1/log; sort of a hack job
* data/banshee-1.desktop.in.in: Pass --redirect-log and remove --enqueue
* build/m4/shamrock/nunit.m4: Fix nunit detection
Added:
trunk/banshee/src/Core/Banshee.Core/Banshee.IO/DirectoryScannerPipelineElement.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseImportResultHandler.cs
trunk/banshee/src/Libraries/Hyena/Hyena.Collections/QueuePipeline.cs
trunk/banshee/src/Libraries/Hyena/Hyena.Collections/QueuePipelineElement.cs
trunk/banshee/src/Libraries/Hyena/Hyena.Collections/Tests/QueuePipelineTests.cs
trunk/banshee/src/Libraries/Hyena/Hyena.Collections/WriteLineElement.cs
Modified:
trunk/banshee/ChangeLog
trunk/banshee/build/m4/shamrock/nunit.m4
trunk/banshee/data/banshee-1.desktop.in.in
trunk/banshee/src/Clients/Halie/Halie/Client.cs
trunk/banshee/src/Clients/banshee-1.in
trunk/banshee/src/Core/Banshee.Core/Banshee.Base/ApplicationContext.cs
trunk/banshee/src/Core/Banshee.Core/Banshee.Core.mdp
trunk/banshee/src/Core/Banshee.Core/Makefile.am
trunk/banshee/src/Core/Banshee.Services/Banshee.Base/ThreadAssist.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.Library/HomeDirectoryImportSource.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.Library/LibraryImportManager.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.ServiceStack/Application.cs
trunk/banshee/src/Core/Banshee.Services/Banshee.Services.mdp
trunk/banshee/src/Core/Banshee.Services/Makefile.am
trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/ConnectedMessageBar.cs
trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Library.Gui/FileImportSource.cs
trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Library.Gui/FolderImportSource.cs
trunk/banshee/src/Core/Core.mds
trunk/banshee/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/MassStorageSource.cs
trunk/banshee/src/Dap/Dap.mds
trunk/banshee/src/Extensions/Banshee.FileSystemQueue/Banshee.FileSystemQueue/FileSystemQueueSource.cs
trunk/banshee/src/Extensions/Banshee.Podcasting/Banshee.Podcasting/PodcastImportManager.cs
trunk/banshee/src/Libraries/Hyena/Hyena.CommandLine/CommandLineParser.cs
trunk/banshee/src/Libraries/Hyena/Hyena.mdp
trunk/banshee/src/Libraries/Hyena/Makefile.am
trunk/banshee/src/Libraries/Libraries.mds
Modified: trunk/banshee/build/m4/shamrock/nunit.m4
==============================================================================
--- trunk/banshee/build/m4/shamrock/nunit.m4 (original)
+++ trunk/banshee/build/m4/shamrock/nunit.m4 Mon Jun 16 20:32:09 2008
@@ -2,7 +2,7 @@
[
NUNIT_REQUIRED=2.4.7
- PKG_CHECK_MODULES(NUNIT, nunit >= NUNIT_REQUIRED,
+ PKG_CHECK_MODULES(NUNIT, nunit >= $NUNIT_REQUIRED,
do_tests="yes", do_tests="no")
AC_SUBST(NUNIT_LIBS)
Modified: trunk/banshee/data/banshee-1.desktop.in.in
==============================================================================
--- trunk/banshee/data/banshee-1.desktop.in.in (original)
+++ trunk/banshee/data/banshee-1.desktop.in.in Mon Jun 16 20:32:09 2008
@@ -4,7 +4,7 @@
_Name=Banshee Media Player
_GenericName=Media Player
Comment=Play and organize your media collection
-Exec=banshee-1 --play-enqueued --enqueue %U
+Exec=banshee-1 --redirect-log --play-enqueued %U
Icon=media-player-banshee
StartupNotify=true
Terminal=false
Modified: trunk/banshee/src/Clients/Halie/Halie/Client.cs
==============================================================================
--- trunk/banshee/src/Clients/Halie/Halie/Client.cs (original)
+++ trunk/banshee/src/Clients/Halie/Halie/Client.cs Mon Jun 16 20:32:09 2008
@@ -72,9 +72,9 @@
command = DBusServiceManager.FindInstance<DBusCommandService> ("/DBusCommandService");
hide_field = ApplicationContext.CommandLine.Contains ("hide-field");
- HandleFiles ();
bool present = HandlePlayerCommands ();
HandleWindowCommands (present);
+ HandleFiles ();
}
private static void HandleWindowCommands (bool present)
Modified: trunk/banshee/src/Clients/banshee-1.in
==============================================================================
--- trunk/banshee/src/Clients/banshee-1.in (original)
+++ trunk/banshee/src/Clients/banshee-1.in Mon Jun 16 20:32:09 2008
@@ -25,6 +25,10 @@
case "x--profile=" in ("x${arg:0:10}")
BANSHEE_PROFILE=$arg
esac
+
+ case "x--redirect-log" in ("x$arg")
+ BANSHEE_REDIRECT_LOG="$HOME/.config/banshee-1/log"
+ esac
done
if [ -n "$BANSHEE_DEBUG" -o -n "$BANSHEE_TRACE" -o -n "$BANSHEE_PROFILE" ]; then
@@ -33,5 +37,12 @@
fi
# Finally - environment is set up, time to run our beloved
-exec -a banshee-1 mono $MONO_OPTIONS $MONO_EXE "$@"
+exec_args="-a banshee-1 mono $MONO_OPTIONS $MONO_EXE $@"
+
+if [ -z "$BANSHEE_REDIRECT_LOG" ]; then
+ exec $exec_args
+else
+ exec $exec_args &> $BANSHEE_REDIRECT_LOG
+fi
+
Modified: trunk/banshee/src/Core/Banshee.Core/Banshee.Base/ApplicationContext.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Core/Banshee.Base/ApplicationContext.cs (original)
+++ trunk/banshee/src/Core/Banshee.Core/Banshee.Base/ApplicationContext.cs Mon Jun 16 20:32:09 2008
@@ -33,6 +33,8 @@
namespace Banshee.Base
{
+ public delegate void InvokeHandler ();
+
public static class ApplicationContext
{
static ApplicationContext ()
@@ -40,7 +42,7 @@
Log.Debugging = Debugging;
}
- private static CommandLineParser command_line = new CommandLineParser ("enqueue");
+ private static CommandLineParser command_line = new CommandLineParser ();
public static CommandLineParser CommandLine {
set { command_line = value; }
get { return command_line; }
Modified: trunk/banshee/src/Core/Banshee.Core/Banshee.Core.mdp
==============================================================================
--- trunk/banshee/src/Core/Banshee.Core/Banshee.Core.mdp (original)
+++ trunk/banshee/src/Core/Banshee.Core/Banshee.Core.mdp Mon Jun 16 20:32:09 2008
@@ -71,6 +71,7 @@
<File name="Banshee.Base/Tests/TaglibReadWriteTests.cs" subtype="Code" buildaction="Compile" />
<File name="Banshee.Kernel/DelegateJob.cs" subtype="Code" buildaction="Compile" />
<File name="Banshee.Collection/CacheableItem.cs" subtype="Code" buildaction="Compile" />
+ <File name="Banshee.IO/DirectoryScannerPipelineElement.cs" subtype="Code" buildaction="Compile" />
</Contents>
<References>
<ProjectReference type="Project" localcopy="False" refto="Hyena" />
Added: trunk/banshee/src/Core/Banshee.Core/Banshee.IO/DirectoryScannerPipelineElement.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Core/Banshee.Core/Banshee.IO/DirectoryScannerPipelineElement.cs Mon Jun 16 20:32:09 2008
@@ -0,0 +1,90 @@
+//
+// DirectoryScannerPipelineElement.cs
+//
+// Author:
+// Aaron Bockover <abockover 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.IO;
+
+using Hyena.Collections;
+
+using Banshee.Base;
+
+namespace Banshee.IO
+{
+ public class DirectoryScannerPipelineElement : QueuePipelineElement<string>
+ {
+ protected override string ProcessItem (string item)
+ {
+ ScanForFiles (item);
+ return null;
+ }
+
+ private void ScanForFiles (string source)
+ {
+ CheckForCanceled ();
+
+ bool is_regular_file = false;
+ bool is_directory = false;
+
+ SafeUri source_uri = new SafeUri (source);
+
+ try {
+ is_regular_file = Banshee.IO.File.Exists (source_uri);
+ is_directory = !is_regular_file && Banshee.IO.Directory.Exists (source);
+ } catch {
+ return;
+ }
+
+ if (is_regular_file) {
+ try {
+ if (!Path.GetFileName (source).StartsWith (".")) {
+ EnqueueDownstream (source);
+ }
+ } catch (System.ArgumentException) {
+ // If there are illegal characters in path
+ }
+ } else if (is_directory) {
+ try {
+ if (!Path.GetFileName (Path.GetDirectoryName (source)).StartsWith (".")) {
+ try {
+ foreach (string file in Banshee.IO.Directory.GetFiles (source)) {
+ ScanForFiles (file);
+ }
+
+ foreach (string directory in Banshee.IO.Directory.GetDirectories (source)) {
+ ScanForFiles (directory);
+ }
+ } catch {
+ }
+ }
+ } catch (System.ArgumentException) {
+ // If there are illegal characters in path
+ }
+ }
+ }
+ }
+}
Modified: trunk/banshee/src/Core/Banshee.Core/Makefile.am
==============================================================================
--- trunk/banshee/src/Core/Banshee.Core/Makefile.am (original)
+++ trunk/banshee/src/Core/Banshee.Core/Makefile.am Mon Jun 16 20:32:09 2008
@@ -42,6 +42,7 @@
Banshee.IO.SystemIO/Provider.cs \
Banshee.IO/DemuxVfs.cs \
Banshee.IO/Directory.cs \
+ Banshee.IO/DirectoryScannerPipelineElement.cs \
Banshee.IO/File.cs \
Banshee.IO/IDemuxVfs.cs \
Banshee.IO/IDirectory.cs \
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Base/ThreadAssist.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Base/ThreadAssist.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Base/ThreadAssist.cs Mon Jun 16 20:32:09 2008
@@ -50,12 +50,12 @@
}
}
- public static void ProxyToMain (EventHandler handler)
+ public static void ProxyToMain (InvokeHandler handler)
{
if (!InMainThread) {
Banshee.ServiceStack.Application.Invoke (handler);
} else {
- handler (null, EventArgs.Empty);
+ handler ();
}
}
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 Mon Jun 16 20:32:09 2008
@@ -92,16 +92,19 @@
private TrackPrimarySourceChooser trackPrimarySourceChooser;
private Dictionary<int, int> counts;
private ErrorSource error_source;
- protected int [] primary_source_ids;
- protected string base_directory;
- protected bool force_copy;
+ private int [] primary_source_ids;
+ private string base_directory;
+ private bool force_copy;
+
+ public event DatabaseImportResultHandler ImportResult;
public DatabaseImportManager (PrimarySource psource) :
this (psource.ErrorSource, delegate { return psource; }, new int [] {psource.DbId}, psource.BaseDirectory)
{
}
- public DatabaseImportManager (ErrorSource error_source, TrackPrimarySourceChooser chooser, int [] primarySourceIds, string baseDirectory) : this (chooser)
+ public DatabaseImportManager (ErrorSource error_source, TrackPrimarySourceChooser chooser,
+ int [] primarySourceIds, string baseDirectory) : this (chooser)
{
this.error_source = error_source;
primary_source_ids = primarySourceIds;
@@ -120,28 +123,46 @@
protected virtual int [] PrimarySourceIds {
get { return primary_source_ids; }
+ set { primary_source_ids = value; }
}
protected virtual string BaseDirectory {
get { return base_directory; }
+ set { base_directory = value; }
+ }
+
+ protected virtual bool ForceCopy {
+ get { return force_copy; }
+ set { force_copy = value; }
}
protected override void OnImportRequested (string path)
{
if (!IsWhiteListedFile (path)) {
- IncrementProcessedCount (null);
+ UpdateProgress (null);
return;
}
try {
DatabaseTrackInfo track = ImportTrack (path);
if (track != null && track.TrackId > 0) {
- IncrementProcessedCount (String.Format ("{0} - {1}",
+ UpdateProgress (String.Format ("{0} - {1}",
track.DisplayArtistName, track.DisplayTrackTitle));
}
+
+ OnImportResult (track, path, null);
} catch (Exception e) {
LogError (path, e);
- IncrementProcessedCount (null);
+ UpdateProgress (null);
+ OnImportResult (null, path, e);
+ }
+ }
+
+ protected virtual void OnImportResult (DatabaseTrackInfo track, string path, Exception error)
+ {
+ DatabaseImportResultHandler handler = ImportResult;
+ if (handler != null) {
+ handler (this, new DatabaseImportResultArgs (track, path, error));
}
}
@@ -157,7 +178,7 @@
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.
- IncrementProcessedCount (null);
+ UpdateProgress (null);
return null;
}
Added: trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseImportResultHandler.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/DatabaseImportResultHandler.cs Mon Jun 16 20:32:09 2008
@@ -0,0 +1,60 @@
+//
+// DatabaseImportResultHandler.cs
+//
+// Author:
+// Aaron Bockover <abockover 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;
+
+namespace Banshee.Collection.Database
+{
+ public delegate void DatabaseImportResultHandler (object o, DatabaseImportResultArgs args);
+
+ public sealed class DatabaseImportResultArgs : EventArgs
+ {
+ private DatabaseTrackInfo track;
+ private string path;
+ private Exception error;
+
+ public DatabaseImportResultArgs (DatabaseTrackInfo track, string path, Exception error)
+ {
+ this.track = track;
+ this.path = path;
+ this.error = error;
+ }
+
+ public string Path {
+ get { return path; }
+ }
+
+ public DatabaseTrackInfo Track {
+ get { return track; }
+ }
+
+ public Exception Error {
+ get { return error; }
+ }
+ }
+}
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 Mon Jun 16 20:32:09 2008
@@ -99,11 +99,11 @@
public override bool TrackEqual (TrackInfo track)
{
- if (!(track is DatabaseTrackInfo)) {
+ DatabaseTrackInfo db_track = track as DatabaseTrackInfo;
+ if (db_track == null) {
return base.TrackEqual (track);
}
- DatabaseTrackInfo db_track = (DatabaseTrackInfo)track;
return db_track.TrackId == TrackId && db_track.CacheModelId == CacheModelId &&
db_track.CacheEntryId == CacheEntryId;
}
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 Mon Jun 16 20:32:09 2008
@@ -27,43 +27,113 @@
//
using System;
-using System.IO;
-using System.Collections.Generic;
-using System.Threading;
+using System.Globalization;
using Mono.Unix;
using Hyena;
+using Hyena.Collections;
+
using Banshee.IO;
using Banshee.Base;
using Banshee.ServiceStack;
namespace Banshee.Collection
{
- public class ImportManager
+ public class ImportManager : QueuePipeline<string>
{
- private class ImportCanceledException : ApplicationException
+
+#region Importing Pipeline Element
+
+ private class ImportElement : QueuePipelineElement<string>
{
+ private ImportManager manager;
+
+ public ImportElement (ImportManager manager)
+ {
+ 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);
+ }
+
+ protected override string ProcessItem (string item)
+ {
+ manager.OnImportRequested (item);
+ processed_count++;
+ return null;
+ }
+
+ protected override void OnFinished ()
+ {
+ base.OnFinished ();
+ manager.DestroyUserJob ();
+ manager.OnImportFinished ();
+ }
+
+ public void Reset ()
+ {
+ processed_count = 0;
+ total_count = 0;
+ }
}
- private readonly object user_job_mutex = new object ();
- private UserJob user_job;
+#endregion
- private Queue<string> path_queue = new Queue<string> ();
- private bool processing_queue = false;
+ private static NumberFormatInfo number_format = new NumberFormatInfo ();
- private int total_count;
- private int processed_count;
- private int scan_ref_count = 0;
+ private DirectoryScannerPipelineElement scanner_element;
+ private ImportElement import_element;
+
+ private readonly object user_job_mutex = new object ();
+ private UserJob user_job;
+ private uint timer_id;
public event ImportEventHandler ImportRequested;
public event EventHandler ImportFinished;
public ImportManager ()
{
+ AddElement (scanner_element = new DirectoryScannerPipelineElement ());
+ AddElement (import_element = new ImportElement (this));
+ }
+
+#region Public API
+
+ public virtual void Enqueue (UriList uris)
+ {
+ CreateUserJob ();
+
+ foreach (string path in uris.LocalPaths) {
+ base.Enqueue (path);
+ }
+ }
+
+ public override void Enqueue (string source)
+ {
+ Enqueue (new UriList (source));
+ }
+
+ public void Enqueue (string [] paths)
+ {
+ Enqueue (new UriList (paths));
}
public bool IsImportInProgress {
- get { return processing_queue; }
+ get { return import_element.Processing; }
}
private bool keep_user_job_hidden = false;
@@ -72,6 +142,10 @@
set { keep_user_job_hidden = value; }
}
+#endregion
+
+#region User Job / Interaction
+
private void CreateUserJob ()
{
lock (user_job_mutex) {
@@ -79,17 +153,19 @@
return;
}
+ timer_id = Log.DebugTimerStart ();
+
user_job = new UserJob (Title, Catalog.GetString ("Scanning for media"));
user_job.IconNames = new string [] { "system-search", "gtk-find" };
user_job.CancelMessage = CancelMessage;
user_job.CanCancel = true;
+ user_job.CancelRequested += OnCancelRequested;
if (!KeepUserJobHidden) {
user_job.Register ();
}
- total_count = 0;
- processed_count = 0;
+ import_element.Reset ();
}
}
@@ -100,186 +176,58 @@
return;
}
+ Log.DebugTimerPrint (timer_id, Title + " duration: {0}");
+
+ user_job.CancelRequested -= OnCancelRequested;
user_job.Finish ();
user_job = null;
- total_count = 0;
- processed_count = 0;
- scan_ref_count = 0;
+ import_element.Reset ();
}
}
- protected void IncrementProcessedCount (string message)
+ private void OnCancelRequested (object o, EventArgs args)
+ {
+ scanner_element.Cancel ();
+ }
+
+ protected void UpdateProgress (string message)
{
CreateUserJob ();
- processed_count++;
- double new_progress = (double)processed_count / (double)total_count;
+ double new_progress = (double)import_element.ProcessedCount / (double)import_element.TotalCount;
double old_progress = user_job.Progress;
if (new_progress >= 0.0 && new_progress <= 1.0 && Math.Abs (new_progress - old_progress) > 0.001) {
- string disp_progress = String.Format (ProgressMessage, processed_count, total_count);
-
- user_job.Title = disp_progress;
- user_job.Status = String.IsNullOrEmpty (message) ? Catalog.GetString ("Scanning...") : message;
- user_job.Progress = new_progress;
- }
- }
-
- private void CheckForCanceled ()
- {
- lock (user_job_mutex) {
- if (user_job != null && user_job.IsCancelRequested) {
- throw new ImportCanceledException ();
+ lock (number_format) {
+ string disp_progress = String.Format (ProgressMessage,
+ import_element.ProcessedCount.ToString ("N", number_format),
+ import_element.TotalCount.ToString ("N", number_format));
+
+ user_job.Title = disp_progress;
+ user_job.Status = String.IsNullOrEmpty (message) ? Catalog.GetString ("Scanning...") : message;
+ user_job.Progress = new_progress;
}
}
}
- private void FinalizeImport ()
- {
- path_queue.Clear ();
- processing_queue = false;
- DestroyUserJob ();
- OnImportFinished ();
- }
-
private DateTime last_enqueue_display = DateTime.Now;
- private static System.Globalization.NumberFormatInfo nfi = new System.Globalization.NumberFormatInfo ();
- private void Enqueue (string path)
+ private void UpdateScannerProgress ()
{
- if (path_queue.Contains (path)) {
- return;
- }
-
- total_count++;
-
if (DateTime.Now - last_enqueue_display > TimeSpan.FromMilliseconds (400)) {
- lock (nfi) {
- nfi.NumberDecimalDigits = 0;
+ lock (number_format) {
+ number_format.NumberDecimalDigits = 0;
user_job.Status = String.Format (Catalog.GetString ("Scanning ({0} files)..."),
- total_count.ToString ("N", nfi));
+ import_element.TotalCount.ToString ("N", number_format));
last_enqueue_display = DateTime.Now;
}
}
-
- lock (path_queue) {
- path_queue.Enqueue (path);
- }
}
- public void QueueSource (UriList uris)
- {
- CreateUserJob ();
-
- if (Threaded) {
- ThreadPool.QueueUserWorkItem (ThreadedQueueSource, uris);
- } else {
- ThreadedQueueSource (uris);
- }
- }
-
- public void QueueSource (string source)
- {
- QueueSource (new UriList (source));
- }
-
- public void QueueSource (string [] paths)
- {
- QueueSource (new UriList (paths));
- }
-
- private void ThreadedQueueSource (object o)
- {
- UriList uris = (UriList)o;
-
- try {
- foreach (string path in uris.LocalPaths) {
- Interlocked.Increment (ref scan_ref_count);
- ScanForFiles (path);
- Interlocked.Decrement (ref scan_ref_count);
- }
-
- if(scan_ref_count == 0) {
- ProcessQueue ();
- }
- } catch (ImportCanceledException) {
- FinalizeImport ();
- }
- }
+#endregion
- private void ScanForFiles (string source)
- {
- CheckForCanceled ();
- Interlocked.Increment (ref scan_ref_count);
-
- bool is_regular_file = false;
- bool is_directory = false;
-
- SafeUri source_uri = new SafeUri (source);
-
- try {
- is_regular_file = Banshee.IO.File.Exists (source_uri);
- is_directory = !is_regular_file && Banshee.IO.Directory.Exists (source);
- } catch {
- Interlocked.Decrement (ref scan_ref_count);
- return;
- }
-
- if (is_regular_file) {
- try {
- if (!Path.GetFileName (source).StartsWith (".")) {
- Enqueue (source);
- }
- } catch (System.ArgumentException) {
- // If there are illegal characters in path
- }
- } else if (is_directory) {
- try {
- if (!Path.GetFileName (Path.GetDirectoryName (source)).StartsWith (".")) {
- try {
- foreach (string file in Banshee.IO.Directory.GetFiles (source)) {
- ScanForFiles (file);
- }
-
- foreach (string directory in Banshee.IO.Directory.GetDirectories (source)) {
- ScanForFiles (directory);
- }
- } catch {
- }
- }
- } catch (System.ArgumentException) {
- // If there are illegal characters in path
- }
- }
-
- Interlocked.Decrement (ref scan_ref_count);
- }
-
- private void ProcessQueue ()
- {
- if (processing_queue) {
- return;
- }
-
- processing_queue = true;
- uint timer_id = Log.DebugTimerStart ();
-
- while (path_queue.Count > 0) {
- CheckForCanceled ();
- OnImportRequested (path_queue.Dequeue ());
- }
-
- Log.DebugTimerPrint (timer_id, Title + " duration: {0}");
-
- path_queue.Clear ();
- processing_queue = false;
-
- if (scan_ref_count == 0) {
- DestroyUserJob ();
- OnImportFinished ();
- }
- }
+#region Protected Import Hooks
protected virtual void OnImportRequested (string path)
{
@@ -287,9 +235,9 @@
if (handler != null && path != null) {
ImportEventArgs args = new ImportEventArgs (path);
handler (this, args);
- IncrementProcessedCount (args.ReturnMessage);
+ UpdateProgress (args.ReturnMessage);
} else {
- IncrementProcessedCount (null);
+ UpdateProgress (null);
}
}
@@ -301,13 +249,18 @@
}
}
+#endregion
+
+#region Properties
+
private string title = Catalog.GetString ("Importing Media");
public string Title {
get { return title; }
set { title = value; }
}
- private string cancel_message = Catalog.GetString ("The import process is currently running. Would you like to stop it?");
+ private string cancel_message = Catalog.GetString (
+ "The import process is currently running. Would you like to stop it?");
public string CancelMessage {
get { return cancel_message; }
set { cancel_message = value; }
@@ -319,10 +272,11 @@
set { progress_message = value; }
}
- private bool threaded = true;
public bool Threaded {
- get { return threaded; }
- set { threaded = value; }
+ set { import_element.Threaded = scanner_element.Threaded = value; }
}
+
+#endregion
+
}
}
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Library/HomeDirectoryImportSource.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Library/HomeDirectoryImportSource.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Library/HomeDirectoryImportSource.cs Mon Jun 16 20:32:09 2008
@@ -39,7 +39,7 @@
public void Import ()
{
- Banshee.ServiceStack.ServiceManager.Get<LibraryImportManager> ().QueueSource (
+ Banshee.ServiceStack.ServiceManager.Get<LibraryImportManager> ().Enqueue (
Environment.GetFolderPath (Environment.SpecialFolder.Personal)
);
}
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Library/LibraryImportManager.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Library/LibraryImportManager.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Library/LibraryImportManager.cs Mon Jun 16 20:32:09 2008
@@ -53,7 +53,7 @@
public LibraryImportManager (bool force_copy) : base (DefaultTrackPrimarySourceChooser)
{
- this.force_copy = force_copy;
+ ForceCopy = force_copy;
}
protected override ErrorSource ErrorSource {
@@ -62,12 +62,14 @@
protected override int [] PrimarySourceIds {
get {
- if (primary_source_ids == null) {
- primary_source_ids = new int [] {
- ServiceManager.SourceManager.VideoLibrary.DbId, ServiceManager.SourceManager.MusicLibrary.DbId
+ if (base.PrimarySourceIds == null) {
+ base.PrimarySourceIds = new int [] {
+ ServiceManager.SourceManager.VideoLibrary.DbId,
+ ServiceManager.SourceManager.MusicLibrary.DbId
};
}
- return primary_source_ids;
+
+ return base.PrimarySourceIds;
}
}
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.ServiceStack/Application.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.ServiceStack/Application.cs (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.ServiceStack/Application.cs Mon Jun 16 20:32:09 2008
@@ -36,13 +36,13 @@
using Banshee.Playlist;
using Banshee.SmartPlaylist;
using Banshee.Sources;
+using Banshee.Base;
namespace Banshee.ServiceStack
{
public delegate bool ShutdownRequestHandler ();
public delegate bool TimeoutHandler ();
public delegate bool IdleHandler ();
- public delegate void InvokeHandler ();
public delegate bool IdleTimeoutRemoveHandler (uint id);
public delegate uint TimeoutImplementationHandler (uint milliseconds, TimeoutHandler handler);
public delegate uint IdleImplementationHandler (IdleHandler handler);
@@ -159,12 +159,7 @@
{
RunIdle (delegate { handler (); return false; });
}
-
- public static void Invoke (EventHandler handler)
- {
- RunIdle (delegate { handler (null, EventArgs.Empty); return false; });
- }
-
+
public static uint RunIdle (IdleHandler handler)
{
if (idle_handler == null) {
Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Services.mdp
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Services.mdp (original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Services.mdp Mon Jun 16 20:32:09 2008
@@ -173,6 +173,7 @@
<File name="Banshee.ServiceStack/DBusCommandService.cs" subtype="Code" buildaction="Compile" />
<File name="Banshee.ServiceStack/IDBusObjectName.cs" subtype="Code" buildaction="Compile" />
<File name="Banshee.Hardware/IDiscDuplicator.cs" subtype="Code" buildaction="Compile" />
+ <File name="Banshee.Collection.Database/DatabaseImportResultHandler.cs" subtype="Code" buildaction="Compile" />
</Contents>
<References>
<ProjectReference type="Gac" localcopy="True" refto="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
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 Mon Jun 16 20:32:09 2008
@@ -12,6 +12,7 @@
Banshee.Collection.Database/DatabaseArtistListModel.cs \
Banshee.Collection.Database/DatabaseFilterListModel.cs \
Banshee.Collection.Database/DatabaseImportManager.cs \
+ Banshee.Collection.Database/DatabaseImportResultHandler.cs \
Banshee.Collection.Database/DatabaseTrackInfo.cs \
Banshee.Collection.Database/DatabaseTrackListModel.cs \
Banshee.Collection.Database/DatabaseTrackModelCache.cs \
Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/ConnectedMessageBar.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/ConnectedMessageBar.cs (original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/ConnectedMessageBar.cs Mon Jun 16 20:32:09 2008
@@ -85,7 +85,7 @@
ThreadAssist.ProxyToMain (InnerUpdate);
}
- private void InnerUpdate (object o, EventArgs args)
+ private void InnerUpdate ()
{
if (source == null || source.CurrentMessage == null || source.CurrentMessage.IsHidden) {
Hide ();
Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Library.Gui/FileImportSource.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Library.Gui/FileImportSource.cs (original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Library.Gui/FileImportSource.cs Mon Jun 16 20:32:09 2008
@@ -51,9 +51,8 @@
chooser.SelectMultiple = true;
chooser.DefaultResponse = ResponseType.Ok;
- if(chooser.Run() == (int)ResponseType.Ok) {
- Banshee.ServiceStack.ServiceManager.Get<LibraryImportManager> ("LibraryImportManager").QueueSource (
- chooser.Uris);
+ if (chooser.Run () == (int)ResponseType.Ok) {
+ Banshee.ServiceStack.ServiceManager.Get<LibraryImportManager> ().Enqueue (chooser.Uris);
}
chooser.Destroy ();
Modified: trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Library.Gui/FolderImportSource.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Library.Gui/FolderImportSource.cs (original)
+++ trunk/banshee/src/Core/Banshee.ThickClient/Banshee.Library.Gui/FolderImportSource.cs Mon Jun 16 20:32:09 2008
@@ -49,9 +49,8 @@
chooser.AddButton (Stock.Open, ResponseType.Ok);
chooser.DefaultResponse = ResponseType.Ok;
- if(chooser.Run () == (int)ResponseType.Ok) {
- Banshee.ServiceStack.ServiceManager.Get<LibraryImportManager> ("LibraryImportManager").QueueSource (
- chooser.Uri);
+ if (chooser.Run () == (int)ResponseType.Ok) {
+ Banshee.ServiceStack.ServiceManager.Get<LibraryImportManager> ().Enqueue (chooser.Uri);
}
chooser.Destroy ();
Modified: trunk/banshee/src/Core/Core.mds
==============================================================================
--- trunk/banshee/src/Core/Core.mds (original)
+++ trunk/banshee/src/Core/Core.mds Mon Jun 16 20:32:09 2008
@@ -7,7 +7,7 @@
<Entry build="True" name="Banshee.ThickClient" configuration="Debug" />
</Configuration>
</Configurations>
- <StartMode startupentry="Nereid" single="True">
+ <StartMode startupentry="Banshee.Widgets" single="True">
<Execute type="None" entry="Banshee.Widgets" />
<Execute type="None" entry="Banshee.Services" />
<Execute type="None" entry="Banshee.Core" />
Modified: trunk/banshee/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/MassStorageSource.cs
==============================================================================
--- trunk/banshee/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/MassStorageSource.cs (original)
+++ trunk/banshee/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/MassStorageSource.cs Mon Jun 16 20:32:09 2008
@@ -119,7 +119,7 @@
importer.Threaded = false; // We are already threaded
foreach (string audio_folder in BaseDirectories) {
- importer.QueueSource (audio_folder);
+ importer.Enqueue (audio_folder);
}
}
@@ -134,7 +134,7 @@
{
LibraryImportManager importer = new LibraryImportManager (true);
foreach (string audio_folder in BaseDirectories) {
- importer.QueueSource (audio_folder);
+ importer.Enqueue (audio_folder);
}
}
Modified: trunk/banshee/src/Dap/Dap.mds
==============================================================================
--- trunk/banshee/src/Dap/Dap.mds (original)
+++ trunk/banshee/src/Dap/Dap.mds Mon Jun 16 20:32:09 2008
@@ -7,7 +7,7 @@
<Entry build="True" name="Banshee.Dap.Ipod" configuration="Debug" />
</Configuration>
</Configurations>
- <StartMode startupentry="Banshee.Dap.Ipod" single="True">
+ <StartMode startupentry="Banshee.Dap" single="True">
<Execute type="None" entry="Banshee.Dap" />
<Execute type="None" entry="Banshee.Dap.MassStorage" />
<Execute type="None" entry="Banshee.Dap.Mtp" />
Modified: trunk/banshee/src/Extensions/Banshee.FileSystemQueue/Banshee.FileSystemQueue/FileSystemQueueSource.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.FileSystemQueue/Banshee.FileSystemQueue/FileSystemQueueSource.cs (original)
+++ trunk/banshee/src/Extensions/Banshee.FileSystemQueue/Banshee.FileSystemQueue/FileSystemQueueSource.cs Mon Jun 16 20:32:09 2008
@@ -48,6 +48,8 @@
private DatabaseImportManager importer;
private bool visible = false;
private bool actions_loaded = false;
+ private bool play_enqueued = false;
+ private string path_to_play;
protected override string TypeUniqueId {
get { return "file-system-queue"; }
@@ -60,9 +62,6 @@
Properties.Set<bool> ("AutoAddSource", false);
IsLocal = true;
- importer = new DatabaseImportManager (this);
- importer.KeepUserJobHidden = true;
-
ServiceManager.Get<DBusCommandService> ().ArgumentPushed += OnCommandLineArgument;
AfterInitialized ();
@@ -93,15 +92,11 @@
ServiceManager.SourceManager.ActiveSourceChanged += delegate { UpdateActions (); };
TrackModel.Reloaded += OnTrackModelReloaded;
- Reload ();
-
+ play_enqueued = ApplicationContext.CommandLine.Contains ("play-enqueued");
+
foreach (string path in ApplicationContext.CommandLine.Files) {
Enqueue (path);
}
-
- if (ApplicationContext.CommandLine.Contains ("play-enqueued")) {
- PlayEnqueued ();
- }
}
uint source_activate_id = 0;
@@ -109,7 +104,27 @@
public void Enqueue (string path)
{
lock (this) {
- importer.QueueSource (path);
+ if (importer == null) {
+ importer = new DatabaseImportManager (this);
+ importer.KeepUserJobHidden = true;
+ importer.ImportResult += delegate (object o, DatabaseImportResultArgs args) {
+ Banshee.ServiceStack.Application.Invoke (delegate {
+ if (args.Error != null || path_to_play != null) {
+ return;
+ }
+
+ path_to_play = args.Path;
+ if (args.Track == null) {
+ // Play immediately if the track is already in the source,
+ // otherwise the call will be deferred until the track has
+ // been imported and loaded into the cache
+ PlayEnqueued ();
+ }
+ });
+ };
+ }
+
+ importer.Enqueue (path);
if (source_activate_id == 0) {
source_activate_id = GLib.Timeout.Add (500, delegate {
@@ -121,6 +136,40 @@
}
}
+ private void PlayEnqueued ()
+ {
+ if (!play_enqueued || path_to_play == null) {
+ return;
+ }
+
+ SafeUri uri = null;
+ play_enqueued = false;
+
+ ServiceManager.PlaybackController.NextSource = this;
+
+ try {
+ uri = new SafeUri (path_to_play);
+ } catch {
+ }
+
+ if (uri == null) {
+ return;
+ }
+
+ int id = DatabaseTrackInfo.GetTrackIdForUri (uri, Paths.MakePathRelative (
+ uri.AbsolutePath, BaseDirectory), new int [] { DbId });
+
+ if (id >= 0) {
+ int index = (int)TrackCache.IndexOf ((long)id);
+ if (index >= 0) {
+ TrackInfo track = TrackModel[index];
+ if (track != null) {
+ ServiceManager.PlayerEngine.OpenPlay (track);
+ }
+ }
+ }
+ }
+
public override void Dispose ()
{
ServiceManager.Get<DBusCommandService> ().ArgumentPushed -= OnCommandLineArgument;
@@ -134,12 +183,13 @@
{
if (!isFile) {
if (argument == "play-enqueued") {
- PlayEnqueued ();
+ play_enqueued = true;
+ path_to_play = null;
}
return;
}
- Log.DebugFormat ("FileSystemQueueSource::Enqueue => {0}", argument);
+ Log.DebugFormat ("FSQ Enqueue: {0}", argument);
try {
if (Banshee.IO.Directory.Exists (argument) || Banshee.IO.File.Exists (new SafeUri (argument))) {
@@ -149,12 +199,6 @@
}
}
- private void PlayEnqueued ()
- {
- ServiceManager.PlaybackController.NextSource = this;
- ServiceManager.PlayerEngine.Play ();
- }
-
protected override void OnUpdated ()
{
base.OnUpdated ();
@@ -163,7 +207,16 @@
UpdateActions ();
}
}
-
+
+ public override void Reload ()
+ {
+ base.Reload ();
+
+ //if (Count > 0) {
+ PlayEnqueued ();
+ // }
+ }
+
private void OnTrackModelReloaded (object sender, EventArgs args)
{
if (Count > 0 && !visible) {
@@ -172,6 +225,10 @@
} else if (Count <= 0 && visible) {
ServiceManager.SourceManager.RemoveSource (this);
visible = false;
+ }
+
+ if (Count > 0) {
+ PlayEnqueued ();
}
}
Modified: trunk/banshee/src/Extensions/Banshee.Podcasting/Banshee.Podcasting/PodcastImportManager.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.Podcasting/Banshee.Podcasting/PodcastImportManager.cs (original)
+++ trunk/banshee/src/Extensions/Banshee.Podcasting/Banshee.Podcasting/PodcastImportManager.cs Mon Jun 16 20:32:09 2008
@@ -40,7 +40,7 @@
{
public PodcastImportManager (PodcastSource source) : base (source)
{
- force_copy = false;
+ ForceCopy = false;
}
public DatabaseTrackInfo ImportPodcast (string uri)
Added: trunk/banshee/src/Libraries/Hyena/Hyena.Collections/QueuePipeline.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/Hyena/Hyena.Collections/QueuePipeline.cs Mon Jun 16 20:32:09 2008
@@ -0,0 +1,81 @@
+//
+// QueuePipeline.cs
+//
+// Author:
+// Aaron Bockover <abockover 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;
+
+namespace Hyena.Collections
+{
+ public class QueuePipeline <T> where T : class
+ {
+ private QueuePipelineElement<T> first_element;
+ internal QueuePipelineElement<T> FirstElement {
+ get { return first_element; }
+ }
+
+ public QueuePipeline ()
+ {
+ }
+
+ public void AddElement (QueuePipelineElement<T> element)
+ {
+ lock (this) {
+ if (first_element == null) {
+ first_element = element;
+ return;
+ }
+
+ QueuePipelineElement<T> current = first_element;
+
+ while (current != null) {
+ if (current.NextElement == null) {
+ current.NextElement = element;
+ break;
+ }
+
+ current = current.NextElement;
+ }
+ }
+ }
+
+ public virtual void Enqueue (T item)
+ {
+ if (first_element == null) {
+ throw new InvalidOperationException ("There are no elements in this pipeline");
+ }
+
+ first_element.Enqueue (item);
+ }
+
+ public virtual void Cancel ()
+ {
+ if (first_element != null) {
+ first_element.Cancel ();
+ }
+ }
+ }
+}
Added: trunk/banshee/src/Libraries/Hyena/Hyena.Collections/QueuePipelineElement.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/Hyena/Hyena.Collections/QueuePipelineElement.cs Mon Jun 16 20:32:09 2008
@@ -0,0 +1,183 @@
+//
+// QueuePipelineElement.cs
+//
+// Author:
+// Aaron Bockover <abockover 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.Threading;
+using System.Collections.Generic;
+
+namespace Hyena.Collections
+{
+ public abstract class QueuePipelineElement<T> where T : class
+ {
+ private class ElementProcessCanceledException : ApplicationException
+ {
+ }
+
+ 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;
+
+ protected abstract T ProcessItem (T item);
+
+ protected virtual void OnFinished ()
+ {
+ lock (this) {
+ canceled = false;
+ }
+
+ Console.WriteLine ("Finished {0}", GetType ());
+ }
+
+ protected virtual void OnCanceled ()
+ {
+ Console.WriteLine ("Canceled {0}", GetType ());
+
+ lock (queue) {
+ queue.Clear ();
+ }
+ }
+
+ public virtual void Enqueue (T item)
+ {
+ lock (this) {
+ lock (queue) {
+ queue.Enqueue (item);
+ }
+
+ if (!threaded) {
+ Processor (null);
+ return;
+ }
+
+ if (thread_wait == null) {
+ thread_wait = new AutoResetEvent (false);
+ }
+
+ if (Monitor.TryEnter (monitor)) {
+ Monitor.Exit (monitor);
+ ThreadPool.QueueUserWorkItem (Processor);
+ thread_wait.WaitOne ();
+ }
+ }
+ }
+
+ protected virtual void EnqueueDownstream (T item)
+ {
+ if (NextElement != null && item != null) {
+ NextElement.Enqueue (item);
+ }
+ }
+
+ private void Processor (object state)
+ {
+ lock (monitor) {
+ if (threaded) {
+ thread_wait.Set ();
+ }
+
+ lock (this) {
+ processing = true;
+ }
+
+ try {
+ while (queue.Count > 0) {
+ CheckForCanceled ();
+
+ T item = null;
+ lock (queue) {
+ item = queue.Dequeue ();
+ }
+
+ EnqueueDownstream (ProcessItem (item));
+ }
+ } catch (ElementProcessCanceledException) {
+ OnCanceled ();
+ }
+
+
+ lock (this) {
+ processing = false;
+ thread_wait.Close ();
+ thread_wait = null;
+ }
+
+ OnFinished ();
+ }
+ }
+
+ protected virtual void CheckForCanceled ()
+ {
+ lock (this) {
+ if (canceled) {
+ throw new ElementProcessCanceledException ();
+ }
+ }
+ }
+
+ public void Cancel ()
+ {
+ lock (this) {
+ if (processing) {
+ canceled = true;
+ }
+
+ if (NextElement != null) {
+ NextElement.Cancel ();
+ }
+ }
+ }
+
+ public bool Processing {
+ get { lock (this) { return processing; } }
+ }
+
+ public bool Threaded {
+ get { return threaded; }
+ set {
+ if (processing) {
+ throw new InvalidOperationException ("Cannot change threading model while the element is processing");
+ }
+
+ threaded = value;
+ }
+ }
+
+ protected Queue<T> Queue {
+ get { return queue; }
+ }
+
+ private QueuePipelineElement<T> next_element;
+ internal QueuePipelineElement<T> NextElement {
+ get { return next_element; }
+ set { next_element = value; }
+ }
+ }
+}
Added: trunk/banshee/src/Libraries/Hyena/Hyena.Collections/Tests/QueuePipelineTests.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/Hyena/Hyena.Collections/Tests/QueuePipelineTests.cs Mon Jun 16 20:32:09 2008
@@ -0,0 +1,141 @@
+//
+// ElementQueueProcessor.cs
+//
+// Author:
+// Aaron Bockover <abockover 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.
+//
+
+#if ENABLE_TESTS
+
+using System;
+using System.Threading;
+using System.Collections.Generic;
+using NUnit.Framework;
+
+using Hyena.Collections;
+
+namespace Hyena.Collections.Tests
+{
+ [TestFixture]
+ public class QueuePipelineTests
+ {
+ private class FakeElement : QueuePipelineElement<object>
+ {
+ protected override object ProcessItem (object item)
+ {
+ return null;
+ }
+ }
+
+ [Test]
+ public void BuildPipeline ()
+ {
+ BuildPipeline (1);
+ BuildPipeline (2);
+ BuildPipeline (3);
+ BuildPipeline (10);
+ BuildPipeline (1000);
+ }
+
+ private void BuildPipeline (int count)
+ {
+ List<FakeElement> elements = new List<FakeElement> ();
+ for (int i = 0; i < count; i++) {
+ elements.Add (new FakeElement ());
+ }
+
+ QueuePipeline<object> qp = new QueuePipeline<object> ();
+ foreach (FakeElement s in elements) {
+ qp.AddElement (s);
+ }
+
+ Assert.AreEqual (elements[0], qp.FirstElement);
+
+ int index = 0;
+ FakeElement element = (FakeElement)qp.FirstElement;
+ while (element != null) {
+ Assert.AreEqual (elements[index++], element);
+ element = (FakeElement)element.NextElement;
+ }
+ }
+
+ [Test]
+ public void Blah ()
+ {
+ QueuePipeline<string> pipeline = new QueuePipeline<string> ();
+ pipeline.AddElement (new EvenFilterElement ());
+ pipeline.AddElement (new RandomFilterElement ());
+ pipeline.AddElement (new TerminationElement ());
+
+ for (int i = 0; i < 1000; i++) {
+ pipeline.Enqueue (i.ToString ());
+ }
+
+ Console.ReadLine ();
+ }
+
+ private class EvenFilterElement : QueuePipelineElement<string>
+ {
+ private int index;
+ private Random random = new Random ();
+
+ protected override string ProcessItem (string item)
+ {
+ System.Threading.Thread.Sleep (random.Next (0, 10));
+ return index++ % 2 == 0 ? item : null;
+ }
+ }
+
+ private class RandomFilterElement : QueuePipelineElement<string>
+ {
+ private Random random = new Random ();
+
+ public RandomFilterElement ()
+ {
+ Threaded = true;
+ }
+
+ protected override string ProcessItem (string item)
+ {
+ return random.Next () % 2 == 0 ? null : item;
+ }
+ }
+
+ private class TerminationElement : QueuePipelineElement<string>
+ {
+ public TerminationElement ()
+ {
+ Threaded = true;
+ }
+
+ protected override string ProcessItem (string item)
+ {
+ Console.WriteLine ("TerminationElement: {0}", item);
+ return null;
+ }
+ }
+ }
+}
+
+#endif
Added: trunk/banshee/src/Libraries/Hyena/Hyena.Collections/WriteLineElement.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/Hyena/Hyena.Collections/WriteLineElement.cs Mon Jun 16 20:32:09 2008
@@ -0,0 +1,46 @@
+//
+// WriteLineElement.cs
+//
+// Author:
+// Aaron Bockover <abockover 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;
+
+namespace Hyena.Collections
+{
+ public class WriteLineElement<T> : QueuePipelineElement<T> where T : class
+ {
+ public WriteLineElement ()
+ {
+ Threaded = false;
+ }
+
+ protected override T ProcessItem (T item)
+ {
+ Console.WriteLine (item);
+ return null;
+ }
+ }
+}
Modified: trunk/banshee/src/Libraries/Hyena/Hyena.CommandLine/CommandLineParser.cs
==============================================================================
--- trunk/banshee/src/Libraries/Hyena/Hyena.CommandLine/CommandLineParser.cs (original)
+++ trunk/banshee/src/Libraries/Hyena/Hyena.CommandLine/CommandLineParser.cs Mon Jun 16 20:32:09 2008
@@ -49,23 +49,17 @@
private int generation;
private int sorted_args_generation;
private int offset;
- private string enqueue_arg;
private string [] arguments;
private KeyValuePair<string, Argument> [] sorted_args;
private Dictionary<string, Argument> parsed_arguments = new Dictionary<string, Argument> ();
private List<string> file_list = new List<string> ();
- public CommandLineParser () : this (null, Environment.GetCommandLineArgs (), 1)
+ public CommandLineParser () : this (Environment.GetCommandLineArgs (), 1)
{
}
- public CommandLineParser (string enqueueArgument) : this (enqueueArgument, Environment.GetCommandLineArgs (), 1)
+ public CommandLineParser (string [] arguments, int offset)
{
- }
-
- public CommandLineParser (string enqueueArgument, string [] arguments, int offset)
- {
- this.enqueue_arg = enqueueArgument;
this.arguments = arguments;
this.offset = offset;
@@ -74,21 +68,14 @@
private void Parse ()
{
- bool enqueue_mode = false;
-
for (int i = offset; i < arguments.Length; i++) {
- if (enqueue_mode || !IsOption (arguments[i])) {
+ if (!IsOption (arguments[i])) {
file_list.Add (arguments[i]);
continue;
}
string name = OptionName (arguments[i]);
string value = String.Empty;
-
- if (name == enqueue_arg) {
- enqueue_mode = true;
- continue;
- }
int eq_offset = name.IndexOf ('=');
if (eq_offset > 1) {
Modified: trunk/banshee/src/Libraries/Hyena/Hyena.mdp
==============================================================================
--- trunk/banshee/src/Libraries/Hyena/Hyena.mdp (original)
+++ trunk/banshee/src/Libraries/Hyena/Hyena.mdp Mon Jun 16 20:32:09 2008
@@ -97,6 +97,10 @@
<File name="Hyena/Tests/TestBase.cs" subtype="Code" buildaction="Compile" />
<File name="Hyena.Data/ICacheableItem.cs" subtype="Code" buildaction="Compile" />
<File name="Hyena.Collections/CollectionExtensions.cs" subtype="Code" buildaction="Compile" />
+ <File name="Hyena.Collections/QueuePipeline.cs" subtype="Code" buildaction="Compile" />
+ <File name="Hyena.Collections/Tests/QueuePipelineTests.cs" subtype="Code" buildaction="Compile" />
+ <File name="Hyena.Collections/QueuePipelineElement.cs" subtype="Code" buildaction="Compile" />
+ <File name="Hyena.Collections/WriteLineElement.cs" subtype="Code" buildaction="Compile" />
</Contents>
<References>
<ProjectReference type="Gac" localcopy="True" refto="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
Modified: trunk/banshee/src/Libraries/Hyena/Makefile.am
==============================================================================
--- trunk/banshee/src/Libraries/Hyena/Makefile.am (original)
+++ trunk/banshee/src/Libraries/Hyena/Makefile.am Mon Jun 16 20:32:09 2008
@@ -5,11 +5,15 @@
Hyena.Collections/CollectionExtensions.cs \
Hyena.Collections/IntervalHeap.cs \
Hyena.Collections/IStackProvider.cs \
+ Hyena.Collections/QueuePipeline.cs \
+ Hyena.Collections/QueuePipelineElement.cs \
Hyena.Collections/RangeCollection.cs \
Hyena.Collections/Selection.cs \
Hyena.Collections/SelectionProxy.cs \
Hyena.Collections/Tests/IntervalHeapTests.cs \
+ Hyena.Collections/Tests/QueuePipelineTests.cs \
Hyena.Collections/Tests/RangeCollectionTests.cs \
+ Hyena.Collections/WriteLineElement.cs \
Hyena.CommandLine/CommandLineParser.cs \
Hyena.CommandLine/Layout.cs \
Hyena.CommandLine/LayoutGroup.cs \
Modified: trunk/banshee/src/Libraries/Libraries.mds
==============================================================================
--- trunk/banshee/src/Libraries/Libraries.mds (original)
+++ trunk/banshee/src/Libraries/Libraries.mds Mon Jun 16 20:32:09 2008
@@ -11,7 +11,7 @@
<Entry build="True" name="Migo" configuration="Debug" />
</Configuration>
</Configurations>
- <StartMode startupentry="MusicBrainz" single="True">
+ <StartMode startupentry="Hyena" single="True">
<Execute type="None" entry="Hyena" />
<Execute type="None" entry="Hyena.Gui" />
<Execute type="None" entry="Lastfm" />
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]