[banshee: 27/61] [InternetArchive] Load details sources async



commit bcb635a0dcf4155e0645d6b1ac556d9b5d006212
Author: Gabriel Burt <gabriel burt gmail com>
Date:   Mon Oct 12 16:48:51 2009 -0700

    [InternetArchive] Load details sources async

 .../Banshee.InternetArchive/Actions.cs             |    4 +-
 .../Banshee.InternetArchive/DetailsSource.cs       |   52 +++++++-
 .../DetailsSourceContents.cs                       |   50 ++++----
 .../Banshee.InternetArchive/Item.cs                |  131 ++++++++++++++++++++
 .../Banshee.InternetArchive/SearchSource.cs        |    4 +-
 .../InternetArchive/Details.cs                     |   82 +++---------
 src/Extensions/Banshee.InternetArchive/Makefile.am |    1 +
 .../Resources/DetailsSourceActiveUI.xml            |    3 +
 8 files changed, 233 insertions(+), 94 deletions(-)
---
diff --git a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Actions.cs b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Actions.cs
index b38363d..93b8df6 100644
--- a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Actions.cs
+++ b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Actions.cs
@@ -47,7 +47,7 @@ namespace Banshee.InternetArchive
                     if (item != null && item.Uri != null) {
                         string [] bits = item.Uri.AbsoluteUri.Split ('/');
                         string id = bits[bits.Length - 1];
-                        var src = new DetailsSource (item.TrackTitle, id);
+                        var src = new DetailsSource (id, item.TrackTitle);
                         source.AddChildSource (src);
                         Banshee.ServiceStack.ServiceManager.SourceManager.SetActiveSource (src);
                     }
