[Banshee-List] [PATCH] cover art extension
- From: "James Willcox" <snorp snorp net>
- To: banshee-list gnome org
- Subject: [Banshee-List] [PATCH] cover art extension
- Date: Mon, 26 May 2008 12:24:55 -0500
Folks,
Attached is a patch which adds a new extension for user-initiated cover art fetching. It adds a "Download Cover Art" menu item under "Tools", and also automatically fetches cover art when you add/change tracks in the music library.
Thanks,
James
Index: src/Extensions/Extensions.mds
===================================================================
--- src/Extensions/Extensions.mds (revision 3968)
+++ src/Extensions/Extensions.mds (working copy)
@@ -13,6 +13,7 @@
<Entry build="True" name="Banshee.Podcasting" configuration="Debug" />
<Entry build="True" name="Banshee.Sample" configuration="Debug" />
<Entry build="True" name="Banshee.BooScript" configuration="Debug" />
+ <Entry build="True" name="Banshee.CoverArt" configuration="Debug" />
</Configuration>
</Configurations>
<StartMode startupentry="Banshee.Daap" single="True">
@@ -28,6 +29,7 @@
<Execute type="None" entry="Banshee.Podcasting" />
<Execute type="None" entry="Banshee.Sample" />
<Execute type="None" entry="Banshee.BooScript" />
+ <Execute type="None" entry="Banshee.CoverArt" />
</StartMode>
<Entries>
<Entry filename="Banshee.Daap/Banshee.Daap.mdp" />
@@ -42,5 +44,6 @@
<Entry filename="Banshee.Podcasting/Banshee.Podcasting.mdp" />
<Entry filename="Banshee.Sample/Banshee.Sample.mdp" />
<Entry filename="Banshee.BooScript/Banshee.BooScript.mdp" />
+ <Entry filename="Banshee.CoverArt/Banshee.CoverArt.mdp" />
</Entries>
</Combine>
\ No newline at end of file
Index: src/Extensions/Banshee.CoverArt/CoverArtJob.cs
===================================================================
--- src/Extensions/Banshee.CoverArt/CoverArtJob.cs (revision 0)
+++ src/Extensions/Banshee.CoverArt/CoverArtJob.cs (revision 0)
@@ -0,0 +1,100 @@
+// CoverArtJob.cs created with MonoDevelop
+// User: snorp at 11:42 AMÂ 5/25/2008
+//
+// To change standard headers go to Edit->Preferences->Coding->Standard Headers
+//
+
+using System;
+using System.Collections.Generic;
+using System.Data;
+using System.IO;
+using System.Threading;
+using Mono.Unix;
+
+using Banshee.Base;
+using Banshee.Collection;
+using Banshee.Collection.Gui;
+using Banshee.Kernel;
+using Banshee.Metadata;
+using Banshee.ServiceStack;
+using Hyena;
+using Gtk;
+
+namespace Banshee.CoverArt
+{
+ public class CoverArtJob : UserJob, IJob
+ {
+ private DateTime lastScan = DateTime.MinValue;
+
+ public CoverArtJob (DateTime last_scan) : base (Catalog.GetString ("Downloading Cover Art"))
+ {
+ lastScan = last_scan;
+ CanCancel = true;
+ }
+
+ public void Start ()
+ {
+ Register ();
+ Scheduler.Schedule (this);
+ }
+
+ public void Run ()
+ {
+ this.Status = Catalog.GetString ("Preparing...");
+
+ List<TrackInfo> tracks = new List<TrackInfo> ();
+ using (IDataReader reader = ServiceManager.DbConnection.Query ("select CoreAlbums.Title, " +
+ "CoreArtists.Name from CoreAlbums, " +
+ "CoreArtists, CoreTracks where CoreAlbums.ArtistID = " +
+ "CoreArtists.ArtistID AND CoreTracks.AlbumID = " +
+ "CoreAlbums.AlbumID AND CoreTracks.DateUpdatedStamp > " +
+ "? ORDER BY CoreAlbums.Title ASC",
+ DateTimeUtil.FromDateTime (lastScan))) {
+ while (reader.Read ()) {
+ if (!CoverArtSpec.CoverExists (reader.GetString (1),
+ reader.GetString (0))) {
+ TrackInfo track = new TrackInfo ();
+ track.AlbumTitle = reader.GetString (0);
+ track.ArtistName = reader.GetString (1);
+ tracks.Add (track);
+ }
+ }
+ }
+
+ if (tracks.Count == 0) {
+ Finish ();
+ return;
+ }
+
+ MetadataService metadata_service = MetadataService.Instance;
+ //ArtworkManager artwork_manager = ServiceManager.Get<Artworkmanager> ();
+
+ for (int i = 0; i < tracks.Count; i++) {
+ if (IsCancelRequested) {
+ break;
+ }
+
+ TrackInfo track = tracks[i];
+
+ this.Progress = (double) i / (double) tracks.Count;
+ this.Status = String.Format (Catalog.GetString ("Downloading cover art for '{0}'"), track.AlbumTitle);
+ IMetadataLookupJob job = metadata_service.CreateJob (track);
+ try {
+ job.Run ();
+ string cover_file = CoverArtSpec.GetPath (CoverArtSpec.CreateArtistAlbumId (track.ArtistName,
+ track.AlbumTitle));
+ if (File.Exists (cover_file)) {
+ IconNames = new string[] { CoverArtSpec.GetPath (CoverArtSpec.CreateArtistAlbumId (track.ArtistName,
+ track.AlbumTitle)) };
+ }
+ } catch (Exception e) {
+ Console.Error.WriteLine ("Metadata job failed: " + e);
+ }
+ }
+
+ Gtk.Application.Invoke (delegate {
+ Finish ();
+ });
+ }
+ }
+}
Index: src/Extensions/Banshee.CoverArt/Banshee.CoverArt.addin.xml
===================================================================
--- src/Extensions/Banshee.CoverArt/Banshee.CoverArt.addin.xml (revision 0)
+++ src/Extensions/Banshee.CoverArt/Banshee.CoverArt.addin.xml (revision 0)
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Addin
+ id="Banshee.CoverArt"
+ version="1.0"
+ compatVersion="1.0"
+ copyright="© 2008 Novell Inc. Licensed under the MIT X11 license."
+ name="Cover Art Fetching"
+ category="User Interface"
+ description="Provides UI to enable the user to fetch cover art"
+ author="James Willcox"
+ url="http://banshee-project.org/"
+ defaultEnabled="true">
+
+ <Dependencies>
+ <Addin id="Banshee.Services" version="1.0"/>
+ <Addin id="Banshee.ThickClient" version="1.0"/>
+ </Dependencies>
+
+ <Extension path="/Banshee/ServiceManager/Service">
+ <Service class="Banshee.CoverArt.CoverArtService"/>
+ </Extension>
+
+
+</Addin>
Index: src/Extensions/Banshee.CoverArt/Banshee.CoverArt.mdp
===================================================================
--- src/Extensions/Banshee.CoverArt/Banshee.CoverArt.mdp (revision 0)
+++ src/Extensions/Banshee.CoverArt/Banshee.CoverArt.mdp (revision 0)
@@ -0,0 +1,34 @@
+<Project name="Banshee.CoverArt" fileversion="2.0" language="C#" clr-version="Net_2_0" UseParentDirectoryAsNamespace="True" ctype="DotNetProject">
+ <Configurations active="Debug">
+ <Configuration name="Debug" ctype="DotNetProjectConfiguration">
+ <Output directory="../../../bin" assemblyKeyFile="." assembly="Banshee.CoverArt" />
+ <Build debugmode="True" target="Library" />
+ <Execution runwithwarnings="True" consolepause="True" runtime="MsNet" clr-version="Net_2_0" />
+ <CodeGeneration compiler="Mcs" warninglevel="4" optimize="True" unsafecodeallowed="False" generateoverflowchecks="True" generatexmldocumentation="False" ctype="CSharpCompilerParameters" />
+ </Configuration>
+ </Configurations>
+ <Contents>
+ <File name="Banshee.CoverArt.addin.xml" subtype="Code" buildaction="EmbedAsResource" />
+ <File name="CoverArtService.cs" subtype="Code" buildaction="Compile" />
+ <File name="Resources/CoverArtMenu.xml" subtype="Code" buildaction="EmbedAsResource" />
+ <File name="CoverArtJob.cs" subtype="Code" buildaction="Compile" />
+ </Contents>
+ <References>
+ <ProjectReference type="Project" localcopy="True" refto="Banshee.Core" />
+ <ProjectReference type="Project" localcopy="True" refto="Banshee.Services" />
+ <ProjectReference type="Project" localcopy="True" refto="Hyena" />
+ <ProjectReference type="Gac" localcopy="True" refto="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+ <ProjectReference type="Project" localcopy="True" refto="Banshee.ThickClient" />
+ <ProjectReference type="Project" localcopy="True" refto="Hyena.Gui" />
+ <ProjectReference type="Gac" localcopy="True" refto="System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+ </References>
+ <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>
+</Project>
\ No newline at end of file
Index: src/Extensions/Banshee.CoverArt/CoverArtService.cs
===================================================================
--- src/Extensions/Banshee.CoverArt/CoverArtService.cs (revision 0)
+++ src/Extensions/Banshee.CoverArt/CoverArtService.cs (revision 0)
@@ -0,0 +1,190 @@
+//
+// CoverArtService.cs
+//
+// Authors:
+// James Willcox <snorp novell com>
+//
+// Copyright (C) 2005-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.Data;
+using Gtk;
+using Mono.Unix;
+
+using Banshee.Base;
+using Banshee.Collection;
+using Banshee.Collection.Database;
+using Banshee.ServiceStack;
+using Banshee.Configuration;
+using Banshee.Gui;
+using Banshee.Collection.Gui;
+using Banshee.Library;
+using Banshee.Metadata;
+using Banshee.Sources;
+using Hyena;
+
+namespace Banshee.CoverArt
+{
+ public class CoverArtService : IExtensionService
+ {
+ private InterfaceActionService action_service;
+ private ActionGroup actions;
+ private bool disposed;
+ private uint ui_manager_id;
+
+ private CoverArtJob job;
+
+ public CoverArtService ()
+ {
+ }
+
+ void IExtensionService.Initialize ()
+ {
+ action_service = ServiceManager.Get<InterfaceActionService> ("InterfaceActionService");
+ ServiceManager.SourceManager.SourceAdded += OnSourceAdded;
+
+ if (!ServiceStartup ()) {
+ ServiceManager.ServiceStarted += OnServiceStarted;
+ }
+ }
+
+ private void OnSourceAdded (SourceAddedArgs args)
+ {
+ if (ServiceStartup ()) {
+ ServiceManager.SourceManager.SourceAdded -= OnSourceAdded;
+ }
+ }
+
+ private void OnServiceStarted (ServiceStartedArgs args)
+ {
+ if (args.Service is Banshee.Gui.InterfaceActionService) {
+ action_service = (InterfaceActionService)args.Service;
+ }
+
+ ServiceStartup ();
+ }
+
+ private bool ServiceStartup ()
+ {
+ if (action_service == null || ServiceManager.SourceManager.MusicLibrary == null) {
+ return false;
+ }
+
+ Initialize ();
+
+ ServiceManager.ServiceStarted -= OnServiceStarted;
+
+ return true;
+ }
+
+ private void Initialize ()
+ {
+ actions = new ActionGroup ("CoverArt");
+
+ ActionEntry[] action_list = new ActionEntry [] {
+ new ActionEntry ("CoverArtAction", null,
+ Catalog.GetString ("_Cover Art"), null,
+ Catalog.GetString ("Manage cover art"), null),
+ new ActionEntry ("FetchCoverArtAction", null,
+ Catalog.GetString ("_Download Cover Art"), null,
+ Catalog.GetString ("Download cover art for all tracks"), OnFetchCoverArt)
+ };
+
+ actions.Add (action_list);
+
+ action_service.UIManager.InsertActionGroup (actions, 0);
+ ui_manager_id = action_service.UIManager.AddUiFromResource ("CoverArtMenu.xml");
+
+ ServiceManager.SourceManager.MusicLibrary.TracksAdded += OnTracksAdded;
+ ServiceManager.SourceManager.MusicLibrary.TracksChanged += OnTracksChanged;
+ }
+
+ public void Dispose ()
+ {
+ if (disposed) {
+ return;
+ }
+
+ Gtk.Action fetch_action = action_service.GlobalActions["FetchCoverArtAction"];
+ if (fetch_action != null) {
+ action_service.GlobalActions.Remove (fetch_action);
+ }
+
+ action_service.RemoveActionGroup ("CoverArt");
+ action_service.UIManager.RemoveUi (ui_manager_id);
+
+ actions = null;
+ action_service = null;
+
+ ServiceManager.SourceManager.MusicLibrary.TracksAdded -= OnTracksAdded;
+ ServiceManager.SourceManager.MusicLibrary.TracksChanged -= OnTracksChanged;
+
+ disposed = true;
+ }
+
+ public void FetchCoverArt ()
+ {
+ if (job == null) {
+ job = new CoverArtJob (DateTime.Parse (LastScanDate.Get ()));
+ job.Finished += delegate {
+ LastScanDate.Set (DateTime.Now.ToString ());
+ job = null;
+ };
+ job.Start ();
+ }
+ }
+
+ private void OnFetchCoverArt (object o, EventArgs args)
+ {
+ FetchCoverArt ();
+ }
+
+ private void OnTracksAdded (Source sender, TrackEventArgs args)
+ {
+ FetchCoverArt ();
+ }
+
+ private void OnTracksChanged (Source sender, TrackEventArgs args)
+ {
+ FetchCoverArt ();
+ }
+
+ string IService.ServiceName {
+ get { return "CoverArtService"; }
+ }
+
+ public static readonly SchemaEntry<bool> EnabledSchema = new SchemaEntry<bool> (
+ "plugins.cover_art", "enabled",
+ true,
+ "Plugin enabled",
+ "Cover art plugin enabled"
+ );
+
+ public static readonly SchemaEntry<string> LastScanDate = new SchemaEntry<string> (
+ "plugins.cover_art", "last_scan_date",
+ "",
+ "Last scan date",
+ "Date of last scan"
+ );
+ }
+}
Index: src/Extensions/Makefile.am
===================================================================
--- src/Extensions/Makefile.am (revision 3968)
+++ src/Extensions/Makefile.am (working copy)
@@ -2,6 +2,7 @@
Banshee.AudioCd \
Banshee.Bookmarks \
Banshee.BooScript \
+ Banshee.CoverArt \
Banshee.Daap \
Banshee.Lastfm \
Banshee.MiniMode \
Index: src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/UserJobTile.cs
===================================================================
--- src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/UserJobTile.cs (revision 3968)
+++ src/Core/Banshee.ThickClient/Banshee.Gui.Widgets/UserJobTile.cs (working copy)
@@ -239,7 +239,16 @@
if (icon_pixbuf != null) {
icon.Pixbuf = icon_pixbuf;
icon.Show ();
+ return;
}
+
+ icon_pixbuf = new Gdk.Pixbuf (icon_names[0]);
+ if (icon_pixbuf != null) {
+ Gdk.Pixbuf scaled = icon_pixbuf.ScaleSimple (22, 22, Gdk.InterpType.Bilinear);
+ icon_pixbuf.Dispose ();
+ icon.Pixbuf = scaled;
+ icon.Show ();
+ }
}
private void OnJobUpdated (object o, EventArgs args)
Index: src/Core/Banshee.Services/Banshee.Metadata.Rhapsody/RhapsodyQueryJob.cs
===================================================================
--- src/Core/Banshee.Services/Banshee.Metadata.Rhapsody/RhapsodyQueryJob.cs (revision 3968)
+++ src/Core/Banshee.Services/Banshee.Metadata.Rhapsody/RhapsodyQueryJob.cs (working copy)
@@ -98,6 +98,8 @@
AddTag(tag);
}
}
+
+ response.Close ();
}
}
}
Index: src/Core/Banshee.Services/Banshee.Metadata.Embedded/EmbeddedQueryJob.cs
===================================================================
--- src/Core/Banshee.Services/Banshee.Metadata.Embedded/EmbeddedQueryJob.cs (revision 3968)
+++ src/Core/Banshee.Services/Banshee.Metadata.Embedded/EmbeddedQueryJob.cs (working copy)
@@ -60,7 +60,7 @@
protected void Fetch()
{
- if (!track.Uri.IsFile)
+ if (track.Uri == null || !track.Uri.IsFile)
return;
string artist_album_id = track.ArtworkId;
Index: build/build.environment.mk
===================================================================
--- build/build.environment.mk (revision 3968)
+++ build/build.environment.mk (working copy)
@@ -111,6 +111,7 @@
REF_EXTENSION_AUDIOCD = $(LINK_BANSHEE_THICKCLIENT_DEPS) $(LINK_MUSICBRAINZ_DEPS)
REF_EXTENSION_BOOKMARKS = $(LINK_BANSHEE_THICKCLIENT_DEPS)
REF_EXTENSION_BOOSCRIPT = $(LINK_BANSHEE_THICKCLIENT_DEPS) $(LINK_BOO)
+REF_EXTENSION_COVERART = $(LINK_BANSHEE_THICKCLIENT_DEPS)
REF_EXTENSION_DAAP = $(LINK_BANSHEE_THICKCLIENT_DEPS) $(LINK_ICSHARP_ZIP_LIB) $(LINK_MONO_ZEROCONF)
REF_EXTENSION_MINIMODE = $(LINK_BANSHEE_THICKCLIENT_DEPS)
REF_EXTENSION_MULTIMEDIAKEYS = $(LINK_BANSHEE_SERVICES_DEPS)
Index: configure.ac
===================================================================
--- configure.ac (revision 3968)
+++ configure.ac (working copy)
@@ -158,6 +158,7 @@
src/Extensions/Banshee.AudioCd/Makefile
src/Extensions/Banshee.Bookmarks/Makefile
src/Extensions/Banshee.BooScript/Makefile
+src/Extensions/Banshee.CoverArt/Makefile
src/Extensions/Banshee.Daap/Makefile
src/Extensions/Banshee.Lastfm/Makefile
src/Extensions/Banshee.MiniMode/Makefile
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]