[banshee: 20/61] [InternetArchive] Much improved item source



commit 4ae1d746facc7c5b592fd91deba4a654f17b9510
Author: Gabriel Burt <gabriel burt gmail com>
Date:   Thu Oct 8 21:23:17 2009 -0700

    [InternetArchive] Much improved item source
    
    The item source shows much more data is and much closer to polished.  It
    shows all the attributes of the item, and the reviews.  Also, add a
    Visit Archive.org action to the main IA source.

 .../Banshee.InternetArchive/Actions.cs             |    6 +
 .../Banshee.InternetArchive/File.cs                |   38 +---
 .../Banshee.InternetArchive/Item.cs                |  127 ++++++++++-
 .../Banshee.InternetArchive/ItemSource.cs          |    2 +-
 .../Banshee.InternetArchive/ItemSourceContents.cs  |  226 ++++++++++++++------
 .../Banshee.InternetArchive/Review.cs              |   75 +++++++
 .../Banshee.InternetArchive/Source.cs              |    6 +
 .../InternetArchive/Item.cs                        |    8 +-
 .../InternetArchive/JsonItem.cs                    |   32 +++-
 .../InternetArchive/Search.cs                      |    8 +-
 src/Extensions/Banshee.InternetArchive/Makefile.am |    1 +
 .../Resources/ActiveSourceUI.xml                   |    3 +-
 12 files changed, 410 insertions(+), 122 deletions(-)
---
diff --git a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Actions.cs b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Actions.cs
index 7d1feb6..7f0aa90 100644
--- a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Actions.cs
+++ b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Actions.cs
@@ -60,6 +60,12 @@ namespace Banshee.InternetArchive
                 })
             );
 
+            AddImportant (
+                new ActionEntry ("VisitInternetArchive", Stock.JumpTo, Catalog.GetString ("Visit Archive.org"), null, null, (o, a) => {
+                    Banshee.Web.Browser.Open ("http://archive.org";);
+                })
+            );
+
             Register ();
         }
     }
diff --git a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/File.cs b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/File.cs
index 3f9182f..6749412 100644
--- a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/File.cs
+++ b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/File.cs
@@ -50,46 +50,16 @@ namespace Banshee.InternetArchive
             this.location_root = location_root;
         }
 
-        private long GetLong (string i)
-        {
-            return i == null ? 0 : Int64.Parse (i);
-        }
-
-        private int GetInt (string i)
-        {
-            return i == null ? 0 : Int32.Parse (i);
-        }
-
-        private TimeSpan GetTimeSpan (string i)
-        {
-            if (i == null)
-                return TimeSpan.Zero;
-
-            int h = 0, m = 0, s = 0;
-            var bits = i.Split (':');
-
-            if (bits.Length > 0)
-                s = Int32.Parse (bits[bits.Length - 1]);
-
-            if (bits.Length > 1)
-                m = Int32.Parse (bits[bits.Length - 2]);
-
-            if (bits.Length > 2)
-                h = Int32.Parse (bits[bits.Length - 3]);
-
-            return new TimeSpan (h, m, s);
-        }
-
         public string Location {
             get { return location_root + file.Get<string> ("location"); }
         }
 
         public long Size {
-            get { return GetLong (file.Get<string> ("size")); }
+            get { return file.Get<long> ("size"); }
         }
 
         public int Track {
-            get { return GetInt (file.Get<string> ("track")); }
+            get { return file.Get<int> ("track"); }
         }
 
         public string Creator {
@@ -101,7 +71,7 @@ namespace Banshee.InternetArchive
         }
 
         public int BitRate {
-            get { return GetInt (file.Get<string> ("bitrate")); }
+            get { return file.Get<int> ("bitrate"); }
         }
 
         public string Format {
@@ -109,7 +79,7 @@ namespace Banshee.InternetArchive
         }
 
         public TimeSpan Length {
-            get { return GetTimeSpan (file.Get<string> ("length")); }
+            get { return file.Get<TimeSpan> ("length"); }
         }
     }
 }
