[banshee] [MiroGuide] New podcast directory extension



commit 34f992b4fe8eb381fb2883d9e6adde217981dfd6
Author: Gabriel Burt <gabriel burt gmail com>
Date:   Tue Jul 13 17:16:20 2010 -0700

    [MiroGuide] New podcast directory extension
    
    Integrates with miroguide.com, a podcast directory website run by the
    non-profit Participatory Culture Foundation.  Embeds it using
    webkit/Ossifer in much the same way we embed the Amazon MP3 store.
    Includes hooks for seamlessly streaming episodes and
    subscribing to podcasts.

 Banshee.sln                                        |    7 +
 configure.ac                                       |    2 +
 data/addin-xml-strings.cs                          |    5 +
 .../Banshee.MiroGuide/Banshee.MiroGuide.addin.xml  |   23 +++
 .../Banshee.MiroGuide/Banshee.MiroGuide.csproj     |   96 ++++++++++
 .../Banshee.MiroGuide/MiroGuideSource.cs           |   57 ++++++
 .../Banshee.MiroGuide/MiroGuideView.cs             |  180 +++++++++++++++++++
 src/Extensions/Banshee.MiroGuide/Makefile.am       |   18 ++
 .../Banshee.MiroGuide/Resources/loading.html       |   31 ++++
 .../22x22/categories/miro-guide-source.png         |  Bin 0 -> 2060 bytes
 .../scalable/categories/miro-guide-source.svg      |  188 ++++++++++++++++++++
 src/Extensions/Makefile.am                         |    1 +
 12 files changed, 608 insertions(+), 0 deletions(-)
---
diff --git a/Banshee.sln b/Banshee.sln
index c6eaa51..a337da2 100644
--- a/Banshee.sln
+++ b/Banshee.sln
@@ -102,6 +102,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Banshee.LibraryWatcher", "s
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Banshee.MiniMode", "src\Extensions\Banshee.MiniMode\Banshee.MiniMode.csproj", "{FCC1AE87-E10B-4B47-8ADE-D5F447E48518}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MiroGuide", "src\Extensions\Banshee.MiroGuide\Banshee.MiroGuide.csproj", "{621F56FD-2E25-45E1-A30A-59F98A28A9E7}"
+EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Banshee.Podcasting", "src\Extensions\Banshee.Podcasting\Banshee.Podcasting.csproj", "{46AD1892-C5D3-4696-BA40-FBF7F4CE2B39}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Banshee.Sample", "src\Extensions\Banshee.Sample\Banshee.Sample.csproj", "{6FF6F049-9DAB-48A7-BC4B-F7F3ED0EBA63}"
@@ -425,6 +427,10 @@ Global
 		{FCC1AE87-E10B-4B47-8ADE-D5F447E48518}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{FCC1AE87-E10B-4B47-8ADE-D5F447E48518}.Windows|Any CPU.ActiveCfg = Windows|Any CPU
 		{FCC1AE87-E10B-4B47-8ADE-D5F447E48518}.Windows|Any CPU.Build.0 = Windows|Any CPU
+		{621F56FD-2E25-45E1-A30A-59F98A28A9E7}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{621F56FD-2E25-45E1-A30A-59F98A28A9E7}.Debug|x86.Build.0 = Debug|Any CPU
+		{621F56FD-2E25-45E1-A30A-59F98A28A9E7}.Release|x86.ActiveCfg = Release|Any CPU
+		{621F56FD-2E25-45E1-A30A-59F98A28A9E7}.Release|x86.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(NestedProjects) = preSolution
 		{EB1FDF3F-048C-4010-80F5-D936A312580F} = {E6AD3714-5EA3-49D9-BA8D-12C69B2B8067}
@@ -469,6 +475,7 @@ Global
 		{F38B53BA-8F85-4DC6-9B94-029C1CF96F24} = {4DD1DE63-F20B-4FC3-8FDA-F0BDF4183722}
 		{49CA3F27-0BB6-428d-8B3A-20232493652E} = {4DD1DE63-F20B-4FC3-8FDA-F0BDF4183722}
 		{FCC1AE87-E10B-4B47-8ADE-D5F447E48518} = {4DD1DE63-F20B-4FC3-8FDA-F0BDF4183722}
