[banshee: 17/57] Moved parsing of tracks out of the source and into the service, this will allow for one parsing pass



commit 3739dc244ce30a87db46e3ad8db09d2118a78380
Author: Tobias Arrskog <topfs2 xbmc org>
Date:   Tue Jun 28 12:23:54 2011 +0200

    Moved parsing of tracks out of the source and into the service, this will allow for one parsing pass for the multiple types of media found on a mediaserver.

 .../Banshee.UPnPClient/UPnPService.cs              |   77 +++++++++++++++++--
 .../Banshee.UPnPClient/UPnPSource.cs               |   78 ++++----------------
 2 files changed, 85 insertions(+), 70 deletions(-)
---
diff --git a/src/Extensions/Banshee.UPnPClient/Banshee.UPnPClient/UPnPService.cs b/src/Extensions/Banshee.UPnPClient/Banshee.UPnPClient/UPnPService.cs
index 5a261b6..e647f56 100644
--- a/src/Extensions/Banshee.UPnPClient/Banshee.UPnPClient/UPnPService.cs
+++ b/src/Extensions/Banshee.UPnPClient/Banshee.UPnPClient/UPnPService.cs
@@ -27,11 +27,13 @@
 //
 
 using System;
+using System.Collections.Generic;
 
 using Mono.Addins;
 
 using Mono.Upnp;
 using Mono.Upnp.Dcp.MediaServer1.ContentDirectory1;
+using Mono.Upnp.Dcp.MediaServer1.ContentDirectory1.AV;
 
 using Banshee.Base;
 using Banshee.Sources.Gui;
@@ -57,8 +59,8 @@ namespace Banshee.UPnPClient
 
             client.Browse(Mono.Upnp.Dcp.MediaServer1.MediaServer.DeviceType);
         }
-		
-		public void Dispose ()
+    
+        public void Dispose ()
         {
             if (container != null)
             {
@@ -75,20 +77,79 @@ namespace Banshee.UPnPClient
             Hyena.Log.Debug ("UPnPService.DeviceAdded (" + e.Device.ToString() + ") (" + e.Device.Type + ")");
             Device device = e.Device.GetDevice();
             
-            RemoteContentDirectory contentDirectory = null;
+            ContentDirectoryController contentDirectory = null;
             
             foreach (Service service in device.Services) {
                 Hyena.Log.Debug ("UPnPService \"" + device.FriendlyName + "\" Implements " + service.Type);
-                if (service.Type.Equals(Mono.Upnp.Dcp.MediaServer1.ContentDirectory1.ContentDirectory.ServiceType))
-                    contentDirectory = new RemoteContentDirectory(new ContentDirectoryController(service.GetController()));
+                if (service.Type.Equals (Mono.Upnp.Dcp.MediaServer1.ContentDirectory1.ContentDirectory.ServiceType))
+                    contentDirectory = new ContentDirectoryController (service.GetController());
             }
 
             if (contentDirectory != null)
-                container.AddChildSource (new UPnPSource(device, contentDirectory));
+            {
+                UPnPSource source = new UPnPSource(device);
+                container.AddChildSource (source);
+                Parse(source, contentDirectory);
+            }
+        }
+
+
+        static void Parse (UPnPSource source, ContentDirectoryController contentDirectory)
+        {
+            RemoteContentDirectory remoteContentDirectory = new RemoteContentDirectory (contentDirectory);
+            List<MusicTrack> musicTracks = new List<MusicTrack>();
+            DateTime begin = DateTime.Now;
+            Container root = remoteContentDirectory.GetRootObject();
+            bool recursiveBrowse = !contentDirectory.CanSearch;
+
+            if (!recursiveBrowse) {
+                try {
+                    Hyena.Log.Debug ("Searchable, lets search");
+					foreach (var item in remoteContentDirectory.Search<MusicTrack>(root, visitor => visitor.VisitDerivedFrom("upnp:class", "object.item.audioItem.musicTrack"), new ResultsSettings())) {
+                        musicTracks.Add(item as MusicTrack);
+					}
+                } catch (Exception exception) {
+                    Hyena.Log.Exception (exception);
+                    recursiveBrowse = true;
+                }
+            }
+            if (recursiveBrowse) {
+                try {
+                    Hyena.Log.Debug ("Not searchable, lets recursive browse");
+                    ParseContainer (source, remoteContentDirectory, root, 0, musicTracks);
+                } catch (Exception exception) {
+                    Hyena.Log.Exception (exception);
+                }
+            }
+
+            source.AddTracks (musicTracks);
+            Hyena.Log.Debug ("Found all items on the service, took " + (DateTime.Now - begin).ToString());
+        }
+
+        static void ParseContainer (UPnPSource source, RemoteContentDirectory remoteContentDirectory, Container container, int depth, List<MusicTrack> musicTracks)
+        {
+            if (depth > 10 || (container.ChildCount != null && container.ChildCount == 0))
+                return;
+
+            foreach (var upnp_object in remoteContentDirectory.GetChildren<Mono.Upnp.Dcp.MediaServer1.ContentDirectory1.Object>(container)) {
+                if (upnp_object is Item) {
+                    Item item = upnp_object as Item;
+
+                    if (item.IsReference || item.Resources.Count == 0)
+                      continue;
+
+                    if (item is MusicTrack) {
+                        musicTracks.Add(item as MusicTrack);
+                    }
+                }
+                else if (upnp_object is Container) {
+                    ParseContainer (source, remoteContentDirectory, upnp_object as Container, depth + 1, musicTracks);
+                }
+            }
         }
-		
+    
         string IService.ServiceName {
             get { return "uPnP Client service"; }
         }
-	}
+  }
 }
