banshee r4788 - in trunk/banshee: . src/Core/Banshee.Services/Banshee.Collection.Database src/Core/Banshee.Services/Banshee.Library src/Core/Banshee.Services/Banshee.Sources src/Dap/Banshee.Dap.Ipod/Banshee.Dap.Ipod src/Dap/Banshee.Dap.Karma/Banshee.Dap.Karma src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage src/Dap/Banshee.Dap.Mtp/Banshee.Dap.Mtp src/Dap/Banshee.Dap/Banshee.Dap



Author: abock
Date: Fri Nov  7 09:08:31 2008
New Revision: 4788
URL: http://svn.gnome.org/viewvc/banshee?rev=4788&view=rev

Log:
* banshee/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/AndroidDevice.cs:
  Implemented special support for grouping tracks purchased from the
  Amazon MP3 store on the G1 into their own source; also do not allow
  deleting these tracks in the main Music source on the device; they
  can only be deleted from the Purchased Music source

* banshee/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/MassStorageDevice.cs:
  Implemented SourceInitialize and DeleteTrackHook methods

* banshee/src/Dap/Banshee.Dap/Banshee.Dap/VideoGroupSource.cs:
* banshee/src/Dap/Banshee.Dap/Banshee.Dap/PodcastGroupSource.cs: Set
  AutoHide to true so these sources will only show up if there is
  content in them

* banshee/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/MassStorageSource.cs:
  Call SourceInitialize on the MassStorageDevice if we have one and
  after the source itself is initialized; call DeleteTrackHook on the
  MassStorageDevice if we have one and return false if the hook returns
  false, effectively voiding the track deletion from both the disk and
  the database

* banshee/src/Core/Banshee.Services/Banshee.Sources/PrimarySource.cs:
  Make DeleteTrack return bool; in DeleteTrackList, cache the track
  against which DeleteTrack returns false in a skip list and when the
  cache iteration is complete, remove any skip list tracks from the
  cache list before executing the database purge against the cache
  list. Phew.

* banshee/src/Dap/Banshee.Dap/Banshee.Dap/DapSource.cs: Do not add the
  video and podcasts group sources since they are now AutoHide and will
  manage that on their own

* banshee/src/Dap/Banshee.Dap/Banshee.Dap/MediaGroupSource.cs:
  Implemented an AutoHide feature that will only show items when the
  feature is on if there are actually items in the source

* banshee/src/Dap/Banshee.Dap.Mtp/Banshee.Dap.Mtp/MtpSource.cs:
* banshee/src/Dap/Banshee.Dap.Ipod/Banshee.Dap.Ipod/IpodSource.cs:
* banshee/src/Core/Banshee.Services/Banshee.Library/LibrarySource.cs:
* banshee/src/Dap/Banshee.Dap.Karma/Banshee.Dap.Karma/KarmaSource.cs:
  Updated to reflect API change in PrimarySource

* banshee/src/Core/Banshee.Services/Banshee.Collection.Database/CachedList.cs:
  Implement a Remove method that allows trimming the cache

* banshee/src/Core/Banshee.Services/Banshee.Sources/Source.cs:
  Implemented ContainsChildSource method

Modified:
   trunk/banshee/ChangeLog
   trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/CachedList.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Library/LibrarySource.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/PrimarySource.cs
   trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/Source.cs
   trunk/banshee/src/Dap/Banshee.Dap.Ipod/Banshee.Dap.Ipod/IpodSource.cs
   trunk/banshee/src/Dap/Banshee.Dap.Karma/Banshee.Dap.Karma/KarmaSource.cs
   trunk/banshee/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/AndroidDevice.cs
   trunk/banshee/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/MassStorageDevice.cs
   trunk/banshee/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/MassStorageSource.cs
   trunk/banshee/src/Dap/Banshee.Dap.Mtp/Banshee.Dap.Mtp/MtpSource.cs
   trunk/banshee/src/Dap/Banshee.Dap/Banshee.Dap/DapSource.cs
   trunk/banshee/src/Dap/Banshee.Dap/Banshee.Dap/MediaGroupSource.cs
   trunk/banshee/src/Dap/Banshee.Dap/Banshee.Dap/PodcastGroupSource.cs
   trunk/banshee/src/Dap/Banshee.Dap/Banshee.Dap/VideoGroupSource.cs

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/CachedList.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/CachedList.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Collection.Database/CachedList.cs	Fri Nov  7 09:08:31 2008
@@ -27,6 +27,7 @@
 //
 
 using System;