@@ -56,7 +56,7 @@ namespace Banshee.InternetArchive
                     string uri = null;
                     var src = ActiveSource as DetailsSource;
                     if (src != null) {
-                        uri = src.Item.WebpageUrl;
+                        uri = src.Item.Details.WebpageUrl;
                     } else {
                         var item = source.TrackModel.FocusedItem;
                         if (item != null && item.Uri != null) {
diff --git a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/DetailsSource.cs b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/DetailsSource.cs
index 37e7bd9..35f5e13 100644
--- a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/DetailsSource.cs
+++ b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/DetailsSource.cs
@@ -53,25 +53,55 @@ using IA=InternetArchive;
 
 namespace Banshee.InternetArchive
 {
-    public class DetailsSource : Banshee.Sources.Source, ITrackModelSource, IDurationAggregator, IFileSizeAggregator
+    public class DetailsSource : Banshee.Sources.Source, ITrackModelSource, IDurationAggregator, IFileSizeAggregator, IUnmapableSource
     {
-        private IA.Details item;
+        private Item item;
         private MemoryTrackListModel track_model;
+        private DetailsSourceContents gui;
 
-        public IA.Details Item {
+        public Item Item {
             get { return item; }
         }
 
-        public DetailsSource (string name, string id) : base (name, name, 40, "internet-archive-" + id)
+        public DetailsSource (string id, string title) : this (Item.LoadOrCreate (id, title)) {}
+
+        public DetailsSource (Item item) : base (item.Title, item.Title, 40, "internet-archive-" + item.Id)
         {
-            item = IA.Details.LoadOrCreate (id, name);
+            this.item = item;
             track_model = new MemoryTrackListModel ();
             track_model.Reloaded += delegate { OnUpdated (); };
 
             Properties.SetString ("ActiveSourceUIResource", "DetailsSourceActiveUI.xml");
             Properties.SetString ("GtkActionPath", "/IaDetailsSourcePopup");
+            Properties.SetString ("UnmapSourceActionLabel", Catalog.GetString ("Close Item"));
+
+            gui = new DetailsSourceContents (this, item);
+            Properties.Set<Gtk.Widget> ("Nereid.SourceContents", gui);
 
-            Properties.Set<Gtk.Widget> ("Nereid.SourceContents", new DetailsSourceContents (this, item));
+            if (item.Details == null) {
+                SetStatus (Catalog.GetString ("Getting item details from the Internet Archive"), false, true, null);
+                ThreadAssist.SpawnFromMain (ThreadedLoad);
+            } else {
+                gui.UpdateDetails ();
+            }
+        }
+
+        private void ThreadedLoad ()
+        {
+            try {
+                item.LoadDetails ();
+                ThreadAssist.ProxyToMain (delegate {
+                    ClearMessages ();
+                    if (item.Details != null) {
+                        gui.UpdateDetails ();
+                    }
+                });
+            } catch (Exception e) {
+                ThreadAssist.ProxyToMain (delegate {
+                    SetStatus (Catalog.GetString ("Error getting item details from the Internet Archive"), true);
+                });
+                Hyena.Log.Exception ("Error loading IA item details", e);
+            }
         }
 
         public void Reload ()
@@ -145,6 +175,16 @@ namespace Banshee.InternetArchive
 
 #endregion
 
+        public bool CanUnmap { get { return true; } }
+        public bool ConfirmBeforeUnmap { get { return false; } }
+
+        public bool Unmap ()
+        {
+            item.Delete ();
+            Parent.RemoveChildSource (this);
+            return true;
+        }
+
         public override bool HasEditableTrackProperties {
             get { return false; }
         }
diff --git a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/DetailsSourceContents.cs b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/DetailsSourceContents.cs
index a49edbb..b568923 100644
--- a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/DetailsSourceContents.cs
+++ b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/DetailsSourceContents.cs
@@ -62,18 +62,22 @@ namespace Banshee.InternetArchive
     public class DetailsSourceContents : Gtk.HBox, Banshee.Sources.Gui.ISourceContents
     {
         private DetailsSource source;
-        IA.Details item;
+        private IA.Details details;
+        private Item item;
 
-        public DetailsSourceContents (DetailsSource source, IA.Details item)
+        public DetailsSourceContents (DetailsSource source, Item item)
         {
             this.source = source;
             this.item = item;
 
             Spacing = 6;
+        }
 
+        public void UpdateDetails ()
+        {
+            details = item.Details;
             BuildInfoBox ();
             BuildFilesBox ();
-
             ShowAll ();
         }
 
@@ -123,7 +127,7 @@ namespace Banshee.InternetArchive
             var desc_exp = CreateExpander (Catalog.GetString ("Description"));
 
             var desc = new Hyena.Widgets.WrapLabel () {
-                Markup = String.Format ("<small>{0}</small>", GLib.Markup.EscapeText (item.Description))
+                Markup = String.Format ("<small>{0}</small>", GLib.Markup.EscapeText (details.Description))
             };
 
             desc_exp.Child = desc;
@@ -140,42 +144,42 @@ namespace Banshee.InternetArchive
                 table.SetSizeRequest (a.Requisition.Width, a.Requisition.Height);
             };
 
-            AddToTable (table, Catalog.GetString ("Venue:"), item.Venue);
-            AddToTable (table, Catalog.GetString ("Location:"), item.Coverage);
-            if (item.DateCreated != DateTime.MinValue) {
-                AddToTable (table, Catalog.GetString ("Date:"), item.DateCreated);
+            AddToTable (table, Catalog.GetString ("Venue:"), details.Venue);
+            AddToTable (table, Catalog.GetString ("Location:"), details.Coverage);
+            if (details.DateCreated != DateTime.MinValue) {
+                AddToTable (table, Catalog.GetString ("Date:"), details.DateCreated);
             } else {
-                AddToTable (table, Catalog.GetString ("Year:"), item.Year);
+                AddToTable (table, Catalog.GetString ("Year:"), details.Year);
             }
-            AddToTable (table, Catalog.GetString ("Publisher:"), item.Publisher);
-            AddToTable (table, Catalog.GetString ("Subject:"), item.Subject);
+            AddToTable (table, Catalog.GetString ("Publisher:"), details.Publisher);
+            AddToTable (table, Catalog.GetString ("Subject:"), details.Subject);
 
             table.AddSeparator ();
 
-            AddToTable (table, Catalog.GetString ("Downloads, overall:"), item.DownloadsAllTime);
-            AddToTable (table, Catalog.GetString ("Downloads, past month:"), item.DownloadsLastMonth);
-            AddToTable (table, Catalog.GetString ("Downloads, past week:"), item.DownloadsLastWeek);
+            AddToTable (table, Catalog.GetString ("Downloads, overall:"), details.DownloadsAllTime);
+            AddToTable (table, Catalog.GetString ("Downloads, past month:"), details.DownloadsLastMonth);
+            AddToTable (table, Catalog.GetString ("Downloads, past week:"), details.DownloadsLastWeek);
 
             table.AddSeparator ();
 
-            AddToTable (table, Catalog.GetString ("Added:"),      item.DateAdded);
-            AddToTable (table, Catalog.GetString ("Added by:"),   item.AddedBy);
-            AddToTable (table, Catalog.GetString ("Source:"),     item.Source);
-            AddToTable (table, Catalog.GetString ("Recorded by:"),item.Taper);
-            AddToTable (table, Catalog.GetString ("Lineage:"),    item.Lineage);
-            AddToTable (table, Catalog.GetString ("Transferred by:"), item.Transferer);
+            AddToTable (table, Catalog.GetString ("Added:"),      details.DateAdded);
+            AddToTable (table, Catalog.GetString ("Added by:"),   details.AddedBy);
+            AddToTable (table, Catalog.GetString ("Source:"),     details.Source);
+            AddToTable (table, Catalog.GetString ("Recorded by:"),details.Taper);
+            AddToTable (table, Catalog.GetString ("Lineage:"),    details.Lineage);
+            AddToTable (table, Catalog.GetString ("Transferred by:"), details.Transferer);
 
             expander.Child = table;
 
             // Reviews
             Expander reviews = null;
-            if (item.NumReviews > 0) {
+            if (details.NumReviews > 0) {
                 reviews = CreateExpander (Catalog.GetString ("Reviews"));
                 var reviews_box = new VBox () { Spacing = 6 };
                 reviews.Child = reviews_box;
 
                 var sb = new System.Text.StringBuilder ();
-                foreach (var review in item.Reviews) {
+                foreach (var review in details.Reviews) {
                     var review_item = new Hyena.Widgets.WrapLabel ();
 
                     var title = review.Title;
@@ -279,7 +283,7 @@ namespace Banshee.InternetArchive
 
             string [] format_blacklist = new string [] { "zip", "m3u", "metadata", "fingerprint", "checksums", "text" };
             var formats = new List<string> ();
-            foreach (var f in item.Files) {
+            foreach (var f in details.Files) {
                 var track = new TrackInfo () {
                     Uri         = new SafeUri (f.Location),
                     FileSize    = f.Size,
diff --git a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Item.cs b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Item.cs
new file mode 100644
index 0000000..8c2fd40
--- /dev/null
+++ b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Item.cs
@@ -0,0 +1,131 @@
+//
+// Item.cs
+//
+// Authors:
+//   Gabriel Burt <gburt novell com>
+//
+// Copyright (C) 2009 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.Collections.Generic;
+using System.Linq;
+
+using Mono.Unix;
+
+using Hyena.Collections;
+using Hyena.Data.Sqlite;
+
+using Banshee.Base;
+using Banshee.Collection;
+using Banshee.Collection.Database;
+using Banshee.Configuration;
+using Banshee.Database;
+using Banshee.Gui;
+using Banshee.Library;
+using Banshee.MediaEngine;
+using Banshee.PlaybackController;
+using Banshee.Playlist;
+using Banshee.Preferences;
+using Banshee.ServiceStack;
+using Banshee.Sources;
+
+using IA=InternetArchive;
+
+namespace Banshee.InternetArchive
+{
+    public class Item
+    {
+        public static Item LoadOrCreate (string id, string title)
+        {
+            var item = Provider.FetchFirstMatching ("ID = ?", id);
+            if (item == null) {
+                item = new Item (id, title);
+                Provider.Save (item);
+            }
+
+            return item;
+        }
+
+        public static IEnumerable<Item> LoadAll ()
+        {
+            return Provider.FetchAll ();
+        }
+
+        [DatabaseColumn("ItemId", Constraints = DatabaseColumnConstraints.PrimaryKey)]
+        private int DbId { get; set; }
+
+        [DatabaseColumn("DetailsJson")]
+        private string DetailsJson { get; set; }
+
+        [DatabaseColumn("ID")]
+        public string Id { get; private set; }
+
+        [DatabaseColumn("Title")]
+        public string Title { get; private set; }
+
+        public IA.Details Details { get; private set; }
+
+        public Item () {}
+
+        private Item (string id, string title)
+        {
+            Id = id;
+            Title = title;
+        }
+
+        public void Delete ()
+        {
+            Provider.Delete (this);
+        }
+
+        public void LoadDetails ()
+        {
+            if (Details == null) {
+                Details = new IA.Details (Id, DetailsJson);
+            }
+        }
+
+        private static SqliteModelProvider<Item> provider;
+        private static SqliteModelProvider<Item> Provider {
+            get {
+                if (provider == null) {
+                    provider = new SqliteModelProvider<Item> (ServiceManager.DbConnection, "IaItems", false);
+                }
+                return provider;
+            }
+        }
+
+        static Item () {
+            var db = ServiceManager.DbConnection;
+            if (!db.TableExists ("IaItems")) {
+                db.Execute (@"
+                    CREATE TABLE IaItems (
+                        ItemID         INTEGER PRIMARY KEY,
+                        ID             TEXT UNIQUE NOT NULL,
+                        Title          TEXT NOT NULL,
+                        DetailsJson    TEXT)"
+                );
+            }
+        }
+    }
+}
diff --git a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/SearchSource.cs b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/SearchSource.cs
index 93f3b53..77b6c2c 100644
--- a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/SearchSource.cs
+++ b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/SearchSource.cs
@@ -130,8 +130,8 @@ namespace Banshee.InternetArchive
                 Properties.Set<Gtk.Widget> ("Nereid.SourceContents.HeaderWidget", header_widget);
             }
 
-            if (ApplicationContext.CommandLine.Contains ("internet-archive-offline-mode")) {
-                AddChildSource (new DetailsSource ("Local H Live at Levis L2 Lazer Rock Stage [Summerfest 1999] on 1999-06-24", "banshee-internet-archive-offline-mode"));
+            foreach (var item in Item.LoadAll ()) {
+                AddChildSource (new DetailsSource (item));
             }
         }
 
diff --git a/src/Extensions/Banshee.InternetArchive/InternetArchive/Details.cs b/src/Extensions/Banshee.InternetArchive/InternetArchive/Details.cs
index ff831b0..0457643 100644
--- a/src/Extensions/Banshee.InternetArchive/InternetArchive/Details.cs
+++ b/src/Extensions/Banshee.InternetArchive/InternetArchive/Details.cs
@@ -40,47 +40,20 @@ namespace InternetArchive
 {
     public class Details
     {
-        JsonObject details;
-        JsonObject metadata, misc, item, review_info;
-        JsonArray reviews;
+        private string id, json;
+        private JsonObject details;
+        private JsonObject metadata, misc, item, review_info;
+        private JsonArray reviews;
 
-        public static Details LoadOrCreate (string id, string title)
-        {
-            /*var item = Provider.LoadFromId (id);
-            if (item != null)
-                return item;*/
-
-            return new Details (id, title);
-        }
+        public Details (string id) : this (id, null) {}
 
-        private Details (string id, string title)
+        public Details (string id, string json)
         {
-            Id = id;
-            Title = title;
-            //Provider.Save ();
-
+            this.id = id;
+            this.json = json;
             LoadDetails ();
         }
 
-#region Properties stored in database columns
-
-        //[DatabaseColumn (PrimaryKey=true)]
-        public long DbId { get; set; }
-
-        //[DatabaseColumn]
-        public string Id { get; set; }
-
-        //[DatabaseColumn]
-        public string Title { get; private set; }
-
-        //[DatabaseColumn]
-        public string JsonDetails { get; set; }
-
-        //[DatabaseColumn]
-        public bool IsHidden { get; set; }
-
-#endregion
-
 #region Properties from the JSON object
 
         public string Description {
@@ -195,36 +168,25 @@ namespace InternetArchive
         }
 
         public string WebpageUrl {
-            get { return String.Format ("http://www.archive.org/details/{0}";, Id); }
+            get { return String.Format ("http://www.archive.org/details/{0}";, id); }
         }
 
 #endregion
 
-        private bool LoadDetails ()
+        private void LoadDetails ()
         {
-            // First see if we already have the Hyena.JsonObject parsed
-            if (details != null) {
-                return true;
-            }
-
-            // If not, see if we have a copy in the database, and parse that
-            /*if (JsonDetails != null) {
-                details = new Hyena.Json.Deserializer (JsonDetails).Deserialize () as JsonObject;
-                return true;
-            }*/
-
-
-            // Hack to load JSON data from local file instead of from archive.org
-            if (Id == "banshee-internet-archive-offline-mode") {
-                details = new Hyena.Json.Deserializer (System.IO.File.ReadAllText ("item2.json")).Deserialize () as JsonObject;
+            if (json != null) {
+                // use the passed in json
+            } else if (id == "banshee-internet-archive-offline-mode") {
+                // Hack to load JSON data from local file instead of from archive.org
+                json = System.IO.File.ReadAllText ("item2.json");
             } else {
-                // We don't; grab it from archive.org and parse it
-                string json_str = GetDetails (Id);
+                // get it from archive.org
+                json = FetchDetails (id);
+            }
 
-                if (json_str != null) {
-                    details = new Hyena.Json.Deserializer (json_str).Deserialize () as JsonObject;
-                    JsonDetails = json_str;
-                }
+            if (json != null) {
+                details = new Hyena.Json.Deserializer (json).Deserialize () as JsonObject;
             }
 
             if (details != null) {
@@ -237,11 +199,9 @@ namespace InternetArchive
                     review_info = r.Get<JsonObject> ("info");
                 }
             }
-
-            return false;
         }
 
-        private static string GetDetails (string id)
+        private static string FetchDetails (string id)
         {
             HttpWebResponse response = null;
             string url = String.Format ("http://www.archive.org/details/{0}&output=json";, id);
diff --git a/src/Extensions/Banshee.InternetArchive/Makefile.am b/src/Extensions/Banshee.InternetArchive/Makefile.am
index 3aca9d4..1517be5 100644
--- a/src/Extensions/Banshee.InternetArchive/Makefile.am
+++ b/src/Extensions/Banshee.InternetArchive/Makefile.am
@@ -8,6 +8,7 @@ SOURCES = \
 	Banshee.InternetArchive/DetailsSource.cs \
 	Banshee.InternetArchive/DetailsSourceContents.cs \
 	Banshee.InternetArchive/HeaderFilters.cs \
+	Banshee.InternetArchive/Item.cs \
 	Banshee.InternetArchive/SearchSource.cs \
 	InternetArchive/Collection.cs \
 	InternetArchive/Details.cs \
diff --git a/src/Extensions/Banshee.InternetArchive/Resources/DetailsSourceActiveUI.xml b/src/Extensions/Banshee.InternetArchive/Resources/DetailsSourceActiveUI.xml
index 33b5ddd..f1206c5 100644
--- a/src/Extensions/Banshee.InternetArchive/Resources/DetailsSourceActiveUI.xml
+++ b/src/Extensions/Banshee.InternetArchive/Resources/DetailsSourceActiveUI.xml
@@ -6,7 +6,10 @@
   </toolbar>
 
   <popup action="IaDetailsSourcePopup">
+    <menuitem action="OpenItemWebsite" />
     <menuitem action="VisitInternetArchive" />
+    <separator />
+    <menuitem action="UnmapSourceAction"/>
   </popup>
 
   <popup name="TrackContextMenu" action="TrackContextMenuAction">



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