diff --git a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Item.cs b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Item.cs
index d869bf8..7afe6e0 100644
--- a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Item.cs
+++ b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Item.cs
@@ -42,21 +42,24 @@ namespace Banshee.InternetArchive
     public class Item
     {
         JsonObject details;
-        JsonObject metadata;
+        JsonObject metadata, misc, item, review_info;
+        JsonArray reviews;
 
-        public static Item LoadOrCreate (string id)
+        public static Item LoadOrCreate (string id, string title)
         {
             /*var item = Provider.LoadFromId (id);
             if (item != null)
                 return item;*/
 
-            return new Item (id);
+            return new Item (id, title);
         }
 
-        private Item (string id)
+        private Item (string id, string title)
         {
             Id = id;
+            Title = title;
             //Provider.Save ();
+
             LoadDetails ();
         }
 
@@ -69,6 +72,9 @@ namespace Banshee.InternetArchive
         public string Id { get; set; }
 
         //[DatabaseColumn]
+        public string Title { get; private set; }
+
+        //[DatabaseColumn]
         public string JsonDetails { get; set; }
 
         //[DatabaseColumn]
@@ -78,20 +84,85 @@ namespace Banshee.InternetArchive
 
 #region Properties from the JSON object
 
-        public string Title {
-            get { return metadata.GetJoined ("title", System.Environment.NewLine); }
-        }
-
         public string Description {
             get { return metadata.GetJoined ("description", System.Environment.NewLine); }
         }
 
         public string Creator {
-            get { return metadata.Get<string> ("creator"); }
+            get { return metadata.GetJoined ("creator", ", "); }
+        }
+
+        public string Publisher {
+            get { return metadata.GetJoined ("publisher", ", "); }
+        }
+
+        public string Year {
+            get { return metadata.GetJoined ("year", ", "); }
+        }
+
+        public string Subject {
+            get { return metadata.GetJoined ("subject", ", "); }
+        }
+
+        public string Source {
+            get { return metadata.GetJoined ("source", ", "); }
+        }
+
+        public string Taper {
+            get { return metadata.GetJoined ("taper", ", "); }
+        }
+
+        public string Lineage {
+            get { return metadata.GetJoined ("lineage", ", "); }
+        }
+
+        public string Transferer {
+            get { return metadata.GetJoined ("transferer", ", "); }
+        }
+
+        public DateTime DateAdded {
+            get { return GetMetadataDate ("addeddate"); }
+        }
+
+        public string AddedBy {
+            get { return metadata.GetJoined ("adder", ", "); }
+        }
+
+        public string Venue {
+            get { return metadata.GetJoined ("venue", ", "); }
+        }
+
+        public string Coverage {
+            get { return metadata.GetJoined ("coverage", ", "); }
+        }
+
+        public string ImageUrl {
+            get { return misc.Get<string> ("image"); }
+        }
+
+        public long DownloadsAllTime {
+            get { return (int)item.Get<double> ("downloads"); }
+        }
+
+        public long DownloadsLastMonth {
+            get { return (int)item.Get<double> ("month"); }
+        }
+
+        public long DownloadsLastWeek {
+            get { return (int)item.Get<double> ("week"); }
         }
 
         public DateTime DateCreated {
-            get { return DateTime.Parse (metadata.Get<string> ("date")); }
+            get { return GetMetadataDate ("date"); }
+        }
+
+        private DateTime GetMetadataDate (string key)
+        {
+            DateTime ret;
+            if (DateTime.TryParse (metadata.GetJoined (key, null), out ret))
+                return ret;
+            else
+                return DateTime.MinValue;
         }
 
         public IEnumerable<File> Files {
@@ -104,6 +175,26 @@ namespace Banshee.InternetArchive
             }
         }
 