+using System.Text;
 using System.Collections;
 using System.Collections.Generic;
 
@@ -116,6 +117,28 @@
             ServiceManager.DbConnection.Execute ("DELETE FROM CoreCache WHERE ModelId = ?", CacheId);
         }
         
+        public void Remove (IEnumerable<T> items)
+        {
+            lock (cache) {
+                StringBuilder builder = new StringBuilder ();
+                bool first = true;
+                foreach (T item in items) {
+                    if (!first) {
+                        builder.Append (',');
+                    }
+                    
+                    builder.Append (item.CacheEntryId);
+                    first = false;
+                }
+                
+                ServiceManager.DbConnection.Execute (String.Format (
+                    "DELETE FROM CoreCache WHERE ModelId = {0} AND ItemId IN ({1})", 
+                    CacheId, builder));
+                    
+                cache.UpdateAggregates ();
+            }
+        }
+        
         public T this[int index] {
             get { return cache.GetValue (index); }
         }

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Library/LibrarySource.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Library/LibrarySource.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Library/LibrarySource.cs	Fri Nov  7 09:08:31 2008
@@ -89,13 +89,15 @@
             Banshee.IO.File.Copy (track.Uri, uri, false);
         }*/
 
-        protected override void DeleteTrack (DatabaseTrackInfo track)
+        protected override bool DeleteTrack (DatabaseTrackInfo track)
         {
             try {
                 Banshee.IO.Utilities.DeleteFileTrimmingParentDirectories (track.Uri);
             } catch (System.IO.FileNotFoundException) {
             } catch (System.IO.DirectoryNotFoundException) {
             }
+            
+            return true;
         }
 
         protected override void AddTrack (DatabaseTrackInfo track)

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/PrimarySource.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/PrimarySource.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/PrimarySource.cs	Fri Nov  7 09:08:31 2008
@@ -479,6 +479,7 @@
         {
             is_deleting = true;
             DeleteTrackJob.Total += (int) list.Count;
+            List<DatabaseTrackInfo> skip_deletion = null;
 
             // Remove from file system
             foreach (DatabaseTrackInfo track in list) {
@@ -489,7 +490,12 @@
 
                 try {
                     DeleteTrackJob.Status = String.Format ("{0} - {1}", track.ArtistName, track.TrackTitle);
-                    DeleteTrack (track);
+                    if (!DeleteTrack (track)) {
+                        if (skip_deletion == null) {
+                            skip_deletion = new List<DatabaseTrackInfo> ();
+                        }
+                        skip_deletion.Add (track);
+                    }
                 } catch (Exception e) {
                     Log.Exception (e);
                     ErrorSource.AddMessage (e.Message, track.Uri.ToString ());
@@ -507,10 +513,18 @@
                 delete_track_job.Finish ();
                 delete_track_job = null;
             }
+            
+            if (skip_deletion != null) {
+                list.Remove (skip_deletion);
+                skip_deletion.Clear ();
+                skip_deletion = null;
+            }
 
             // Remove from database
-            ServiceManager.DbConnection.Execute (remove_list_command, DateTime.Now, list.CacheId, list.CacheId);
-
+            if (list.Count > 0) {
+                ServiceManager.DbConnection.Execute (remove_list_command, DateTime.Now, list.CacheId, list.CacheId);
+            }
+            
             ThreadAssist.ProxyToMain (delegate {
                 OnTracksDeleted ();
                 OnUserNotifyUpdated ();
@@ -518,7 +532,7 @@
             });
         }
 
-        protected virtual void DeleteTrack (DatabaseTrackInfo track)
+        protected virtual bool DeleteTrack (DatabaseTrackInfo track)
         {
             throw new Exception ("PrimarySource DeleteTrack method not implemented");
         }

Modified: trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/Source.cs
==============================================================================
--- trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/Source.cs	(original)
+++ trunk/banshee/src/Core/Banshee.Services/Banshee.Sources/Source.cs	Fri Nov  7 09:08:31 2008
@@ -173,6 +173,13 @@
             this.parent = parent;
         }
         