diff --git a/src/Extensions/Banshee.UPnPClient/Banshee.UPnPClient/UPnPSource.cs b/src/Extensions/Banshee.UPnPClient/Banshee.UPnPClient/UPnPSource.cs
index ef73b7b..4bc5785 100644
--- a/src/Extensions/Banshee.UPnPClient/Banshee.UPnPClient/UPnPSource.cs
+++ b/src/Extensions/Banshee.UPnPClient/Banshee.UPnPClient/UPnPSource.cs
@@ -27,6 +27,7 @@
 //
 
 using System;
+using System.Collections.Generic;
 
 using Mono.Unix;
 using Mono.Addins;
@@ -51,46 +52,23 @@ namespace Banshee.UPnPClient
     public class UPnPSource : PrimarySource
     {
         const int sort_order = 190;
+        private Dictionary<string, UPnPTrackInfo> music_tracks;
 
-        public UPnPSource (Device device, RemoteContentDirectory contentDirectory) : base (Catalog.GetString ("Music Share"), device.FriendlyName, device.Udn, sort_order)
+        public UPnPSource (Device device) : base (Catalog.GetString ("Music Share"), device.FriendlyName, device.Udn, sort_order)
         {
             Hyena.Log.Information ("UPnPSource.Added(\"" + this.Name + "\", \"" + this.UniqueId + "\")");
 
             Properties.SetStringList ("Icon.Name", "computer", "network-server");
 
+            music_tracks = new Dictionary<string, UPnPTrackInfo>();
+
             // Remove tracks previously associated with this source, we do this to be sure they are non-existant before we refresh.
             PurgeTracks();
-
             AfterInitialized ();
-
-            try
-            {
-                Container root = contentDirectory.GetRootObject();
-                /*
-                if (root.IsSearchable)
-                {
-                    Hyena.Log.Debug("UPnPSource: " + this.UniqueId + " have searchable root");
-
-                    foreach (MusicTrack track in contentDirectory.Search<MusicTrack>(root, visitor => visitor.VisitAllResults(), new ResultsSettings()))
-                        AddTrack(track);
-                }
-                else
-                */
-                {
-                    Hyena.Log.Debug("UPnPSource: " + this.UniqueId + " does not contain a searchable root, need to recursive browse");
-
-                    ParseContainer(contentDirectory, root, 0);
-                }
-            }
-            catch (Exception exception)
-            {
-                Hyena.Log.DebugException(exception);
-            }
-
-            Hyena.Log.Information ("UPnPSource \"" + this.Name + "\", \"" + this.UniqueId + "\" parsed");
+            OnTracksRemoved ();
         }
 
-        ~UPnPSource()
+        ~UPnPSource ()
         {
             Dispose ();
         }
@@ -101,7 +79,7 @@ namespace Banshee.UPnPClient
             base.Dispose ();
         }
 
-        public void Disconnect()
+        public void Disconnect ()
         {
             Hyena.Log.Information ("UPnPSource.Disconnect(\"" + this.Name + "\", \"" + this.UniqueId + "\")");
 
@@ -124,41 +102,17 @@ namespace Banshee.UPnPClient
             get { return false; }
         }
 
-        private void ParseContainer(RemoteContentDirectory contentDirectory, Container container, int depth)
+        public void AddTracks (List<MusicTrack> tracks)
         {
-            if (depth > 10 || (container.ChildCount.HasValue && container.ChildCount == 0))
-                return;
-            
-            foreach (var item in contentDirectory.GetChildren<Mono.Upnp.Dcp.MediaServer1.ContentDirectory1.Object>(container))
-            {
-                if (item is AudioItem)
-                {
-                    if (item is MusicTrack)
-                        AddMusicTrack(item as MusicTrack);
-                    else
-                        AddAudioItem(item as AudioItem);
-                }
-                else if (item is Container)
-                    ParseContainer(contentDirectory, item as Container, depth + 1);
-            }
-        }
-
-        private void AddMusicTrack(MusicTrack basetrack)
-        {
-            if (basetrack.IsReference)
-                return;
+            foreach (var track in tracks) {
+                if (music_tracks.ContainsKey(track.Id))
+                    continue;
 
-			UPnPTrackInfo track = new UPnPTrackInfo (basetrack, this);
-            track.Save();
-        }
-
-        private void AddAudioItem(AudioItem basetrack)
-        {
-            if (basetrack.IsReference)
-                return;
+                UPnPTrackInfo track_info = new UPnPTrackInfo (track, this);
+                track_info.Save (false);
+            }
 
-            UPnPTrackInfo track = new UPnPTrackInfo (basetrack, this);
-            track.Save();
+            OnTracksAdded ();
         }
     }
 }



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