+        public IEnumerable<Review> Reviews {
+            get {
+                if (reviews == null) {
+                    yield break;
+                }
+
+                foreach (JsonObject review in reviews) {
+                    yield return new Review (review);
+                }
+            }
+        }
+
+        public double AvgRating {
+            get { return review_info.Get<double> ("avg_rating"); }
+        }
+
+        public int NumReviews {
+            get { return review_info.Get<int> ("num_reviews"); }
+        }
+
 #endregion
 
         private bool LoadDetails ()
@@ -121,7 +212,16 @@ namespace Banshee.InternetArchive
 
 
             /*details = new Hyena.Json.Deserializer (System.IO.File.ReadAllText ("item.json")).Deserialize () as JsonObject;
+            details.Dump ();
             metadata = details["metadata"] as JsonObject;
+            misc = details["misc"] as JsonObject;
+            item = details["item"] as JsonObject;
+            var r = details["reviews"] as JsonObject;
+            if (r != null) {
+                reviews = r["reviews"] as JsonArray;
+                review_info = r["info"] as JsonObject;
+            }
+
             return details != null;*/
             
             // We don't; grab it from archive.org and parse it
@@ -130,6 +230,13 @@ namespace Banshee.InternetArchive
             if (json_str != null) {
                 details = new Hyena.Json.Deserializer (json_str).Deserialize () as JsonObject;
                 metadata = details["metadata"] as JsonObject;
+                misc = details["misc"] as JsonObject;
+                item = details["item"] as JsonObject;
+                var r = details["reviews"] as JsonObject;
+                if (r != null) {
+                    reviews = r["reviews"] as JsonArray;
+                    review_info = r["info"] as JsonObject;
+                }
 
                 if (details != null) {
                     JsonDetails = json_str;
diff --git a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/ItemSource.cs b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/ItemSource.cs
index 8d685d1..39232cf 100644
--- a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/ItemSource.cs
+++ b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/ItemSource.cs
@@ -60,7 +60,7 @@ namespace Banshee.InternetArchive
 
         public ItemSource (string name, string id) : base (name, name, 40, "internet-archive-" + id)
         {
-            item = Item.LoadOrCreate (id);
+            item = Item.LoadOrCreate (id, name);
             track_model = new MemoryTrackListModel ();
             track_model.Reloaded += delegate { OnUpdated (); };
 
diff --git a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/ItemSourceContents.cs b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/ItemSourceContents.cs
index 7dfa6db..dd19ec3 100644
--- a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/ItemSourceContents.cs
+++ b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/ItemSourceContents.cs
@@ -95,11 +95,23 @@ namespace Banshee.InternetArchive
 
 #endregion
 
+        private List<Expander> expanders = new List<Expander> ();
+        private Expander CreateExpander (string label)
+        {
+            var expander = new Expander (label) {
+                Expanded = true
+            };
+
+            expanders.Add (expander);
+
+            return expander;
+        }
+
         private void BuildInfoBox ()
         {
             var frame = new Hyena.Widgets.RoundedFrame ();
             var vbox = new VBox ();
-            vbox.Spacing = 6;
+            vbox.Spacing = 0;
 
             // Title
             /*var title = new Label () {
@@ -108,53 +120,137 @@ namespace Banshee.InternetArchive
             };*/
 
             // Description
+            var desc_exp = CreateExpander (Catalog.GetString ("Description"));
+
             var desc = new Hyena.Widgets.WrapLabel () {
-                Markup = item.Description
+                Markup = String.Format ("<small>{0}</small>", GLib.Markup.EscapeText (item.Description))
             };
 
-            //var expander = new Expander (Catalog.GetString ("Details"));
-            // A table w/ this info, inside the expander?
-            // Notes / DateCreated / venue / publisher / source / taper / lineage
+            desc_exp.Child = desc;
 
-            //var desc_sw = new Gtk.ScrolledWindow ();
-            //desc_sw.AddWithViewport (desc);
+            // Details
+            var expander = CreateExpander (Catalog.GetString ("Details"));
+            var table = new Banshee.Gui.TrackEditor.StatisticsPage () {
+                ShadowType = ShadowType.None,
+                BorderWidth = 0
+            };
 
-            // Reviews
-            var reviews = new Label () {
-                Xalign = 0f,
-                Markup = String.Format ("<big><b>{0}</b></big>", GLib.Markup.EscapeText (Catalog.GetString ("Reviews")))
+            // Keep the table from needing to vertically scroll
+            table.Child.SizeRequested += (o, a) => {
+                table.SetSizeRequest (a.Requisition.Width, a.Requisition.Height);
             };
 
-            //vbox.PackStart (title,   false, false, 0);
-            //vbox.PackStart (desc_sw, true,  true,  0);
-            vbox.PackStart (desc, true,  true,  0);
-            vbox.PackStart (reviews, false, false, 0);
-            frame.Child = vbox;
+            AddToTable (table, Catalog.GetString ("Venue:"), item.Venue);
+            AddToTable (table, Catalog.GetString ("Coverage:"), item.Coverage);
+            if (item.DateCreated != DateTime.MinValue) {
+                AddToTable (table, Catalog.GetString ("Created:"), item.DateCreated);
+            } else {
+                AddToTable (table, Catalog.GetString ("Year:"), item.Year);
+            }
+            AddToTable (table, Catalog.GetString ("Publisher:"), item.Publisher);
+            AddToTable (table, Catalog.GetString ("Subject:"), item.Subject);
+
+            table.AddSeparator ();
+
+            AddToTable (table, Catalog.GetString ("Downloads (overall):"), item.DownloadsAllTime);
+            AddToTable (table, Catalog.GetString ("Downloads (last month):"), item.DownloadsLastMonth);
+            AddToTable (table, Catalog.GetString ("Downloads (last week):"), item.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 ("Taper:"), item.Taper);
+            AddToTable (table, Catalog.GetString ("Lineage:"), item.Lineage);
+            AddToTable (table, Catalog.GetString ("Transferer:"), item.Transferer);
+
+            expander.Child = table;
+
+            // Reviews
+            Expander reviews = null;
+            if (item.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) {
+                    var review_item = new Hyena.Widgets.WrapLabel ();
+
+                    var title = review.Title;
+                    if (title != null) {
+                        sb.AppendFormat ("<small><b>{0}</b> ({1:0.0})</small>", GLib.Markup.EscapeText (title), review.Stars);
+                    }
+
+                    var body = review.Body;
+                    if (body != null) {
+                        if (title != null) {
+                            sb.Append ("\n");
+                        }
+
+                        body = body.Replace ("\r\n", "\n");
+                        body = body.Replace ("\n\n", "\n");
+                        sb.AppendFormat ("<small>{0}</small>", GLib.Markup.EscapeText (body));
+                    }
+
+                    review_item.Markup = sb.ToString ();
+                    sb.Length = 0;
+
+                    reviews_box.PackStart (review_item, false, false, 0);
+                }
+            }
+
+            // Packing
+            vbox.PackStart (desc_exp, true, true,  0);
+            vbox.PackStart (new HSeparator (), false, false,  6);
+            vbox.PackStart (expander, true, true,  0);
+            vbox.PackStart (new HSeparator (), false, false,  6);
+            if (reviews != null) {
+                vbox.PackStart (reviews, true, true, 0);
+            }
+
+            var vbox2 = new VBox ();
+            vbox2.PackStart (vbox, false, false, 0);
+
+            var sw = new Gtk.ScrolledWindow () { ShadowType = ShadowType.None };
+            sw.AddWithViewport (vbox2);
+            (sw.Child as Viewport).ShadowType = ShadowType.None;
+            frame.Child = sw;
+            frame.ShowAll ();
+
+            StyleSet += delegate {
+                sw.Child.ModifyBg (StateType.Normal, Style.Base (StateType.Normal));
+                sw.Child.ModifyFg (StateType.Normal, Style.Text (StateType.Normal));
+            };
 
             PackStart (frame, true, true, 0);
         }
 
+        private void AddToTable (Banshee.Gui.TrackEditor.StatisticsPage table, string label, object val)
+        {
+            if (val != null) {
+                if (val is long) {
+                    table.AddItem (label, ((long)val).ToString ("N0"));
+                } else if (val is DateTime) {
+                    var dt = (DateTime)val;
+                    if (dt != DateTime.MinValue) {
+                        var str = dt.TimeOfDay == TimeSpan.Zero
+                            ? dt.ToShortDateString ()
+                            : dt.ToString ("g");
+                        table.AddItem (label, str);
+                    }
+                } else {
+                    table.AddItem (label, val.ToString ());
+                }
+            }
+        }
+
         private void BuildFilesBox ()
         {
             var vbox = new VBox ();
             vbox.Spacing = 6;
 
-            var format_list = new Hyena.Data.Gui.ListView<string> () {
-                HeaderVisible = false
-            };
-
-            format_list.SizeRequested += (o, a) => {
-                //a.Requisition.Height += (format_list.Model.Count * format_list.RowHeight);
-                var new_req = new Requisition () {
-                    Width = a.Requisition.Width,
-                    Height = a.Requisition.Height + (format_list.Model.Count * format_list.RowHeight)
-                };
-                a.Requisition = new_req;
-            };
-
-            var format_cols = new ColumnController ();
-            format_cols.Add (new Column ("format", new ColumnCellText (null, true), 1.0));
-
             var file_list = new BaseTrackListView () {
                 HeaderVisible = true,
                 IsEverReorderable = false
@@ -179,10 +275,10 @@ namespace Banshee.InternetArchive
             var file_sw = new Gtk.ScrolledWindow ();
             file_sw.Child = file_list;
 
-            var format_model = new MemoryListModel<string> ();
             var files = new List<TrackInfo> ();
 
             string [] format_blacklist = new string [] { "zip", "m3u", "metadata", "fingerprint", "checksums", "text" };
+            var formats = new List<string> ();
             foreach (var f in item.Files) {
                 var track = new TrackInfo () {
                     Uri         = new SafeUri (f.Location),
@@ -197,9 +293,9 @@ namespace Banshee.InternetArchive
 
                 files.Add (track);
 
-                if (format_model.IndexOf (f.Format) == -1) {
+                if (f.Format != null && !formats.Contains (f.Format)) {
                     if (!format_blacklist.Any (fmt => f.Format.ToLower ().Contains (fmt))) {
-                        format_model.Add (f.Format);
+                        formats.Add (f.Format);
                     }
                 }
             }
@@ -216,28 +312,30 @@ namespace Banshee.InternetArchive
             // Make these columns snugly fix their data
             (columns.TrackColumn.GetCell (0) as ColumnCellText).SetMinMaxStrings (files.Max (f => f.TrackNumber));
             (columns.FileSizeColumn.GetCell (0) as ColumnCellText).SetMinMaxStrings (files.Max (f => f.FileSize));
-            (columns.FileSizeColumn.GetCell (0) as ColumnCellText).Expand = false;
+            //(columns.FileSizeColumn.GetCell (0) as ColumnCellText).Expand = false;
             (columns.DurationColumn.GetCell (0) as ColumnCellText).SetMinMaxStrings (files.Max (f => f.Duration));
 
             string max_title = "";
             var sorted_by_title = files.OrderBy (f => f.TrackTitle == null ? 0 : f.TrackTitle.Length).ToList ();
-            //var nine_tenths = sorted_by_title[(int)Math.Floor (.90 * sorted_by_title.Count)].TrackTitle;
+            var nine_tenths = sorted_by_title[(int)Math.Floor (.90 * sorted_by_title.Count)].TrackTitle;
             var max = sorted_by_title[sorted_by_title.Count - 1].TrackTitle;
-            //max_title = max.Length >= 2.0 * nine_tenths.Length ? nine_tenths : max;
-            max_title = max;//max.Length >= 2.0 * nine_tenths.Length ? nine_tenths : max;
-            (columns.TitleColumn.GetCell (0) as ColumnCellText).SetMinMaxStrings (sorted_by_title[0].TrackTitle, max_title);
+            max_title = ((double)max.Length >= (double)(2.0 * (double)nine_tenths.Length)) ? nine_tenths : max;
+            (columns.TitleColumn.GetCell (0) as ColumnCellText).SetMinMaxStrings (max_title);
 
             file_list.ColumnController = file_columns;
-            format_list.ColumnController = format_cols;
             file_list.SetModel (files_model);
-            format_list.SetModel (format_model);
 
-            format_list.SelectionProxy.Changed += (o, a) => {
+            var format_list = ComboBox.NewText ();
+            foreach (var fmt in formats) {
+                format_list.AppendText (fmt);
+            }
+
+            format_list.Changed += (o, a) => {
                 files_model.Clear ();
 
-                var selected_formats = new ModelSelection<string> (format_model, format_list.Selection);
+                var selected_fmt = format_list.ActiveText;
                 foreach (var track in files) {
-                    if (selected_formats.Contains (track.MimeType)) {
+                    if (track.MimeType == selected_fmt) {
                         files_model.Add (track);
                     }
                 }
@@ -245,34 +343,26 @@ namespace Banshee.InternetArchive
                 files_model.Reload ();
             };
 
-            if (format_model.IndexOf ("VBR MP3") != -1) {
-                format_list.Selection.Select (format_model.IndexOf ("VBR MP3"));
+            if (formats.IndexOf ("VBR MP3") != -1) {
+                format_list.Active = formats.IndexOf ("VBR MP3");
             }
 
+            vbox.PackStart (file_sw, true, true, 0);
+            vbox.PackStart (format_list, false, false, 0);
+           
+            file_list.SizeAllocated += (o, a) => {
+                int target_list_width = file_list.MaxWidth;
+                if (file_sw.VScrollbar != null && file_sw.VScrollbar.IsMapped) {
+                    target_list_width += file_sw.VScrollbar.Allocation.Width + 2;
+                }
 
-            // Action buttons
-            var button = new Button ("Add to Library") {
-                Relief = ReliefStyle.None
+                if (a.Allocation.Width != target_list_width) {
+                    file_sw.SetSizeRequest (target_list_width, -1);
+                }
             };
 
-            /*var menu = new Menu ();
-            menu.Append (new MenuItem ("Add to Music Library"));
-            menu.Append (new MenuItem ("Add to Video Library"));
-            menu.Append (new MenuItem ("Add to Podcast Library"));
-            menu.ShowAll ();
-
-            var add_to_library = new MenuButton (button, menu, true);*/
-            //var action_frame = new RoundedFrame ();
-            var action_box = new HBox () { Spacing = 6 };
-            action_box.PackStart (button, false, false, 0);
-            //action_frame.Add (action_box);
-            action_box.ShowAll ();
-
-            vbox.PackStart (format_list, false, false, 0);
-            vbox.PackStart (file_sw,   true,  true,  0);
-            //vbox.PackStart (action_box, false, false, 0);
-
-            PackStart (vbox, true, true, 0);
+            //PackStart (vbox, true, true, 0);
+            PackStart (vbox, false, false, 0);
         }
     }
 }
diff --git a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Review.cs b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Review.cs
new file mode 100644
index 0000000..2157666
--- /dev/null
+++ b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Review.cs
@@ -0,0 +1,75 @@
+//
+// Review.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.Json;
+
+using InternetArchive;
+using IA=InternetArchive;
+
+namespace Banshee.InternetArchive
+{
+    public class Review
+    {
+        JsonObject review;
+
+        public Review (JsonObject review)
+        {
+            this.review = review;
+        }
+
+        public long Id {
+            get { return (long) review.Get<double> ("review_id"); }
+        }
+
+        public int Stars {
+            get { return (int) review.Get<double> ("stars"); }
+        }
+
+        public string Title {
+            get { return review.Get<string> ("reviewtitle"); }
+        }
+
+        public string Body {
+            get { return review.Get<string> ("reviewbody"); }
+        }
+
+        public string Reviewer {
+            get { return review.Get<string> ("reviewer"); }
+        }
+
+        public DateTime DateReviewed {
+            get { return DateTime.Parse (review.Get<string> ("reviewdate")); }
+        }
+    }
+}
diff --git a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Source.cs b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Source.cs
index a92aa37..2bee7e9 100644
--- a/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Source.cs
+++ b/src/Extensions/Banshee.InternetArchive/Banshee.InternetArchive/Source.cs
@@ -131,6 +131,8 @@ namespace Banshee.InternetArchive
                 header_widget.ShowAll ();
                 Properties.Set<Gtk.Widget> ("Nereid.SourceContents.HeaderWidget", header_widget);
             }
+
+            //AddChildSource (new ItemSource ("Fooz", "fooz"));
         }
 
         public override void Reload ()
@@ -153,6 +155,9 @@ namespace Banshee.InternetArchive
             try {
                 results = new IA.JsonResults (search.GetResults ());
                 total_results = results.TotalResults;
+            } catch (System.Net.WebException e) {
+                Hyena.Log.Exception ("Error searching the Internet Archive", e);
+                results = null;
             } catch (Exception e) {
                 Hyena.Log.Exception ("Error searching the Internet Archive", e);
                 results = null;
@@ -212,6 +217,7 @@ namespace Banshee.InternetArchive
                 }
             } else {
                 // TODO differentiate between various errors types (network, invalid search, etc)
+                //if (error.Status == WebExceptionStatus.Timeout) 
                 ThreadAssist.ProxyToMain (delegate {
                     SetStatus (Catalog.GetString ("Error searching the Internet Archive"), true);
                 });
diff --git a/src/Extensions/Banshee.InternetArchive/InternetArchive/Item.cs b/src/Extensions/Banshee.InternetArchive/InternetArchive/Item.cs
index a4ffa65..b8d6455 100644
--- a/src/Extensions/Banshee.InternetArchive/InternetArchive/Item.cs
+++ b/src/Extensions/Banshee.InternetArchive/InternetArchive/Item.cs
@@ -70,14 +70,16 @@ namespace InternetArchive
                 request.KeepAlive = Search.KeepAlive;
 
                 response = (HttpWebResponse) request.GetResponse ();
+
+                if (response.StatusCode != HttpStatusCode.OK) {
+                    return null;
+                }
+
                 using (Stream stream = response.GetResponseStream ()) {
                     using (StreamReader reader = new StreamReader (stream)) {
                         return reader.ReadToEnd ();
                     }
                 }
-            } catch (Exception e) {
-                Hyena.Log.Exception (String.Format ("Error searching {0}", url), e);
-                return null;
             } finally {
                 if (response != null) {
                     if (response.StatusCode != HttpStatusCode.OK) {
diff --git a/src/Extensions/Banshee.InternetArchive/InternetArchive/JsonItem.cs b/src/Extensions/Banshee.InternetArchive/InternetArchive/JsonItem.cs
index b908305..7d4d1c4 100644
--- a/src/Extensions/Banshee.InternetArchive/InternetArchive/JsonItem.cs
+++ b/src/Extensions/Banshee.InternetArchive/InternetArchive/JsonItem.cs
@@ -41,7 +41,37 @@ namespace InternetArchive
             object result;
             if (item.TryGetValue (key, out result)) {
                 try {
-                    return (T)result;
+                    if (result is T) {
+                        result = (T)result;
+                    } else if (result is string) {
+                        var type = typeof (T);
+                        string i = result as string;
+                        if (type == typeof(Int32)) {
+                            result = Int32.Parse (i);
+                        } else if (type == typeof(Int64)) {
+                            result = Int64.Parse (i);
+                        } else if (type == typeof(double)) {
+                            result = Double.Parse (i);
+                        } else if (type == typeof(TimeSpan)) {
+                            int h = 0, m = 0, s = 0;
+                            var bits = i.Split (':');
+
+                            if (bits.Length > 0)
+                                s = Int32.Parse (bits[bits.Length - 1]);
+
+                            if (bits.Length > 1)
+                                m = Int32.Parse (bits[bits.Length - 2]);
+
+                            if (bits.Length > 2)
+                                h = Int32.Parse (bits[bits.Length - 3]);
+
+                            result = new TimeSpan (h, m, s);
+                        }
+                    } else {
+                        result = default (T);
+                    }
+
+                    return (T) result;
                 } catch {
                     Console.WriteLine ("Couldn't cast {0} ({1}) as {2} for key {3}", result, result.GetType (), typeof(T), key);
                 }
diff --git a/src/Extensions/Banshee.InternetArchive/InternetArchive/Search.cs b/src/Extensions/Banshee.InternetArchive/InternetArchive/Search.cs
index 8c41db1..fff2967 100644
--- a/src/Extensions/Banshee.InternetArchive/InternetArchive/Search.cs
+++ b/src/Extensions/Banshee.InternetArchive/InternetArchive/Search.cs
@@ -108,14 +108,16 @@ namespace InternetArchive
                 request.KeepAlive = KeepAlive;
 
                 response = (HttpWebResponse) request.GetResponse ();
+
+                if (response.StatusCode != HttpStatusCode.OK) {
+                    return null;
+                }
+
                 using (Stream stream = response.GetResponseStream ()) {
                     using (StreamReader reader = new StreamReader (stream)) {
                         return reader.ReadToEnd ();
                     }
                 }
-            } catch (Exception e) {
-                Hyena.Log.Exception (String.Format ("Error searching {0}", url), e);
-                return null;
             } finally {
                 if (response != null) {
                     if (response.StatusCode != HttpStatusCode.OK) {
diff --git a/src/Extensions/Banshee.InternetArchive/Makefile.am b/src/Extensions/Banshee.InternetArchive/Makefile.am
index 6011294..9ed5b7f 100644
--- a/src/Extensions/Banshee.InternetArchive/Makefile.am
+++ b/src/Extensions/Banshee.InternetArchive/Makefile.am
@@ -21,6 +21,7 @@ SOURCES = \
 	Banshee.InternetArchive/ItemSource.cs \
 	Banshee.InternetArchive/ItemSourceContents.cs \
 	Banshee.InternetArchive/HeaderFilters.cs \
+	Banshee.InternetArchive/Review.cs \
 	Banshee.InternetArchive/Source.cs
 
 RESOURCES = \
diff --git a/src/Extensions/Banshee.InternetArchive/Resources/ActiveSourceUI.xml b/src/Extensions/Banshee.InternetArchive/Resources/ActiveSourceUI.xml
index d4d420a..5959c5a 100644
--- a/src/Extensions/Banshee.InternetArchive/Resources/ActiveSourceUI.xml
+++ b/src/Extensions/Banshee.InternetArchive/Resources/ActiveSourceUI.xml
@@ -1,8 +1,7 @@
 <ui>
   <toolbar name="HeaderToolbar">
     <placeholder name="SourceActions">
-        <!--<toolitem name="PodcastAdd" action="PodcastAddAction" />
-        <toolitem name="PodcastUpdateAll" action="PodcastUpdateAllAction" />-->
+        <toolitem action="VisitInternetArchive" />
     </placeholder>
   </toolbar>
 



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