+		{621F56FD-2E25-45E1-A30A-59F98A28A9E7} = {4DD1DE63-F20B-4FC3-8FDA-F0BDF4183722}
 		{46AD1892-C5D3-4696-BA40-FBF7F4CE2B39} = {4DD1DE63-F20B-4FC3-8FDA-F0BDF4183722}
 		{6FF6F049-9DAB-48A7-BC4B-F7F3ED0EBA63} = {4DD1DE63-F20B-4FC3-8FDA-F0BDF4183722}
 		{01818BD5-9A0C-4C89-84FB-08D0E968778F} = {4DD1DE63-F20B-4FC3-8FDA-F0BDF4183722}
diff --git a/configure.ac b/configure.ac
index 841d85b..542e74c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -345,6 +345,7 @@ src/Extensions/Banshee.Lastfm/Makefile
 src/Extensions/Banshee.LastfmStreaming/Makefile
 src/Extensions/Banshee.LibraryWatcher/Makefile
 src/Extensions/Banshee.MiniMode/Makefile
+src/Extensions/Banshee.MiroGuide/Makefile
 src/Extensions/Banshee.MeeGo/Makefile
 src/Extensions/Banshee.MultimediaKeys/Makefile
 src/Extensions/Banshee.NotificationArea/Makefile
@@ -395,6 +396,7 @@ ${PACKAGE}-${VERSION}
     Web Browser:       ${have_libwebkit} (webkit-1.0 >= 1.2.0, libsoup-2.4 >= 2.26)
       + GNOME Proxy    ${have_libsoup_gnome} (libsoup-gnome-2.4 >= 2.26)
       + Amazon MP3     ${have_libwebkit}
+      + Miro Guide     ${have_libwebkit}
       + Wikipedia      ${have_libwebkit}
     Boo Scripting:     ${enable_boo}
     Builtin Equalizer: ${enable_builtin_equalizer}
diff --git a/data/addin-xml-strings.cs b/data/addin-xml-strings.cs
index d599c9a..eb72ad0 100644
--- a/data/addin-xml-strings.cs
+++ b/data/addin-xml-strings.cs
@@ -145,6 +145,11 @@ internal static class AddinXmlStringCatalog
         Catalog.GetString (@"Control Banshee through a small window with only playback controls and track information.");
         Catalog.GetString (@"Utilities");
 
+        // ../src/Extensions/Banshee.MiroGuide/Banshee.MiroGuide.addin.xml
+        Catalog.GetString (@"Miro Guide Podcast Directory");
+        Catalog.GetString (@"Browse and subscribe to thousands of audio and video podcasts.");
+        Catalog.GetString (@"Online Sources");
+
         // ../src/Extensions/Banshee.MultimediaKeys/Banshee.MultimediaKeys.addin.xml
         Catalog.GetString (@"Multimedia Keys");
         Catalog.GetString (@"Control playback via the multimedia keys on your keyboard.");
