beagle r4871 - branches/beagle-abock-branch/beagled/BansheeQueryable
- From: abock svn gnome org
- To: svn-commits-list gnome org
- Subject: beagle r4871 - branches/beagle-abock-branch/beagled/BansheeQueryable
- Date: Sat, 11 Oct 2008 03:52:21 +0000 (UTC)
Author: abock
Date: Sat Oct 11 03:52:20 2008
New Revision: 4871
URL: http://svn.gnome.org/viewvc/beagle?rev=4871&view=rev
Log:
First pass at implementing a Queryable to consume the new Banshee Collection Indexer DBus API through the light weight helper library, Banshee.CollectionIndexer.dll
Added:
branches/beagle-abock-branch/beagled/BansheeQueryable/
branches/beagle-abock-branch/beagled/BansheeQueryable/BansheeIndexableGenerator.cs
branches/beagle-abock-branch/beagled/BansheeQueryable/BansheeIndexer.cs
branches/beagle-abock-branch/beagled/BansheeQueryable/BansheeQueryable.cs
branches/beagle-abock-branch/beagled/BansheeQueryable/BansheeQueryable.csproj
branches/beagle-abock-branch/beagled/BansheeQueryable/BansheeQueryable.sln
Added: branches/beagle-abock-branch/beagled/BansheeQueryable/BansheeIndexableGenerator.cs
==============================================================================
--- (empty file)
+++ branches/beagle-abock-branch/beagled/BansheeQueryable/BansheeIndexableGenerator.cs Sat Oct 11 03:52:20 2008
@@ -0,0 +1,101 @@
+//
+// BansheeIndexableGenerator.cs
+//
+// Author:
+// Aaron Bockover <abockover novell com>
+//
+// Copyright (C) 2008 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 Beagle.Daemon;
+using Beagle.Util;
+
+namespace Beagle.Daemon.BansheeQueryable
+{
+ public class BansheeIndexableGenerator : IIndexableGenerator
+ {
+ internal const string Tag = "BansheeCollectionIndexer";
+
+ private static int generator_count = 0;
+
+ private IDictionary<string, object> [] index_results;
+ private int current_index;
+ private bool done;
+ private DateTime create_date;
+ private int create_id;
+
+ public bool Done {
+ get { return done; }
+ }
+
+ public BansheeIndexableGenerator (BansheeQueryable queryable)
+ {
+ this.index_results = queryable.Indexer.CopyResults ();
+ this.create_date = DateTime.Now;
+ this.create_id = generator_count++;
+
+ Log.Info ("BansheeQueryable: New BansheeIndexableGenerator ({0})", this);
+ }
+
+ public override string ToString ()
+ {
+ return String.Format ("{0}:{1} [{2}]", GetType (), create_id, create_date);
+ }
+
+#region IIndexableGenerator
+
+ public string StatusName {
+ get { return String.Format ("Banshee object {0} of {1}", current_index, index_results.Length); }
+ }
+
+ public void PostFlushHook ()
+ {
+ }
+
+ public bool HasNextIndexable ()
+ {
+ if (current_index <= index_results.Length) {
+ return true;
+ }
+
+ done = true;
+ index_results = null;
+ current_index = 0;
+ return false;
+ }
+
+ public Indexable GetNextIndexable ()
+ {
+ if (!Done && current_index < index_results.Length) {
+ return BansheeIndexer.GetIndexable (index_results[current_index++]);
+ }
+
+ return null;
+ }
+
+#endregion
+
+ }
+}
Added: branches/beagle-abock-branch/beagled/BansheeQueryable/BansheeIndexer.cs
==============================================================================
--- (empty file)
+++ branches/beagle-abock-branch/beagled/BansheeQueryable/BansheeIndexer.cs Sat Oct 11 03:52:20 2008
@@ -0,0 +1,298 @@
+//
+// BansheeIndexer.cs
+//
+// Author:
+// Aaron Bockover <abockover novell com>
+//
+// Copyright (C) 2008 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 Banshee.Collection.Indexer.RemoteHelper;
+
+using Beagle.Util;
+using Beagle.Daemon;
+using Stopwatch = Beagle.Util.Stopwatch;
+
+namespace Beagle.Daemon.BansheeQueryable
+{
+ // Field dump from GetExportFields in Banshee 1.3.2
+ //
+ // bit-rate, artist, rating, skip-count, artist-music-brainz-id, conductor, mime-type,
+ // file-size, length, URI, music-brainz-id, name, play-count, license-uri, track-number,
+ // disc-count, grouping, date-added, album-artist, last-played, genre, release-date,
+ // local-path, is-compilation, media-attributes, more-info-uri, disc-number, comment,
+ // year, copyright, bpm, composer, last-skipped, track-count, album, album-music-brainz-id
+
+ public class BansheeIndexer : SimpleIndexerClient
+ {
+ private List<IDictionary<string, object>> indexed_items = new List<IDictionary<string, object>> ();
+ private BansheeQueryable queryable;
+ private Stopwatch stopwatch;
+ private bool should_commit;
+
+ public BansheeIndexer (BansheeQueryable queryable)
+ {
+ this.queryable = queryable;
+ }
+
+ public IDictionary<string, object> [] CopyResults ()
+ {
+ return indexed_items.ToArray ();
+ }
+
+#region SimpleIndexerClient Implementation Hooks
+
+ protected override void OnStarted ()
+ {
+ foreach (string field in GetAvailableExportFields ()) {
+ if (!ShouldSkipField (field, SkipType.Exclude)) {
+ AddExportField (field);
+ }
+ }
+ }
+
+ protected override void OnBeginUpdateIndex ()
+ {
+ Log.Info ("BansheeQueryable: Reading indexer results from DBus");
+
+ stopwatch = new Stopwatch ();
+ stopwatch.Start ();
+
+ indexed_items.Clear ();
+ should_commit = true;
+ }
+
+ protected override void OnEndUpdateIndex ()
+ {
+ stopwatch.Stop ();
+ Log.Info ("BansheeQueryable: Finished reading {0} results in {1} over DBus", indexed_items.Count, stopwatch);
+
+ // The indexing server terminated our read, probably because a user requested
+ // that Banshee start up as an application; in this case we discard any index
+ // results collected, and reset - the index process will trigger automatically
+ // when the application starts per the user's request
+ if (!should_commit) {
+ indexed_items.Clear ();
+ Log.Info ("BansheeQueryable: Discarding index results, OnShutdownWhileIndexing called");
+ return;
+ }
+
+ queryable.OnIndexablesReady ();
+ }
+
+ protected override void IndexResult (IDictionary<string, object> result)
+ {
+ indexed_items.Add (result);
+ }
+
+ protected override void OnShutdownWhileIndexing ()
+ {
+ Log.Info ("BansheeQueryable: OnShutdownWhileIndexing - server has terminated the index operation");
+ should_commit = false;
+ }
+
+#endregion
+
+#region SimpleIndexerClient Index Trigger Properties
+
+ // FIXME: These need implementing, but I have no idea how to store and read
+ // this data in Beagle. With these returning nothing, the entire index process
+ // will trigger every time!
+
+ protected override int CollectionCount {
+ get { return 0; }
+ }
+
+ protected override DateTime CollectionLastModified {
+ get { return DateTime.MinValue; }
+ }
+
+#endregion
+
+#region Convert the remote a{sv} result into a Beagle Indexable
+
+ public static Indexable GetIndexable (IDictionary<string, object> result)
+ {
+ Uri uri = result.ContainsKey ("local-path")
+ ? UriFu.PathToFileUri ((string)result["local-path"])
+ : UriFu.EscapedStringToUri ((string)result["URI"]);
+
+ Indexable indexable = new Indexable (IndexableType.PropertyChange, uri);
+
+ foreach (KeyValuePair<string, object> item in result) {
+ FieldAction action = GetFieldAction (item.Key);
+ if (action.Skip == SkipType.Ignore) {
+ continue;
+ }
+
+ string banshee_name = item.Key;
+ string beagle_name = action.BeagleName ?? MakeBeagleName (banshee_name);
+ Property property;
+
+ switch (action.PropertyKind) {
+ case PropertyKind.String:
+ property = Beagle.Property.New (beagle_name, item.Value.ToString ());
+ break;
+ case PropertyKind.Date:
+ property = Beagle.Property.NewDateFromString (beagle_name, item.Value.ToString ());
+ break;
+ case PropertyKind.Unsearched:
+ default:
+ property = Beagle.Property.NewUnsearched (beagle_name, item.Value);
+ break;
+ }
+
+ property.IsMutable = true;
+ property.IsPersistent = true;
+ indexable.AddProperty (property);
+ }
+
+ return indexable;
+ }
+
+#endregion
+
+#region Crazy Static stuff for magically translating, ignoring, and excluding fields from Banshee to Beagle
+
+ private enum PropertyKind
+ {
+ Unsearched,
+ String,
+ Date
+ }
+
+ private enum SkipType
+ {
+ None,
+ Ignore,
+ Exclude
+ }
+
+ private struct FieldAction
+ {
+ public static FieldAction Zero = new FieldAction ();
+
+ public static FieldAction NewIgnore (string bansheeName)
+ {
+ FieldAction action = new FieldAction ();
+ action.BansheeName = bansheeName;
+ action.Skip = SkipType.Ignore;
+ return action;
+ }
+
+ public static FieldAction NewExclude (string bansheeName)
+ {
+ FieldAction action = new FieldAction ();
+ action.BansheeName = bansheeName;
+ action.Skip = SkipType.Exclude;
+ return action;
+ }
+
+ public static FieldAction NewMap (string bansheeName, string beagleName)
+ {
+ return NewMap (bansheeName, beagleName, PropertyKind.Unsearched);
+ }
+
+ public static FieldAction NewMap (string bansheeName, string beagleName, PropertyKind kind)
+ {
+ FieldAction action = new FieldAction ();
+ action.BansheeName = bansheeName;
+ action.BeagleName = beagleName;
+ action.PropertyKind = kind;
+ return action;
+ }
+
+ public static FieldAction NewOverride (string bansheeName, PropertyKind kind)
+ {
+ FieldAction action = new FieldAction ();
+ action.BansheeName = bansheeName;
+ action.PropertyKind = kind;
+ return action;
+ }
+
+ public string BansheeName;
+ public string BeagleName;
+
+ public SkipType Skip;
+ public PropertyKind PropertyKind;
+ }
+
+ private static List<FieldAction> field_actions = new List<FieldAction> ();
+
+ static BansheeIndexer ()
+ {
+ field_actions.Add (FieldAction.NewMap ("copyright", "dc:copyright", PropertyKind.String));
+ field_actions.Add (FieldAction.NewMap ("name", "dc:title", PropertyKind.String));
+
+ field_actions.Add (FieldAction.NewOverride ("artist", PropertyKind.String));
+ field_actions.Add (FieldAction.NewOverride ("album-artist", PropertyKind.String));
+ field_actions.Add (FieldAction.NewOverride ("composer", PropertyKind.String));
+ field_actions.Add (FieldAction.NewOverride ("album", PropertyKind.String));
+ field_actions.Add (FieldAction.NewOverride ("conductor", PropertyKind.String));
+ field_actions.Add (FieldAction.NewOverride ("genre", PropertyKind.String));
+ field_actions.Add (FieldAction.NewOverride ("date-added", PropertyKind.Date));
+ field_actions.Add (FieldAction.NewOverride ("release-date", PropertyKind.Date));
+ field_actions.Add (FieldAction.NewOverride ("last-played", PropertyKind.Date));
+ field_actions.Add (FieldAction.NewOverride ("last-skipped", PropertyKind.Date));
+
+ field_actions.Add (FieldAction.NewIgnore ("URI"));
+ field_actions.Add (FieldAction.NewIgnore ("local-path"));
+
+ field_actions.Add (FieldAction.NewExclude ("file-size"));
+ field_actions.Add (FieldAction.NewExclude ("media-attributes"));
+ field_actions.Add (FieldAction.NewExclude ("mime-type"));
+ }
+
+ private static bool ShouldSkipField (string field, SkipType skip)
+ {
+ foreach (FieldAction action in field_actions) {
+ if (action.Skip == skip && action.BansheeName == field) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private static FieldAction GetFieldAction (string field)
+ {
+ foreach (FieldAction action in field_actions) {
+ if (action.BansheeName == field) {
+ return action;
+ }
+ }
+
+ return FieldAction.Zero;
+ }
+
+ private static string MakeBeagleName (string bansheeName)
+ {
+ return String.Format ("fixme:{0}", bansheeName.ToLower ().Replace ("-", String.Empty));
+ }
+
+#endregion
+
+ }
+}
Added: branches/beagle-abock-branch/beagled/BansheeQueryable/BansheeQueryable.cs
==============================================================================
--- (empty file)
+++ branches/beagle-abock-branch/beagled/BansheeQueryable/BansheeQueryable.cs Sat Oct 11 03:52:20 2008
@@ -0,0 +1,98 @@
+//
+// BansheeQueryable.cs
+//
+// Author:
+// Aaron Bockover <abockover novell com>
+//
+// Copyright (C) 2008 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.Threading;
+using System.Diagnostics;
+using System.Collections.Generic;
+
+using Stopwatch = Beagle.Util.Stopwatch;
+
+using Beagle.Daemon;
+using Beagle.Util;
+
+[assembly: Beagle.Daemon.IQueryableTypes (typeof (Beagle.Daemon.BansheeQueryable.BansheeQueryable))]
+
+namespace Beagle.Daemon.BansheeQueryable
+{
+ [QueryableFlavor (Name = "Banshee", Domain=QueryDomain.Local, RequireInotify = false, DependsOn = "Files")]
+ public class BansheeQueryable : ExternalMetadataQueryable
+ {
+ private FileSystemQueryable.FileSystemQueryable fs_queryable;
+ private BansheeIndexer indexer;
+ private BansheeIndexableGenerator indexable_generator;
+
+ internal BansheeIndexer Indexer {
+ get { return indexer; }
+ }
+
+ public override void Start ()
+ {
+ base.Start ();
+ NDesk.DBus.BusG.Init ();
+ fs_queryable = (FileSystemQueryable.FileSystemQueryable)QueryDriver.GetQueryable ("Files").IQueryable;
+ ExceptionHandlingThread.Start (new ThreadStart (StartWorker));
+ }
+
+ private void StartWorker ()
+ {
+ indexer = new BansheeIndexer (this);
+ indexer.Start ();
+
+ Log.Info ("BansheeQueryable: Banshee metadata backend started");
+ }
+
+ internal void OnIndexablesReady ()
+ {
+ LaunchIndexable ();
+ }
+
+ private void LaunchIndexable ()
+ {
+ // Cancel running task before adding a new one
+ CancelIndexable ();
+
+ // Add the new indexable generator
+ indexable_generator = new BansheeIndexableGenerator (this);
+
+ Scheduler.Task task = fs_queryable.NewAddTask (indexable_generator);
+ task.Tag = BansheeIndexableGenerator.Tag;
+ fs_queryable.ThisScheduler.Add (task);
+
+ Log.Info ("BansheeQueryable: Scheduled new BansheeIndexableGenerator ({0})", indexable_generator);
+ }
+
+ private void CancelIndexable ()
+ {
+ if (indexable_generator != null && fs_queryable.ThisScheduler.ContainsByTag (BansheeIndexableGenerator.Tag)) {
+ Log.Info ("BansheeQueryable: Cancelling existing BansheeIndexableGenerator ({0})", indexable_generator);
+ fs_queryable.ThisScheduler.GetByTag (BansheeIndexableGenerator.Tag).Cancel ();
+ }
+ }
+ }
+}
Added: branches/beagle-abock-branch/beagled/BansheeQueryable/BansheeQueryable.csproj
==============================================================================
--- (empty file)
+++ branches/beagle-abock-branch/beagled/BansheeQueryable/BansheeQueryable.csproj Sat Oct 11 03:52:20 2008
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.21022</ProductVersion>
+ <ProjectGuid>{D2AC3E46-E166-463B-8DB6-5E811D2D0B68}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AssemblyName>BansheeQueryable</AssemblyName>
+ <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>.</OutputPath>
+ <DefineConstants>DEBUG</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <EnvironmentVariables>
+ <EnvironmentVariables />
+ </EnvironmentVariables>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="BeagleDaemon, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\BeagleDaemon.exe</HintPath>
+ </Reference>
+ <Reference Include="BeagleDaemonLib, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\BeagleDaemonLib.dll</HintPath>
+ </Reference>
+ <Reference Include="BeagleDaemonPlugins, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\BeagleDaemonPlugins.dll</HintPath>
+ </Reference>
+ <Reference Include="NDesk.DBus, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f6716e4f9b2ed099" />
+ <Reference Include="NDesk.DBus.GLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f6716e4f9b2ed099" />
+ <Reference Include="Banshee.CollectionIndexer, Version=1.3.2.0, Culture=neutral, PublicKeyToken=null">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath>..\..\..\..\..\..\..\usr\lib\banshee-1\Banshee.CollectionIndexer.dll</HintPath>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="BansheeQueryable.cs" />
+ <Compile Include="BansheeIndexer.cs" />
+ <Compile Include="BansheeIndexableGenerator.cs" />
+ </ItemGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <ProjectExtensions>
+ <MonoDevelop>
+ <Properties>
+ <Deployment.LinuxDeployData generateScript="false" />
+ </Properties>
+ </MonoDevelop>
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
Added: branches/beagle-abock-branch/beagled/BansheeQueryable/BansheeQueryable.sln
==============================================================================
--- (empty file)
+++ branches/beagle-abock-branch/beagled/BansheeQueryable/BansheeQueryable.sln Sat Oct 11 03:52:20 2008
@@ -0,0 +1,18 @@
+ï
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual Studio 2005
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BansheeQueryable", "BansheeQueryable.csproj", "{D2AC3E46-E166-463B-8DB6-5E811D2D0B68}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {D2AC3E46-E166-463B-8DB6-5E811D2D0B68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D2AC3E46-E166-463B-8DB6-5E811D2D0B68}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ EndGlobalSection
+ GlobalSection(MonoDevelopProperties) = preSolution
+ name = BansheeQueryable
+ StartupItem = BansheeQueryable.csproj
+ EndGlobalSection
+EndGlobal
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]