Re: [Banshee-List] Re: Mass Storage Support



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]