+        public virtual bool ContainsChildSource (Source child)
+        {
+            lock (Children) {
+                return child_sources.Contains (child);
+            }
+        }
+        
         public virtual void AddChildSource (Source child)
         {
             lock (Children) {

Modified: trunk/banshee/src/Dap/Banshee.Dap.Ipod/Banshee.Dap.Ipod/IpodSource.cs
==============================================================================
--- trunk/banshee/src/Dap/Banshee.Dap.Ipod/Banshee.Dap.Ipod/IpodSource.cs	(original)
+++ trunk/banshee/src/Dap/Banshee.Dap.Ipod/Banshee.Dap.Ipod/IpodSource.cs	Fri Nov  7 09:08:31 2008
@@ -429,17 +429,19 @@
             throw new Exception ("Copy to Library is not implemented for iPods yet");
         }*/
 
-        protected override void DeleteTrack (DatabaseTrackInfo track)
+        protected override bool DeleteTrack (DatabaseTrackInfo track)
         {
             lock (sync_mutex) {
                 if (!tracks_map.ContainsKey (track.TrackId)) {
-                    return;
+                    return true;
                 }
                 
                 IpodTrackInfo ipod_track = tracks_map[track.TrackId];
                 if (ipod_track != null) {
                     tracks_to_remove.Enqueue (ipod_track);
                 }
+                
+                return true;
             }
         }
         

Modified: trunk/banshee/src/Dap/Banshee.Dap.Karma/Banshee.Dap.Karma/KarmaSource.cs
==============================================================================
--- trunk/banshee/src/Dap/Banshee.Dap.Karma/Banshee.Dap.Karma/KarmaSource.cs	(original)
+++ trunk/banshee/src/Dap/Banshee.Dap.Karma/Banshee.Dap.Karma/KarmaSource.cs	Fri Nov  7 09:08:31 2008
@@ -113,17 +113,19 @@
             Log.Information("Unimplemented");
         }
 
-        protected override void DeleteTrack(DatabaseTrackInfo track)
+        protected override bool DeleteTrack(DatabaseTrackInfo track)
         {
             KarmaTrackInfo karma_track = track_map[track.TrackId];
             if (karma_track == null)
-                return;
+                return true;
 
             lock (device) {
                 device.DeleteSong(karma_track.KarmaId);
                 device.Save();
                 track_map.Remove(track.TrackId);
             }
+            
+            return true;
         }
 
         protected override void AddTrackToDevice(DatabaseTrackInfo track, SafeUri fromUri)

Modified: trunk/banshee/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/AndroidDevice.cs
==============================================================================
--- trunk/banshee/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/AndroidDevice.cs	(original)
+++ trunk/banshee/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/AndroidDevice.cs	Fri Nov  7 09:08:31 2008
@@ -27,8 +27,10 @@
 //
 
 using System;
+using Mono.Unix;
 
 using Banshee.Hardware;
+using Banshee.Collection.Database;
 
 namespace Banshee.Dap.MassStorage
 {
@@ -47,15 +49,26 @@
         };
         
         private static string [] audio_folders = new string [] {
-            "Music/",
+            "music/",
             "amazonmp3/"
         };
         
+        private AmazonMp3GroupSource amazon_source;
+        private string amazon_base_dir;
+        
         public AndroidDevice (VendorProductInfo productInfo, MassStorageSource source) 
             : base (productInfo, source)
         {
         }
         
+        public override void SourceInitialize ()
+        {
+            amazon_source = new AmazonMp3GroupSource (Source);
+            amazon_source.AutoHide = true;
+            
+            amazon_base_dir = System.IO.Path.Combine (Source.Volume.MountPoint, audio_folders[1]);
+        }
+        
         public override bool LoadDeviceConfiguration ()
         {
             return true;
@@ -75,7 +88,7 @@
             }
         }
         
