Re: [Banshee-List] Re: Mass Storage Support
- From: "James Stembridge" <jstembridge gmail com>
- To: banshee-list gnome org
- Subject: Re: [Banshee-List] Re: Mass Storage Support
- Date: Mon, 17 Apr 2006 23:11:02 +0100
On 4/17/06, James Stembridge <jstembridge gmail com> wrote:
> Thanks for incorporating my patches, a couple of things:
...
Fixed up patch attached.
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/banshee/ChangeLog,v
retrieving revision 1.451
diff -u -r1.451 ChangeLog
--- ChangeLog 17 Apr 2006 17:44:09 -0000 1.451
+++ ChangeLog 17 Apr 2006 19:10:25 -0000
@@ -1,3 +1,31 @@
+2006-04-17 James Stembridge <jstembridge gmail com>
+
+ * src/Banshee.Dap/MassStorage/MassStorageDap.cs: When adding a song to
+ the device, overwrite it if it is out of date. Don't use the volume
+ label for the Name if it's blank. If mounted volume isn't available
+ from VFS yet, wait for it.
+
+2006-04-17 Gabriel Burt <gabriel burt gmail com>
+
+ * src/Banshee.Base/Makefile.am: add QueuedOperationManager.cs.
+
+ * src/Banshee.Base/QueuedOperationManager.cs: New file, allows for generic
+ asynchronous events like copying files to a USB DAP, etc.
+
+ * src/Banshee.Base/Dap/Dap.cs: Add EmitTrackAdded method and allow
+ sub-classes to override AddTrack.
+
+ * src/Banshee.Dap/MassStorage/MassStorageDap.cs: Fix the bug where the DAP
+ couldn't be plugged in when Banshee started, handle copying files to the
+ device asynchronously using a QueuedOperationManager that pops up a
+ ActiveUserEvent if the transfer is slow. Escape artist/album/title when
+ creating the destination filename. Catch exceptions in the copy.
+
+ * src/Banshee.Widets/ActiveUserEvent.cs: Add an option for having the user
+ event not register itself (and therefore not show itself) until at least a
+ second has passed, at which time if the operation is less than 33% done,
+ it is registered and shown (and otherwise it is not).
+
2006-04-17 Aaron Bockover <aaron abock org>
* configure.ac: Require njb-sharp 0.3.0+
Index: src/Banshee.Base/Makefile.am
===================================================================
RCS file: /cvs/gnome/banshee/src/Banshee.Base/Makefile.am,v
retrieving revision 1.28
diff -u -r1.28 Makefile.am
--- src/Banshee.Base/Makefile.am 9 Apr 2006 21:30:23 -0000 1.28
+++ src/Banshee.Base/Makefile.am 17 Apr 2006 19:10:26 -0000
@@ -93,6 +93,7 @@
$(srcdir)/LibraryTrackInfo.cs \
$(srcdir)/FileTrackInfo.cs \
$(srcdir)/DBusRemote.cs \
+ $(srcdir)/QueuedOperationManager.cs \
$(srcdir)/QueuedSqliteDatabase.cs \
$(srcdir)/AudioCdRipper.cs \
$(srcdir)/IImportSource.cs \
Index: src/Banshee.Base/Dap/Dap.cs
===================================================================
RCS file: /cvs/gnome/banshee/src/Banshee.Base/Dap/Dap.cs,v
retrieving revision 1.16
diff -u -r1.16 Dap.cs
--- src/Banshee.Base/Dap/Dap.cs 17 Apr 2006 17:44:10 -0000 1.16
+++ src/Banshee.Base/Dap/Dap.cs 17 Apr 2006 19:10:27 -0000
@@ -123,7 +123,7 @@
private uint uid;
private PropertyTable properties = new PropertyTable();
- private ArrayList tracks = new ArrayList();
+ protected ArrayList tracks = new ArrayList();
private ActiveUserEvent save_report_event;
private bool is_syncing = false;
private bool can_cancel_save = true;
@@ -188,7 +188,7 @@
OnPropertiesChanged();
}
- public void AddTrack(TrackInfo track)
+ public virtual void AddTrack(TrackInfo track)
{
TrackInfo dap_track = OnTrackAdded(track);
@@ -537,6 +537,12 @@
return new SafeUri(dir + Path.DirectorySeparatorChar
+ ".banshee-dap-" + file + "." + newext);
+ }
+
+ protected void EmitTrackAdded (TrackInfo track)
+ {
+ if(TrackAdded != null)
+ TrackAdded(this, new DapTrackListUpdatedArgs(track));
}
public virtual Gdk.Pixbuf GetIcon(int size)
Index: src/Banshee.Dap/MassStorage/MassStorageDap.cs
===================================================================
RCS file: /cvs/gnome/banshee/src/Banshee.Dap/MassStorage/MassStorageDap.cs,v
retrieving revision 1.6
diff -u -r1.6 MassStorageDap.cs
--- src/Banshee.Dap/MassStorage/MassStorageDap.cs 9 Apr 2006 21:30:26 -0000 1.6
+++ src/Banshee.Dap/MassStorage/MassStorageDap.cs 17 Apr 2006 19:10:27 -0000
@@ -63,7 +63,7 @@
player_device = Hal.Device.UdisToDevices (volume_device.Context, new string [] {volume_device ["info.parent"]}) [0];
usb_device = Hal.Device.UdisToDevices (player_device.Context, new string [] {player_device ["storage.physical_device"]}) [0];
} catch (Exception e) {
- return InitializeResult.Invalid;
+ return InitializeResult.Invalid;
}
if (!player_device.PropertyExists ("portable_audio_player.access_method") ||
@@ -78,37 +78,52 @@
!volume_device.GetPropertyBool("volume.is_mounted"))
return InitializeResult.WaitForPropertyChange;
-
- string block_device = volume_device ["block_device"];
- foreach (Gnome.Vfs.Volume vol in monitor.MountedVolumes) {
- if (vol.DevicePath == block_device) {
- this.volume = vol;
- break;
- }
+ volume = monitor.GetVolumeForPath(MountPoint);
+ if(volume == null) {
+ // Gnome VFS doesn't know volume is mounted yet
+ monitor.VolumeMounted += OnVolumeMounted;
+ is_read_only = true;
+ } else {
+ is_read_only = volume.IsReadOnly;
}
- if (volume == null)
- return InitializeResult.Invalid;
-
- is_read_only = volume.IsReadOnly;
-
base.Initialize (usb_device);
InstallProperty("Vendor", usb_device["usb.vendor"]);
- ReloadDatabase();
+ if(!Globals.UIManager.IsInitialized) {
+ Globals.UIManager.Initialized += OnUIManagerInitialized;
+ } else {
+ ReloadDatabase();
+ }
// FIXME probably should be able to cancel at some point when you can actually sync
CanCancelSave = false;
return InitializeResult.Valid;
}
+ public void OnVolumeMounted(object o, Gnome.Vfs.VolumeMountedArgs args) {
+ if(args.Volume.DevicePath == volume_device["block.device"]) {
+ monitor.VolumeMounted -= OnVolumeMounted;
+
+ volume = args.Volume;
+ is_read_only = volume.IsReadOnly;
+
+ // FIXME should probably reload the tracks..
+ }
+ }
+
public override void Dispose()
{
// FIXME anything else to do here?
volume = null;
base.Dispose();
}
+
+ private void OnUIManagerInitialized(object o, EventArgs args)
+ {
+ ReloadDatabase ();
+ }
private void ReloadDatabase()
{
@@ -145,7 +160,8 @@
public override void Eject ()
{
- volume.Unmount (UnmountCallback);
+ if(volume != null)
+ volume.Unmount (UnmountCallback);
}
private void UnmountCallback (bool succeeded, string error, string detailed_error)
@@ -163,17 +179,49 @@
else
Console.WriteLine ("Failed to eject. {1} {2}", error, detailed_error);
}
+
+ public override void AddTrack(TrackInfo track)
+ {
+ if (track == null || IsReadOnly)
+ return;
+
+ // If we're "adding" it when it's already on the device, then
+ // we don't need to copy it
+ if (track is MassStorageTrackInfo) {
+ tracks.Add(track);
+ EmitTrackAdded(track);
+ } else {
+ Copier.Enqueue (track);
+ }
+ }
- protected override TrackInfo OnTrackAdded(TrackInfo track)
+ private void HandleCopyRequested (object o, QueuedOperationArgs args)
{
- if (track is MassStorageTrackInfo || IsReadOnly)
- return track;
+ TrackInfo track = args.Object as TrackInfo;
+
+ if (track == null)
+ return;
+
+ try {
+ string new_path = GetTrackPath (track);
+
+ // If it already is on the device but it's out of date, remove it
+ if (File.Exists (new_path) && File.GetLastWriteTime(track.Uri.LocalPath) > File.GetLastWriteTime(new_path))
+ RemoveTrack(new MassStorageTrackInfo(new SafeUri(new_path)));
+
+ if (!File.Exists (new_path)) {
+ Directory.CreateDirectory (Path.GetDirectoryName (new_path));
+ File.Copy (track.Uri.LocalPath, new_path);
+ }
- string new_path = GetTrackPath (track);
- Directory.CreateDirectory (Path.GetDirectoryName (new_path));
- File.Copy (track.Uri.LocalPath, new_path);
+ TrackInfo new_track = new MassStorageTrackInfo (new SafeUri (new_path));
+ tracks.Add(new_track);
+ EmitTrackAdded(track);
- return new MassStorageTrackInfo (new SafeUri (new_path));
+ args.ReturnMessage = String.Format("{0} - {1}", track.Artist, track.Title);
+ } catch (Exception e) {
+ args.ReturnMessage = String.Format("Skipping Song", track.Artist, track.Title);
+ }
}
protected override void OnTrackRemoved(TrackInfo track)
@@ -213,19 +261,24 @@
private string GetTrackPath (TrackInfo track)
{
string file_path = "";
+
+ string artist = FileNamePattern.Escape (track.Artist);
+ string album = FileNamePattern.Escape (track.Album);
+ string number_title = FileNamePattern.Escape (track.TrackNumberTitle);
+
if (player_device.PropertyExists ("portable_audio_player.filepath_format")) {
file_path = player_device.GetPropertyString ("portable_audio_player.filepath_format");
- file_path = file_path.Replace ("%Artist", track.Artist);
- file_path = file_path.Replace ("%Album", track.Album);
+ file_path = file_path.Replace ("%Artist", artist);
+ file_path = file_path.Replace ("%Album", album);
if (file_path.IndexOf ("%Track") == -1) {
- file_path = System.IO.Path.Combine (file_path, track.TrackNumberTitle);
+ file_path = System.IO.Path.Combine (file_path, number_title);
} else {
- file_path = file_path.Replace ("%Track", track.TrackNumberTitle);
+ file_path = file_path.Replace ("%Track", number_title);
}
} else {
- file_path = System.IO.Path.Combine (track.Artist, track.Album);
- file_path = System.IO.Path.Combine (file_path, track.TrackNumberTitle);
+ file_path = System.IO.Path.Combine (artist, album);
+ file_path = System.IO.Path.Combine (file_path, number_title);
}
file_path += Path.GetExtension (track.Uri.LocalPath);
@@ -234,6 +287,21 @@
return System.IO.Path.Combine (MountPoint, file_path);
}
+ private QueuedOperationManager copier;
+ public QueuedOperationManager Copier {
+ get {
+ if (copier == null) {
+ copier = new QueuedOperationManager ();
+ copier.ActionMessage = Catalog.GetString ("Copying Songs");
+ copier.ProgressMessage = Catalog.GetString ("Copying {0} of {1}");
+ copier.OperationRequested += HandleCopyRequested;
+ }
+
+ return copier;
+ }
+ set { copier = value; }
+ }
+
public virtual string IconId {
get {
return null;
@@ -242,7 +310,8 @@
public override string Name {
get {
- if (volume_device.PropertyExists("volume.label"))
+ if (volume_device.PropertyExists("volume.label") &&
+ volume_device["volume.label"].Length > 0)
return volume_device["volume.label"];
if (player_device.PropertyExists("info.product"))
Index: src/Banshee.Widgets/ActiveUserEvent.cs
===================================================================
RCS file: /cvs/gnome/banshee/src/Banshee.Widgets/ActiveUserEvent.cs,v
retrieving revision 1.7
diff -u -r1.7 ActiveUserEvent.cs
--- src/Banshee.Widgets/ActiveUserEvent.cs 13 Feb 2006 22:18:14 -0000 1.7
+++ src/Banshee.Widgets/ActiveUserEvent.cs 17 Apr 2006 19:10:28 -0000
@@ -49,6 +49,7 @@
private string header;
private uint timeout_id = 0;
+ private uint slow_timeout_id = 0;
private bool disposed = false;
public event EventHandler Disposed;
@@ -56,8 +57,10 @@
private bool cancel_requested;
private bool can_cancel;
-
- public ActiveUserEvent(string name)
+
+ public ActiveUserEvent(string name) : this (name, false) {}
+
+ public ActiveUserEvent(string name, bool delay_show)
{
tips = new Tooltips();
@@ -117,7 +120,11 @@
table.ShowAll();
- ActiveUserEventsManager.Instance.Register(this);
+ Console.WriteLine ("Delay show = {0}", delay_show);
+ if (delay_show)
+ slow_timeout_id = GLib.Timeout.Add(1000, OnCheckForDisplay);
+ else
+ ActiveUserEventsManager.Instance.Register(this);
}
public void Cancel()
@@ -138,10 +145,34 @@
GLib.Source.Remove(timeout_id);
timeout_id = 0;
}
+
+ if(slow_timeout_id > 0) {
+ GLib.Source.Remove(slow_timeout_id);
+ slow_timeout_id = 0;
+ }
if(Disposed != null) {
Disposed(this, new EventArgs());
}
+ }
+
+ private bool OnCheckForDisplay()
+ {
+ Console.WriteLine ("OnCheckForDisplay called..");
+ if (disposed)
+ return false;
+
+ Console.WriteLine ("...and not disposed..");
+
+ // If the event has not made enough progress, show this event
+ if (Progress < 0.33) {
+ Console.WriteLine ("Didn't make enough progress, showing action event");
+ ActiveUserEventsManager.Instance.Register(this);
+ } else {
+ Console.WriteLine ("Made enough progress, not showing action event");
+ }
+
+ return false;
}
private bool OnTimeout()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]