diff --git a/src/Extensions/Banshee.MiroGuide/Banshee.MiroGuide.addin.xml b/src/Extensions/Banshee.MiroGuide/Banshee.MiroGuide.addin.xml
new file mode 100644
index 0000000..434ea21
--- /dev/null
+++ b/src/Extensions/Banshee.MiroGuide/Banshee.MiroGuide.addin.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Addin 
+    id="Banshee.MiroGuide"
+    version="1.0"
+    compatVersion="1.0"
+    copyright="Copyright © 2010 Novell, Inc. Licensed under the MIT X11 license."
+    name="Miro Guide Podcast Directory"
+    category="Online Sources"
+    description="Browse and subscribe to thousands of audio and video podcasts."
+    author="Gabriel Burt"
+    url="http://banshee-project.org/";
+    defaultEnabled="false">
+
+  <Dependencies>
+    <Addin id="Banshee.Services" version="1.0"/>
+    <Addin id="Banshee.ThickClient" version="1.0"/>
+  </Dependencies>
+
+  <Extension path="/Banshee/SourceManager/Source">
+    <Source class="Banshee.MiroGuide.MiroGuideSource"/>
+  </Extension>
+
+</Addin>
diff --git a/src/Extensions/Banshee.MiroGuide/Banshee.MiroGuide.csproj b/src/Extensions/Banshee.MiroGuide/Banshee.MiroGuide.csproj
new file mode 100644
index 0000000..ac3337c
--- /dev/null
+++ b/src/Extensions/Banshee.MiroGuide/Banshee.MiroGuide.csproj
@@ -0,0 +1,96 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"; ToolsVersion="3.5">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.50727</ProductVersion>
+    <ProjectGuid>{621F56FD-2E25-45E1-A30A-59F98A28A9E7}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <UseParentDirectoryAsNamespace>true</UseParentDirectoryAsNamespace>
+    <AssemblyName>Banshee.MiroGuide</AssemblyName>
+    <SchemaVersion>2.0</SchemaVersion>
+    <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+    <Optimize>true</Optimize>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <OutputPath>..\..\..\bin</OutputPath>
+    <AssemblyKeyFile>.</AssemblyKeyFile>
+    <CustomCommands>
+      <CustomCommands>
+        <Command type="Build" command="make" workingdir="${SolutionDir}" />
+        <Command type="Execute" command="make run" workingdir="${SolutionDir}" />
+      </CustomCommands>
+    </CustomCommands>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Windows|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <OutputPath>..\..\..\bin</OutputPath>
+    <PlatformTarget>x86</PlatformTarget>
+    <AssemblyKeyFile>.</AssemblyKeyFile>
+  </PropertyGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\Core\Banshee.Core\Banshee.Core.csproj">
+      <Project>{2ADB831A-A050-47D0-B6B9-9C19D60233BB}</Project>
+      <Name>Banshee.Core</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\Core\Banshee.Services\Banshee.Services.csproj">
+      <Project>{B28354F0-BA87-44E8-989F-B864A3C7C09F}</Project>
+      <Name>Banshee.Services</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\Libraries\Hyena\Hyena.csproj">
+      <Project>{95374549-9553-4C1E-9D89-667755F90E12}</Project>
+      <Name>Hyena</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\Libraries\Hyena.Gui\Hyena.Gui.csproj">
+      <Project>{C856EFD8-E812-4E61-8B76-E3583D94C233}</Project>
+      <Name>Hyena.Gui</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\Core\Banshee.Widgets\Banshee.Widgets.csproj">
+      <Project>{A3701765-E571-413D-808C-9788A22791AF}</Project>
+      <Name>Banshee.Widgets</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\Core\Banshee.ThickClient\Banshee.ThickClient.csproj">
+      <Project>{AC839523-7BDF-4AB6-8115-E17921B96EC6}</Project>
+      <Name>Banshee.ThickClient</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="gtk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
+    <Reference Include="Mono.Posix" />
+    <Reference Include="gdk-sharp, Version=2.12.0.0, Culture=neutral, PublicKeyToken=35e10195dab3c99f" />
+    <Reference Include="Mono.Cairo" />
+    <Reference Include="Mono.Addins" />
+  </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="MiroGuide.addin.xml">
+      <LogicalName>MiroGuide.addin.xml</LogicalName>
+    </EmbeddedResource>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="Banshee.MiroGuide\MiroGuideSource.cs" />
+    <Compile Include="Banshee.MiroGuide\MiroGuideView.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <ProjectExtensions>
+    <MonoDevelop>
+      <Properties>
+        <MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="true" RelativeMakefileName="./Makefile.am">
+          <BuildFilesVar Sync="true" Name="SOURCES" />
+          <DeployFilesVar />
+          <ResourcesVar Sync="true" Name="RESOURCES" />
+          <OthersVar />
+          <GacRefVar />
+          <AsmRefVar />
+          <ProjectRefVar />
+        </MonoDevelop.Autotools.MakefileInfo>
+      </Properties>
+    </MonoDevelop>
+  </ProjectExtensions>
+</Project>
diff --git a/src/Extensions/Banshee.MiroGuide/Banshee.MiroGuide/MiroGuideSource.cs b/src/Extensions/Banshee.MiroGuide/Banshee.MiroGuide/MiroGuideSource.cs
new file mode 100644
index 0000000..1c60e08
--- /dev/null
+++ b/src/Extensions/Banshee.MiroGuide/Banshee.MiroGuide/MiroGuideSource.cs
@@ -0,0 +1,57 @@
+//
+// MiroGuideSource.cs
+//
+// Authors:
+//   Gabriel Burt <gburt novell com>
+//
+// Copyright (C) 2010 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 Mono.Unix;
+
+using Mono.Addins;
+
+using Banshee.Base;
+using Banshee.Sources;
+using Banshee.Sources.Gui;
+
+using Banshee.ServiceStack;
+using Banshee.Preferences;
+using Banshee.MediaEngine;
+using Banshee.PlaybackController;
+
+namespace Banshee.MiroGuide
+{
+    public class MiroGuideSource : Banshee.WebSource.WebSource
+    {
+        public MiroGuideSource () : base (Catalog.GetString ("Miro Guide"), 160, "miro-guide")
+        {
+            Properties.SetString ("Icon.Name", "miro-guide-source");
+        }
+
+        protected override Gtk.Widget GetWidget ()
+        {
+            return new Banshee.WebSource.WebBrowserShell (Name, new MiroGuideView ());
+        }
+    }
+}
diff --git a/src/Extensions/Banshee.MiroGuide/Banshee.MiroGuide/MiroGuideView.cs b/src/Extensions/Banshee.MiroGuide/Banshee.MiroGuide/MiroGuideView.cs
new file mode 100644
index 0000000..9f411a8
--- /dev/null
+++ b/src/Extensions/Banshee.MiroGuide/Banshee.MiroGuide/MiroGuideView.cs
@@ -0,0 +1,180 @@
+//
+// MiroGuideView.cs
+//
+// Authors:
+//   Aaron Bockover <abockover novell com>
+//   Gabriel Burt <gburt novell com>
+//
+// Copyright 2010 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 Gtk;
+
+using Hyena;
+using Hyena.Downloader;
+
+using Banshee.Base;
+using Banshee.IO;
+using Banshee.ServiceStack;
+using Banshee.WebBrowser;
+
+namespace Banshee.MiroGuide
+{
+    public class MiroGuideView : Banshee.WebSource.WebView
+    {
+        public MiroGuideView ()
+        {
+            CanSearch = true;
+            FullReload ();
+        }
+
+        protected override void OnLoadStatusChanged (OssiferLoadStatus status)
+        {
+            if ((status == OssiferLoadStatus.FirstVisuallyNonEmptyLayout ||
+                status == OssiferLoadStatus.Finished) && Uri != "about:blank") {
+
+                //if (fixup_javascript != null) {
+                    //ExecuteScript (fixup_javascript);
+                //}
+                var fixup_javascript = @"
+                    // Hide welcome
+                    var w = document.getElementById ('welcome');
+                    if (w != null) { w.style.display = 'none'; }
+
+                    // Hide these
+                    var a = document.getElementsByClassName ('only-in-browser')
+                    for (var i = 0; i < a.length; i++) { a[i].style.display = 'none'; }
+
+                    // Show these
+                    a = document.getElementsByClassName ('only-in-miro')
+                    for (var i = 0; i < a.length; i++) { a[i].className = ''; }
+                ";
+                ExecuteScript (fixup_javascript);
+            }
+
+            if (status == OssiferLoadStatus.Finished && Uri != null && Uri.StartsWith ("http://miroguide.com";)) {
+                last_was_audio.Set (Uri.Contains ("miroguide.com/audio/"));
+            }
+
+            base.OnLoadStatusChanged (status);
+        }
+
+        protected override OssiferNavigationResponse OnMimeTypePolicyDecisionRequested (string mimetype)
+        {
+            // We only explicitly accept (render) text/html types, and only
+            // download audio/x-amzxml - everything else is ignored.
+            switch (mimetype) {
+                //case "audio/x-mpegurl":
+                //
+                // TODO:
+                //   media mimetypes - ship to gst/PlayerEngine
+                //   application/rss+xml
+                case "application/x-miro":
+                    return OssiferNavigationResponse.Download;
+                default:
+                    return base.OnMimeTypePolicyDecisionRequested (mimetype);
+            }
+        }
+
+        protected override string OnDownloadRequested (string mimetype, string uri, string suggestedFilename)
+        {
+            switch (mimetype) {
+                case "application/x-miro":
+                    var dest_uri_base = "file://" + Paths.Combine (Paths.TempDir, suggestedFilename);
+                    var dest_uri = new SafeUri (dest_uri_base);
+                    for (int i = 1; File.Exists (dest_uri);
+                        dest_uri = new SafeUri (String.Format ("{0} ({1})", dest_uri_base, ++i)));
+                    return dest_uri.AbsoluteUri;
+                /*case "audio/x-mpegurl":
+                    Banshee.Streaming.RadioTrackInfo.OpenPlay (uri);
+                    Banshee.ServiceStack.ServiceManager.PlaybackController.StopWhenFinished = true;
+                    return null;*/
+            }
+
+            return null;
+        }
+
+        protected override OssiferNavigationResponse OnNavigationPolicyDecisionRequested (string uri)
+        {
+            Log.Information ("ResourceRequestStarting for", uri);
+
+            // Avoid the whole redirect-before-downloading page if possible
+            if (uri != null && uri.StartsWith ("http://subscribe.getmiro.com/";) && uri.Contains ("url1")) {
+                int a = uri.IndexOf ("url1") + 5;
+                int l = Math.Min (uri.Length - 1, uri.IndexOf ('&', a)) - a;
+                if (l > 0 && a + l < uri.Length) {
+                    var direct_uri = System.Web.HttpUtility.UrlDecode (uri.Substring (a, l));
+                    if (uri.Contains ("/download")) {
+                        // Go straight to the destination URL
+                        Banshee.Streaming.RadioTrackInfo.OpenPlay (direct_uri);
+                        Banshee.ServiceStack.ServiceManager.PlaybackController.StopWhenFinished = true;
+                        Log.DebugFormat ("MiroGuide: playing straight away {0}", direct_uri);
+                    } else {
+                        // Subscribe to it straight away, don't redirect at all
+                        ServiceManager.Get<DBusCommandService> ().PushFile (direct_uri);
+                        Log.DebugFormat ("MiroGuide: subscribing straight away to {0}", direct_uri);
+                    }
+                    return OssiferNavigationResponse.Ignore;
+                }
+            }
+
+            return OssiferNavigationResponse.Unhandled;
+        }
+
+        protected override void OnDownloadStatusChanged (OssiferDownloadStatus status, string mimetype, string destinationUri)
+        {
+            // FIXME: handle the error case
+            if (status != OssiferDownloadStatus.Finished) {
+                return;
+            }
+
+            switch (mimetype) {
+                case "application/x-miro":
+                    Log.Debug ("MiroGuide: downloaded Miro subscription file", destinationUri);
+                    ServiceManager.Get<DBusCommandService> ().PushFile (destinationUri);
+                    break;
+            }
+        }
+
+        public override void GoHome ()
+        {
+            if (last_was_audio.Get ()) {
+                LoadUri ("http://miroguide.com/audio/#popular";);
+            } else {
+                LoadUri ("http://miroguide.com/#popular";);
+            }
+        }
+
+        public override void GoSearch (string query)
+        {
+            if (last_was_audio.Get ()) {
+                LoadUri (new Uri ("http://miroguide.com/audio/search?query="; + query).AbsoluteUri);
+            } else {
+                LoadUri (new Uri ("http://miroguide.com/search?query="; + query).AbsoluteUri);
+            }
+        }
+
+        private static Banshee.Configuration.SchemaEntry<bool> last_was_audio = new Banshee.Configuration.SchemaEntry<bool> (
+            "plugins.miroguide", "last_was_audio", true, "", ""
+        );
+    }
+}
diff --git a/src/Extensions/Banshee.MiroGuide/Makefile.am b/src/Extensions/Banshee.MiroGuide/Makefile.am
new file mode 100644
index 0000000..263216b
--- /dev/null
+++ b/src/Extensions/Banshee.MiroGuide/Makefile.am
@@ -0,0 +1,18 @@
+ASSEMBLY = Banshee.MiroGuide
+TARGET = library
+INSTALL_DIR = $(EXTENSIONS_INSTALL_DIR)
+LINK = $(LINK_BANSHEE_THICKCLIENT_DEPS) $(LINK_BANSHEE_WEBBROWSER_DEPS) 
+
+SOURCES = \
+	Banshee.MiroGuide/MiroGuideSource.cs \
+	Banshee.MiroGuide/MiroGuideView.cs
+
+RESOURCES = \
+	Banshee.MiroGuide.addin.xml \
+	Resources/loading.html
+
+if HAVE_LIBWEBKIT
+include $(top_srcdir)/build/build.mk
+else
+EXTRA_DIST = $(SOURCES) $(RESOURCES)
+endif
diff --git a/src/Extensions/Banshee.MiroGuide/Resources/loading.html b/src/Extensions/Banshee.MiroGuide/Resources/loading.html
new file mode 100644
index 0000000..16fc85a
--- /dev/null
+++ b/src/Extensions/Banshee.MiroGuide/Resources/loading.html
@@ -0,0 +1,31 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <script type="text/javascript">
+    window.onload = function () {
+        var canvas = document.getElementById ("spinner");
+        var context = canvas.getContext ("2d");
+        context.translate (32, 32);
+        context.lineWidth = 5;
+        context.lineCap = "round";
+        setInterval (function () {
+            var density = 12;
+            context.clearRect (-32, -32, 64, 64);
+            context.rotate (Math.PI * 2 / density);
+            for (var i = 0; i < density; i++) {
+                context.rotate (Math.PI * 2 / density);
+                context.strokeStyle = "rgba(0,0,0," + i / density + ")";
+                context.beginPath ();
+                context.moveTo (0, 15);
+                context.lineTo (0, 25);
+                context.stroke ();
+            }
+        }, 75);
+    };
+  </script>
+</head>
+<body>
+<canvas id="spinner" width="64" height="64"
+    style="position:absolute; top:35%; left:50%; margin-left:-32px;"/>
+</body>
+</html>
\ No newline at end of file
diff --git a/src/Extensions/Banshee.MiroGuide/ThemeIcons/22x22/categories/miro-guide-source.png b/src/Extensions/Banshee.MiroGuide/ThemeIcons/22x22/categories/miro-guide-source.png
new file mode 100644
index 0000000..ced1240
Binary files /dev/null and b/src/Extensions/Banshee.MiroGuide/ThemeIcons/22x22/categories/miro-guide-source.png differ
diff --git a/src/Extensions/Banshee.MiroGuide/ThemeIcons/scalable/categories/miro-guide-source.svg b/src/Extensions/Banshee.MiroGuide/ThemeIcons/scalable/categories/miro-guide-source.svg
new file mode 100644
index 0000000..be1c328
--- /dev/null
+++ b/src/Extensions/Banshee.MiroGuide/ThemeIcons/scalable/categories/miro-guide-source.svg
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:xlink="http://www.w3.org/1999/xlink";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.0"
+   width="48"
+   height="48"
+   id="svg3266"
+   sodipodi:version="0.32"
+   inkscape:version="0.46"
+   sodipodi:docname="miro.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <metadata
+     id="metadata33">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview
+     inkscape:window-height="794"
+     inkscape:window-width="1440"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     showgrid="false"
+     inkscape:zoom="6.8648283"
+     inkscape:cx="-9.6420969"
+     inkscape:cy="24"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:current-layer="svg3266" />
+  <defs
+     id="defs3268">
+    <linearGradient
+       id="linearGradient8838">
+      <stop
+         id="stop8840"
+         style="stop-color:#000000;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop8842"
+         style="stop-color:#000000;stop-opacity:0"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2490">
+      <stop
+         id="stop2492"
+         style="stop-color:#791235;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop2494"
+         style="stop-color:#dd3b27;stop-opacity:1"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3242">
+      <stop
+         id="stop3244"
+         style="stop-color:#f8b17e;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop3246"
+         style="stop-color:#e35d4f;stop-opacity:1"
+         offset="0.26238" />
+      <stop
+         id="stop3248"
+         style="stop-color:#c6262e;stop-opacity:1"
+         offset="0.66093999" />
+      <stop
+         id="stop3250"
+         style="stop-color:#690b54;stop-opacity:1"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3202">
+      <stop
+         id="stop3204"
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop3206"
+         style="stop-color:#d3eefc;stop-opacity:1"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient3230">
+      <stop
+         id="stop3232"
+         style="stop-color:#ffffff;stop-opacity:1"
+         offset="0" />
+      <stop
+         id="stop3234"
+         style="stop-color:#ffffff;stop-opacity:0"
+         offset="1" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3230"
+       id="linearGradient2408"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(0,0.9999998)"
+       x1="26.153599"
+       y1="4.9999995"
+       x2="26.153599"
+       y2="44.233311" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3202"
+       id="linearGradient2411"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.0395395,0,0,0.9504295,2.4213254,1.5862551)"
+       x1="22.885227"
+       y1="17.628952"
+       x2="22.885227"
+       y2="30.889549" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient3242"
+       id="radialGradient2415"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(0,1.6958206,-1.7757718,0,30.273358,-47.575099)"
+       cx="32.806725"
+       cy="3.5327499"
+       fx="32.806725"
+       fy="3.5327499"
+       r="23" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2490"
+       id="linearGradient2417"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(51.417219,1.3502817)"
+       x1="-23.916132"
+       y1="43.707703"
+       x2="-23.916132"
+       y2="4.6497173" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient8838"
+       id="radialGradient2420"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(2.1647059,0,0,0.8470576,-111.5647,35.082353)"
+       cx="62.625"
+       cy="4.625"
+       fx="62.625"
+       fy="4.625"
+       r="10.625" />
+  </defs>
+  <path
+     style="opacity:0.3;fill:url(#radialGradient2420);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.99999987999999995;stroke-linecap:butt;stroke-linejoin:round;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+     id="path8836"
+     d="M 47.000007,39 C 47.000007,43.970562 36.702555,47.999999 24.000007,47.999999 C 11.297459,47.999999 1.0000068,43.970562 1.0000068,39 C 1.0000068,34.029437 11.297459,30 24.000007,30 C 36.702555,30 47.000007,34.029437 47.000007,39 L 47.000007,39 z" />
+  <path
+     style="fill:url(#radialGradient2415);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2417);stroke-width:0.99999988px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     id="path2421"
+     d="M 1.5000006,31.761226 C 1.5000006,31.761226 10.115608,15.647729 22.458894,9.2294409 C 29.653279,5.4884898 41.244893,4.5285552 46.43013,13.320438 C 46.43013,13.320438 48.176874,36.419951 34.202924,42.922755 C 34.202924,42.922755 19.743769,50.687298 1.5000006,31.761226 z" />
+  <path
+     style="font-size:26.70637703px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:#a1ceef;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:URW Gothic L;-inkscape-font-specification:URW Gothic L Book"
+     id="path2438"
+     d="M 16,30.999999 C 17.225378,30.999999 19.774622,30.999999 21,30.999999 C 21.020028,28.309559 20.916511,25.61742 21,22.928239 C 21,21.493793 21.209448,20.211199 22.896799,20.211199 C 24.832644,20.211199 24.986483,21.181016 24.986483,23.02827 C 24.986483,24.716506 24.986483,29.311763 24.986483,30.999999 C 26.21186,30.999999 28.774623,31 30,31 C 30.014374,28.354294 29.941186,25.707605 30,23.062615 C 30.008937,21.790435 29.886674,20.211199 31.992422,20.211199 C 33.88686,20.211199 33.999064,21.457713 33.999064,23.083965 C 33.999064,24.753635 33.999063,29.330328 33.999064,31 C 35.22444,31 37.774622,31 39,31 C 38.985776,28.048126 39.029681,25.095218 38.975706,22.144048 C 38.898843,20.359713 38.212819,18.388221 36.387725,17.484421 C 35.343606,17.14161 35.045063,17.011799 33.742745,17.011799 C 31.060737,17.011799 20.652644,17 16,17 C 16,21.666666 16,26.333334 16,30.999999 z" />
+  <path
+     style="font-size:26.70637703px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;fill:url(#linearGradient2411);fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:URW Gothic L;-inkscape-font-specification:URW Gothic L Book"
+     id="text3190"
+     d="M 16,31.999999 C 17.225378,31.999999 19.774622,31.999999 21,31.999999 C 21.020028,29.309559 20.916511,26.61742 21,23.928239 C 21,22.493793 21.209448,21.211199 22.896799,21.211199 C 24.832644,21.211199 24.986483,22.181016 24.986483,24.02827 C 24.986483,25.716506 24.986483,30.311763 24.986483,31.999999 C 26.21186,31.999999 28.774623,32 30,32 C 30.014374,29.354294 29.941186,26.707605 30,24.062615 C 30.008937,22.790435 29.886674,21.211199 31.992422,21.211199 C 33.88686,21.211199 33.999064,22.457713 33.999064,24.083965 C 33.999064,25.753635 33.999063,30.330328 33.999064,32 C 35.22444,32 37.774622,32 39,32 C 38.985776,29.048126 39.029681,26.095218 38.975706,23.144048 C 38.898843,21.359713 38.212819,19.388221 36.387725,18.484421 C 35.343606,18.14161 35.045063,18.011799 33.742745,18.011799 C 31.060737,18.011799 20.652644,18 16,18 C 16,22.666666 16,27.333334 16,31.999999 z" />
+  <path
+     style="opacity:0.4;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2408);stroke-width:0.99999988px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     id="path3238"
+     d="M 31.90625,7.4999998 C 28.681328,7.7425666 25.48596,8.7210967 22.90625,10.0625 C 11.707044,15.885887 3.6907335,29.825628 2.71875,31.5625 C 11.484066,40.437302 19.207332,43.094404 24.75,43.5 C 30.407274,43.913983 33.75,42.09375 33.75,42.09375 C 33.760173,42.083092 33.770592,42.072673 33.78125,42.0625 C 40.364812,38.998827 43.337844,31.95008 44.625,25.5 C 45.868154,19.27042 45.525212,13.993747 45.5,13.625 C 42.448467,8.6273583 37.213852,7.1007814 31.90625,7.4999998 z" />
+</svg>
diff --git a/src/Extensions/Makefile.am b/src/Extensions/Makefile.am
index 28f7ad2..5272f25 100644
--- a/src/Extensions/Makefile.am
+++ b/src/Extensions/Makefile.am
@@ -15,6 +15,7 @@ SUBDIRS = \
 	Banshee.LastfmStreaming \
 	Banshee.LibraryWatcher \
 	Banshee.MiniMode \
+	Banshee.MiroGuide \
 	Banshee.MultimediaKeys \
 	Banshee.NotificationArea \
 	Banshee.NowPlaying \



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