-        public override string[] AudioFolders {
+        public override string [] AudioFolders {
             get { return audio_folders; }
         }
         
@@ -98,5 +111,58 @@
         public override int CoverArtSize {
             get { return 320; }
         }
+        
+#region Amazon MP3 Store Purchased Tracks Management
+
+        public override bool DeleteTrackHook (DatabaseTrackInfo track)
+        {
+            // Do not allow removing purchased tracks if not in the
+            // Amazon Purchased Music source; this should prevent
+            // accidental deletion of purchased music that may not 
+            // have been copied from the device yet.
+            //
+            // TODO: Provide some feedback when a purchased track is
+            // skipped from deletion
+            //
+            // FIXME: unfortunately this does not work due to 
+            // the cache models being potentially different
+            // even though they will always reference the same tracks
+            // amazon_source.TrackModel.IndexOf (track) >= 0
+            
+            if (!amazon_source.Active && amazon_source.Count > 0 && track.Uri.LocalPath.StartsWith (amazon_base_dir)) {
+                return false;
+            }
+            
+            return true;
+        }
+        
+        private class AmazonMp3GroupSource : MediaGroupSource
+        {
+            public AmazonMp3GroupSource (DapSource parent) : base (parent, Catalog.GetString ("Purchased Music"))
+            {
+                Properties.SetString ("Icon.Name", "amazon-mp3-source");
+                ConditionSql = "(CoreTracks.Uri LIKE \"amazonmp3/%\")";
+            }
+            
+            public override void Activate ()
+            {
+                base.Activate ();
+                active = true;
+            }
+
+            public override void Deactivate ()
+            {
+                base.Deactivate ();
+                active = false;
+            }
+            
+            private bool active;
+            public bool Active {
+                get { return active; }
+            }
+        }
+
+#endregion
+
     }
 }

Modified: trunk/banshee/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/MassStorageDevice.cs
==============================================================================
--- trunk/banshee/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/MassStorageDevice.cs	(original)
+++ trunk/banshee/src/Dap/Banshee.Dap.MassStorage/Banshee.Dap.MassStorage/MassStorageDevice.cs	Fri Nov  7 09:08:31 2008
@@ -34,6 +34,7 @@
 
 using Banshee.Base;
 using Banshee.Hardware;
+using Banshee.Collection.Database;
 
 namespace Banshee.Dap.MassStorage
 {
@@ -49,6 +50,15 @@
             this.source = source;
         }
         
+        public virtual void SourceInitialize ()
+        {
+        }
+        
+        public virtual bool DeleteTrackHook (DatabaseTrackInfo track)
+        {
+            return true;
+        }
+        
         public virtual bool LoadDeviceConfiguration ()
         {
             string path = IsAudioPlayerPath;

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	Fri Nov  7 09:08:31 2008
@@ -96,7 +96,11 @@
             mount_point = volume.MountPoint;
 
             Initialize ();
-
+            
+            if (ms_device != null) {
+                ms_device.SourceInitialize ();
+            }
+            
             AddDapProperties ();
 
             // TODO differentiate between Audio Players and normal Disks, and include the size, eg "2GB Audio Player"?
@@ -333,7 +337,7 @@
         }
 
         private string write_path = null;
-        protected string WritePath {
+        public string WritePath {
             get {
                 if (write_path == null) {
                     write_path = BaseDirectory;
@@ -482,9 +486,13 @@
             }
         }
 
-        protected override void DeleteTrack (DatabaseTrackInfo track)
+        protected override bool DeleteTrack (DatabaseTrackInfo track)
         {
             try {
+                if (ms_device != null && !ms_device.DeleteTrackHook (track)) {
+                    return false;
+                }
+            
                 string track_file = System.IO.Path.GetFileName (track.Uri.LocalPath);
                 string track_dir = System.IO.Path.GetDirectoryName (track.Uri.LocalPath);
                 int files = 0;
@@ -508,6 +516,8 @@
             } catch (System.IO.FileNotFoundException) {
             } catch (System.IO.DirectoryNotFoundException) {
             }
+            
+            return true;
         }
 
         protected override void Eject ()

Modified: trunk/banshee/src/Dap/Banshee.Dap.Mtp/Banshee.Dap.Mtp/MtpSource.cs
==============================================================================
--- trunk/banshee/src/Dap/Banshee.Dap.Mtp/Banshee.Dap.Mtp/MtpSource.cs	(original)
+++ trunk/banshee/src/Dap/Banshee.Dap.Mtp/Banshee.Dap.Mtp/MtpSource.cs	Fri Nov  7 09:08:31 2008
@@ -361,7 +361,7 @@
             return 0;
         }
 
-        protected override void DeleteTrack (DatabaseTrackInfo track)
+        protected override bool DeleteTrack (DatabaseTrackInfo track)
         {
             lock (mtp_device) {
                 Track mtp_track = track_map [track.TrackId];
@@ -380,6 +380,8 @@
                         album_cache.Remove (key);
                     }
                 }
+                
+                return true;
             }
         }
 

Modified: trunk/banshee/src/Dap/Banshee.Dap/Banshee.Dap/DapSource.cs
==============================================================================
--- trunk/banshee/src/Dap/Banshee.Dap/Banshee.Dap/DapSource.cs	(original)
+++ trunk/banshee/src/Dap/Banshee.Dap/Banshee.Dap/DapSource.cs	Fri Nov  7 09:08:31 2008
@@ -198,11 +198,11 @@
             AddChildSource (music_group_source = new MusicGroupSource (this));
 
             if (SupportsVideo) {
-                AddChildSource (video_group_source = new VideoGroupSource (this));
+                video_group_source = new VideoGroupSource (this);
             }
 
             if (SupportsPodcasts) {
-                AddChildSource (podcast_group_source = new PodcastGroupSource (this));
+                podcast_group_source = new PodcastGroupSource (this);
             }
 
             BuildPreferences ();

Modified: trunk/banshee/src/Dap/Banshee.Dap/Banshee.Dap/MediaGroupSource.cs
==============================================================================
--- trunk/banshee/src/Dap/Banshee.Dap/Banshee.Dap/MediaGroupSource.cs	(original)
+++ trunk/banshee/src/Dap/Banshee.Dap/Banshee.Dap/MediaGroupSource.cs	Fri Nov  7 09:08:31 2008
@@ -65,14 +65,30 @@
             if (parent != null) {
                 parent.RaiseUpdated ();
             }
+            
+            if (AutoHide) {
+                bool contains_me = parent.ContainsChildSource (this);
+                int count = Count;
+                
+                if (count == 0 && contains_me) {
+                    parent.RemoveChildSource (this);
+                } else if (count > 0 && !contains_me) {
+                    parent.AddChildSource (this);
+                }
+            }
         }
 
-
         /*public override bool AcceptsInputFromSource (Source source)
         {
             return (source is DatabaseSource) && source.Parent != Parent && source != Parent;
         }*/
         
+        private bool auto_hide;
+        public virtual bool AutoHide {
+            get { return auto_hide; }
+            set { auto_hide = value; }
+        }
+        
         public override string ConditionSql {
             get { return base.ConditionSql; }
             protected set { 

Modified: trunk/banshee/src/Dap/Banshee.Dap/Banshee.Dap/PodcastGroupSource.cs
==============================================================================
--- trunk/banshee/src/Dap/Banshee.Dap/Banshee.Dap/PodcastGroupSource.cs	(original)
+++ trunk/banshee/src/Dap/Banshee.Dap/Banshee.Dap/PodcastGroupSource.cs	Fri Nov  7 09:08:31 2008
@@ -40,6 +40,7 @@
             Properties.Remove ("Icon.Name");
             Properties.SetStringList ("Icon.Name", "podcast");
             ConditionSql = String.Format ("(CoreTracks.Attributes & {0}) != 0", (int)TrackMediaAttributes.Podcast);
+            AutoHide = true;
         }
     }
 }

Modified: trunk/banshee/src/Dap/Banshee.Dap/Banshee.Dap/VideoGroupSource.cs
==============================================================================
--- trunk/banshee/src/Dap/Banshee.Dap/Banshee.Dap/VideoGroupSource.cs	(original)
+++ trunk/banshee/src/Dap/Banshee.Dap/Banshee.Dap/VideoGroupSource.cs	Fri Nov  7 09:08:31 2008
@@ -40,6 +40,7 @@
             Properties.Remove ("Icon.Name");
             Properties.SetStringList ("Icon.Name", Banshee.ServiceStack.ServiceManager.SourceManager.VideoLibrary.Properties.GetStringList ("Icon.Name"));
             ConditionSql = Banshee.ServiceStack.ServiceManager.SourceManager.VideoLibrary.AttributesCondition;
+            AutoHide = true;
         }
     }
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]