banshee r3580 - in trunk/banshee: . build build/pkg-config src/Core/Banshee.Core/Resources src/Extensions/Banshee.AudioCd src/Extensions/Banshee.AudioCd/Banshee.AudioCd src/Libraries src/Libraries/MusicBrainz src/Libraries/MusicBrainz/MusicBrainz
- From: abock svn gnome org
- To: svn-commits-list gnome org
- Subject: banshee r3580 - in trunk/banshee: . build build/pkg-config src/Core/Banshee.Core/Resources src/Extensions/Banshee.AudioCd src/Extensions/Banshee.AudioCd/Banshee.AudioCd src/Libraries src/Libraries/MusicBrainz src/Libraries/MusicBrainz/MusicBrainz
- Date: Sat, 29 Mar 2008 00:05:09 +0000 (GMT)
Author: abock
Date: Sat Mar 29 00:05:08 2008
New Revision: 3580
URL: http://svn.gnome.org/viewvc/banshee?rev=3580&view=rev
Log:
2008-03-28 Aaron Bockover <abock gnome org>
* build/build.environment.mk:
* build/pkg-config/banshee-1-core.pc.in:
* build/pkg-config/banshee-1-musicbrainz.pc.in:
* configure.ac:
* src/Libraries/Libraries.mds:
* src/Libraries/Makefile.am:
* src/Libraries/MusicBrainz/: Added Scott's musicbrainz-sharp code locally
to the project for now; in the future we will just depend on the library
but for now we'll incubate it
* src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdDiscModel.cs:
Renamed from AudioCdDisc, inhereit MemoryTrackListModel
* src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdService.cs:
* src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdSource.cs:
Changes to reflect the model stuff
Added:
trunk/banshee/build/pkg-config/banshee-1-musicbrainz.pc.in
trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdDiscModel.cs
- copied, changed from r3578, /trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdDisc.cs
trunk/banshee/src/Libraries/MusicBrainz/ (props changed)
trunk/banshee/src/Libraries/MusicBrainz/Makefile.am
trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/
trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz.mdp
trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Artist.cs
trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Disc.cs
trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/DiscLinux.cs
trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/DiscWin32.cs
trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Event.cs
trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Label.cs
trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/LocalDisc.cs
trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/MusicBrainzEntity.cs
trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/MusicBrainzException.cs
trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/MusicBrainzItem.cs
trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/MusicBrainzObject.cs
trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/MusicBrainzService.cs
trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Query.cs
trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Relation.cs
trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Release.cs
trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Track.cs
trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Utils.cs
trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/XmlRequestEventArgs.cs
Removed:
trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdDisc.cs
Modified:
trunk/banshee/ChangeLog
trunk/banshee/build/build.environment.mk
trunk/banshee/build/pkg-config/banshee-1-core.pc.in
trunk/banshee/configure.ac
trunk/banshee/src/Core/Banshee.Core/Resources/translators.xml
trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd.mdp
trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdService.cs
trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdSource.cs
trunk/banshee/src/Extensions/Banshee.AudioCd/Makefile.am
trunk/banshee/src/Libraries/Libraries.mds
trunk/banshee/src/Libraries/Makefile.am
Modified: trunk/banshee/build/build.environment.mk
==============================================================================
--- trunk/banshee/build/build.environment.mk (original)
+++ trunk/banshee/build/build.environment.mk Sat Mar 29 00:05:08 2008
@@ -78,6 +78,11 @@
LINK_MONO_MEDIA = -r:$(DIR_BIN)/Mono.Media.dll
LINK_MONO_MEDIA_DEPS = $(REF_MONO_MEDIA) $(LINK_MONO_MEDIA)
+# MusicBrainz
+REF_MUSICBRAINZ = $(LINK_SYSTEM)
+LINK_MUSICBRAINZ = -r:$(DIR_BIN)/MusicBrainz.dll
+LINK_MUSICBRAINZ_DEPS = $(REF_MUSICBRAINZ) $(LINK_MUSICBRAINZ)
+
#DIR_MUSICBRAINZ = $(DIR_LIBRARIES)/MusicBrainz
#MONO_BASE_PATH += $(DIR_MUSICBRAINZ)
#REF_MUSICBRAINZ = $(LINK_SYSTEM)
@@ -120,7 +125,7 @@
REF_BACKEND_HAL = $(LINK_BANSHEE_SERVICES_DEPS) $(LINK_DBUS)
# Extensions
-REF_EXTENSION_AUDIOCD = $(LINK_BANSHEE_SERVICES_DEPS)
+REF_EXTENSION_AUDIOCD = $(LINK_BANSHEE_SERVICES_DEPS) $(LINK_MUSICBRAINZ_DEPS)
REF_EXTENSION_BOOKMARKS = $(LINK_BANSHEE_THICKCLIENT_DEPS)
REF_EXTENSION_MULTIMEDIAKEYS = $(LINK_BANSHEE_SERVICES_DEPS)
REF_EXTENSION_NOTIFICATIONAREA = $(LINK_BANSHEE_THICKCLIENT_DEPS)
Modified: trunk/banshee/build/pkg-config/banshee-1-core.pc.in
==============================================================================
--- trunk/banshee/build/pkg-config/banshee-1-core.pc.in (original)
+++ trunk/banshee/build/pkg-config/banshee-1-core.pc.in Sat Mar 29 00:05:08 2008
@@ -6,5 +6,5 @@
Name: Banshee Core
Description: Core APIs for the Banshee Media Framework
Version: @VERSION@
-Requires: taglib-sharp ndesk-dbus-1.0 ndesk-dbus-glib-1.0 glib-sharp-2.0 mono-addins banshee-1-hyena
+Requires: taglib-sharp ndesk-dbus-1.0 ndesk-dbus-glib-1.0 glib-sharp-2.0 mono-addins banshee-1-hyena banshee-1-musicbrainz
Libs: -r:${bansheedir}/Banshee.Core.dll
Added: trunk/banshee/build/pkg-config/banshee-1-musicbrainz.pc.in
==============================================================================
--- (empty file)
+++ trunk/banshee/build/pkg-config/banshee-1-musicbrainz.pc.in Sat Mar 29 00:05:08 2008
@@ -0,0 +1,10 @@
+prefix= prefix@
+exec_prefix=${prefix}
+libdir=${exec_prefix}/lib
+bansheedir=${libdir}/banshee-1
+
+Name: Banshee MusicBrainz
+Description: MusicBrainz libraries for the Banshee Media Framework
+Version: @VERSION@
+Libs: -r:System -r:${bansheedir}/MusicBrainz.dll
+
Modified: trunk/banshee/configure.ac
==============================================================================
--- trunk/banshee/configure.ac (original)
+++ trunk/banshee/configure.ac Sat Mar 29 00:05:08 2008
@@ -152,6 +152,7 @@
src/Libraries/Lastfm/Makefile
src/Libraries/Lastfm.Gui/Makefile
src/Libraries/Mono.Media/Makefile
+src/Libraries/MusicBrainz/Makefile
src/Extensions/Makefile
src/Extensions/Banshee.AudioCd/Makefile
Modified: trunk/banshee/src/Core/Banshee.Core/Resources/translators.xml
==============================================================================
--- trunk/banshee/src/Core/Banshee.Core/Resources/translators.xml (original)
+++ trunk/banshee/src/Core/Banshee.Core/Resources/translators.xml Sat Mar 29 00:05:08 2008
@@ -82,8 +82,8 @@
<person>Kjartan Maraas</person>
</language>
<language code="nl" name="Dutch">
- <person>Pepijn van de Geer</person>
<person>Wouter Bolsterlee</person>
+ <person>Pepijn van de Geer</person>
<person>Stijn Verslycken</person>
</language>
<language code="oc" name="Occitan">
Modified: trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd.mdp
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd.mdp (original)
+++ trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd.mdp Sat Mar 29 00:05:08 2008
@@ -11,13 +11,14 @@
<File name="Banshee.AudioCd.addin.xml" subtype="Code" buildaction="EmbedAsResource" />
<File name="Banshee.AudioCd/AudioCdService.cs" subtype="Code" buildaction="Compile" />
<File name="Banshee.AudioCd/AudioCdSource.cs" subtype="Code" buildaction="Compile" />
- <File name="Banshee.AudioCd/AudioCdDisc.cs" subtype="Code" buildaction="Compile" />
+ <File name="Banshee.AudioCd/AudioCdDiscModel.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="MusicBrainz" />
</References>
<MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="True" RelativeMakefileName="./Makefile.am">
<BuildFilesVar Sync="True" Name="SOURCES" />
Copied: trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdDiscModel.cs (from r3578, /trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdDisc.cs)
==============================================================================
--- /trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdDisc.cs (original)
+++ trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdDiscModel.cs Sat Mar 29 00:05:08 2008
@@ -28,17 +28,25 @@
using System;
+using MusicBrainz;
using Banshee.Hardware;
+using Banshee.Collection;
namespace Banshee.AudioCd
{
- public class AudioCdDisc
+ public class AudioCdDiscModel : MemoryTrackListModel
{
private IDiscVolume volume;
- public AudioCdDisc (IDiscVolume volume)
+ public AudioCdDiscModel (IDiscVolume volume)
{
this.volume = volume;
+ ReadDisc ();
+ }
+
+ private void ReadDisc ()
+ {
+
}
public IDiscVolume Volume {
Modified: trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdService.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdService.cs (original)
+++ trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdService.cs Sat Mar 29 00:05:08 2008
@@ -74,7 +74,7 @@
{
lock (this) {
if (!sources.ContainsKey (volume.Uuid) && volume.HasAudio) {
- AudioCdSource source = new AudioCdSource (this, new AudioCdDisc (volume));
+ AudioCdSource source = new AudioCdSource (this, new AudioCdDiscModel (volume));
sources.Add (volume.Uuid, source);
ServiceManager.SourceManager.AddSource (source);
Log.DebugFormat ("Mapping audio CD ({0})", volume.Uuid);
Modified: trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdSource.cs
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdSource.cs (original)
+++ trunk/banshee/src/Extensions/Banshee.AudioCd/Banshee.AudioCd/AudioCdSource.cs Sat Mar 29 00:05:08 2008
@@ -38,16 +38,13 @@
public class AudioCdSource : Source, ITrackModelSource, IUnmapableSource, IDisposable
{
private AudioCdService service;
- private AudioCdDisc disc;
- private MemoryTrackListModel track_model;
+ private AudioCdDiscModel disc_model;
- public AudioCdSource (AudioCdService service, AudioCdDisc disc)
- : base (Catalog.GetString ("Audio CD"), disc.Title, 200)
+ public AudioCdSource (AudioCdService service, AudioCdDiscModel discModel)
+ : base (Catalog.GetString ("Audio CD"), discModel.Title, 200)
{
this.service = service;
- this.disc = disc;
-
- track_model = new MemoryTrackListModel ();
+ this.disc_model = discModel;
Properties.SetStringList ("Icon.Name", "media-cdrom", "gnome-dev-cdrom-audio", "source-cd-audio");
Properties.SetString ("UnmapSourceActionLabel", Catalog.GetString ("Eject Disc"));
@@ -57,8 +54,8 @@
{
}
- public AudioCdDisc Disc {
- get { return disc; }
+ public AudioCdDiscModel DiscModel {
+ get { return disc_model; }
}
#region Source Overrides
@@ -77,7 +74,7 @@
}
public override int Count {
- get { return track_model.Count; }
+ get { return disc_model.Count; }
}
#endregion
@@ -85,7 +82,7 @@
#region ITrackModelSource Implementation
public TrackListModel TrackModel {
- get { return track_model; }
+ get { return disc_model; }
}
public AlbumListModel AlbumModel {
@@ -98,7 +95,7 @@
public void Reload ()
{
- track_model.Reload ();
+ disc_model.Reload ();
}
public void RemoveSelectedTracks ()
@@ -137,15 +134,15 @@
{
System.Threading.ThreadPool.QueueUserWorkItem (delegate {
try {
- disc.Volume.Unmount ();
- disc.Volume.Eject ();
+ disc_model.Volume.Unmount ();
+ disc_model.Volume.Eject ();
} catch (Exception e) {
Log.Error (Catalog.GetString ("Could not eject Audio CD"), e.Message, true);
Log.Exception (e);
}
});
- service.UnmapDiscVolume (disc.Volume.Uuid);
+ service.UnmapDiscVolume (disc_model.Volume.Uuid);
return true;
}
Modified: trunk/banshee/src/Extensions/Banshee.AudioCd/Makefile.am
==============================================================================
--- trunk/banshee/src/Extensions/Banshee.AudioCd/Makefile.am (original)
+++ trunk/banshee/src/Extensions/Banshee.AudioCd/Makefile.am Sat Mar 29 00:05:08 2008
@@ -4,7 +4,7 @@
INSTALL_DIR = $(EXTENSIONS_INSTALL_DIR)
SOURCES = \
- Banshee.AudioCd/AudioCdDisc.cs \
+ Banshee.AudioCd/AudioCdDiscModel.cs \
Banshee.AudioCd/AudioCdService.cs \
Banshee.AudioCd/AudioCdSource.cs
Modified: trunk/banshee/src/Libraries/Libraries.mds
==============================================================================
--- trunk/banshee/src/Libraries/Libraries.mds (original)
+++ trunk/banshee/src/Libraries/Libraries.mds Sat Mar 29 00:05:08 2008
@@ -6,14 +6,16 @@
<Entry build="True" name="Lastfm" configuration="Debug" />
<Entry build="True" name="Lastfm.Gui" configuration="Debug" />
<Entry build="True" name="Mono.Media" configuration="Debug" />
+ <Entry build="True" name="MusicBrainz" configuration="Debug" />
</Configuration>
</Configurations>
- <StartMode startupentry="Nereid" single="True">
+ <StartMode startupentry="MusicBrainz" single="True">
<Execute type="None" entry="Hyena" />
<Execute type="None" entry="Hyena.Gui" />
<Execute type="None" entry="Lastfm" />
<Execute type="None" entry="Lastfm.Gui" />
<Execute type="None" entry="Mono.Media" />
+ <Execute type="None" entry="MusicBrainz" />
</StartMode>
<Entries>
<Entry filename="Hyena/Hyena.mdp" />
@@ -21,5 +23,6 @@
<Entry filename="Lastfm/Lastfm.mdp" />
<Entry filename="Lastfm.Gui/Lastfm.Gui.mdp" />
<Entry filename="Mono.Media/Mono.Media.mdp" />
+ <Entry filename="MusicBrainz/MusicBrainz.mdp" />
</Entries>
</Combine>
\ No newline at end of file
Modified: trunk/banshee/src/Libraries/Makefile.am
==============================================================================
--- trunk/banshee/src/Libraries/Makefile.am (original)
+++ trunk/banshee/src/Libraries/Makefile.am Sat Mar 29 00:05:08 2008
@@ -2,6 +2,7 @@
Hyena \
Hyena.Gui \
Mono.Media \
+ MusicBrainz \
Lastfm \
Lastfm.Gui
Added: trunk/banshee/src/Libraries/MusicBrainz/Makefile.am
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/MusicBrainz/Makefile.am Sat Mar 29 00:05:08 2008
@@ -0,0 +1,25 @@
+ASSEMBLY = MusicBrainz
+TARGET = library
+LINK = $(REF_MUSICBRAINZ)
+SOURCES = \
+ MusicBrainz/Artist.cs \
+ MusicBrainz/Disc.cs \
+ MusicBrainz/DiscLinux.cs \
+ MusicBrainz/DiscWin32.cs \
+ MusicBrainz/Event.cs \
+ MusicBrainz/Label.cs \
+ MusicBrainz/LocalDisc.cs \
+ MusicBrainz/MusicBrainzEntity.cs \
+ MusicBrainz/MusicBrainzException.cs \
+ MusicBrainz/MusicBrainzItem.cs \
+ MusicBrainz/MusicBrainzObject.cs \
+ MusicBrainz/MusicBrainzService.cs \
+ MusicBrainz/Query.cs \
+ MusicBrainz/Relation.cs \
+ MusicBrainz/Release.cs \
+ MusicBrainz/Track.cs \
+ MusicBrainz/Utils.cs \
+ MusicBrainz/XmlRequestEventArgs.cs
+
+include $(top_srcdir)/build/build.mk
+
Added: trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz.mdp
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz.mdp Sat Mar 29 00:05:08 2008
@@ -0,0 +1,43 @@
+<Project name="MusicBrainz" fileversion="2.0" language="C#" clr-version="Net_2_0" ctype="DotNetProject">
+ <Configurations active="Debug">
+ <Configuration name="Debug" ctype="DotNetProjectConfiguration">
+ <Output directory="../../../bin" assembly="MusicBrainz" />
+ <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="MusicBrainz/Artist.cs" subtype="Code" buildaction="Compile" />
+ <File name="MusicBrainz/Disc.cs" subtype="Code" buildaction="Compile" />
+ <File name="MusicBrainz/DiscLinux.cs" subtype="Code" buildaction="Compile" />
+ <File name="MusicBrainz/DiscWin32.cs" subtype="Code" buildaction="Compile" />
+ <File name="MusicBrainz/Event.cs" subtype="Code" buildaction="Compile" />
+ <File name="MusicBrainz/Label.cs" subtype="Code" buildaction="Compile" />
+ <File name="MusicBrainz/LocalDisc.cs" subtype="Code" buildaction="Compile" />
+ <File name="MusicBrainz/MusicBrainzEntity.cs" subtype="Code" buildaction="Compile" />
+ <File name="MusicBrainz/MusicBrainzException.cs" subtype="Code" buildaction="Compile" />
+ <File name="MusicBrainz/MusicBrainzItem.cs" subtype="Code" buildaction="Compile" />
+ <File name="MusicBrainz/MusicBrainzObject.cs" subtype="Code" buildaction="Compile" />
+ <File name="MusicBrainz/MusicBrainzService.cs" subtype="Code" buildaction="Compile" />
+ <File name="MusicBrainz/Query.cs" subtype="Code" buildaction="Compile" />
+ <File name="MusicBrainz/Relation.cs" subtype="Code" buildaction="Compile" />
+ <File name="MusicBrainz/Release.cs" subtype="Code" buildaction="Compile" />
+ <File name="MusicBrainz/Track.cs" subtype="Code" buildaction="Compile" />
+ <File name="MusicBrainz/Utils.cs" subtype="Code" buildaction="Compile" />
+ <File name="MusicBrainz/XmlRequestEventArgs.cs" subtype="Code" buildaction="Compile" />
+ </Contents>
+ <References>
+ <ProjectReference type="Gac" localcopy="True" refto="System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
+ </References>
+ <Deployment.LinuxDeployData generateScript="False" />
+ <MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="True" RelativeMakefileName="Makefile.am">
+ <BuildFilesVar Sync="True" Name="SOURCES" />
+ <DeployFilesVar />
+ <ResourcesVar />
+ <OthersVar />
+ <GacRefVar />
+ <AsmRefVar />
+ <ProjectRefVar />
+ </MonoDevelop.Autotools.MakefileInfo>
+</Project>
\ No newline at end of file
Added: trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Artist.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Artist.cs Sat Mar 29 00:05:08 2008
@@ -0,0 +1,200 @@
+/***************************************************************************
+ * Artist.cs
+ *
+ * Authored by Scott Peterson <lunchtimemama gmail com>
+ *
+ * The author disclaims copyright to this source code.
+ ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Text;
+using System.Xml;
+
+namespace MusicBrainz
+{
+ public enum ArtistType
+ {
+ Unknown,
+ Group,
+ Person
+ }
+
+ public sealed class ArtistReleaseType
+ {
+ string str;
+
+ public ArtistReleaseType (ReleaseType type, bool various) : this ((Enum)type, various)
+ {
+ }
+
+ public ArtistReleaseType (ReleaseStatus status, bool various) : this ((Enum)status, various)
+ {
+ }
+
+ ArtistReleaseType (Enum enumeration, bool various)
+ {
+ str = various
+ ? "va-" + Utils.EnumToString (enumeration)
+ : "sa-" + Utils.EnumToString (enumeration);
+ }
+
+ public override string ToString ()
+ {
+ return str;
+ }
+
+ }
+
+ public sealed class Artist : MusicBrainzEntity
+ {
+ const string EXTENSION = "artist";
+
+ protected override string UrlExtension {
+ get { return EXTENSION; }
+ }
+
+ public static ArtistReleaseType DefaultArtistReleaseType =
+ new ArtistReleaseType (ReleaseStatus.Official, false);
+
+ ArtistReleaseType artist_release_type = DefaultArtistReleaseType;
+
+ public ArtistReleaseType ArtistReleaseType {
+ get { return artist_release_type; }
+ set {
+ artist_release_type = value;
+ releases = null;
+ have_all_releases = false;
+ }
+ }
+
+ Artist (string mbid) : base (mbid, null)
+ {
+ }
+
+ Artist (string mbid, string parameters) : base (mbid, parameters)
+ {
+ }
+
+ Artist (string mbid, ArtistReleaseType artist_release_type)
+ : this (mbid, "&inc=" + artist_release_type.ToString ())
+ {
+ have_all_releases = true;
+ this.artist_release_type = artist_release_type;
+ }
+
+ internal Artist (XmlReader reader) : base (reader, false)
+ {
+ }
+
+ protected override void HandleCreateInc (StringBuilder builder)
+ {
+ AppendIncParameters (builder, artist_release_type.ToString ());
+ base.HandleCreateInc (builder);
+ }
+
+ protected override void HandleLoadMissingData ()
+ {
+ Artist artist = new Artist (Id, CreateInc ());
+ type = artist.Type;
+ base.HandleLoadMissingData (artist);
+ }
+
+ protected override bool HandleAttributes (XmlReader reader)
+ {
+ switch (reader ["type"]) {
+ case "Group":
+ type = ArtistType.Group;
+ break;
+ case "Person":
+ type = ArtistType.Person;
+ break;
+ }
+ return type != ArtistType.Unknown;
+ }
+
+ protected override bool HandleXml (XmlReader reader)
+ {
+ reader.Read ();
+ bool result = base.HandleXml (reader);
+ if (!result) {
+ result = true;
+ switch (reader.Name) {
+ case "release-list":
+ if (reader.ReadToDescendant ("release")) {
+ List<Release> releases = new List<Release> ();
+ do releases.Add (new Release (reader.ReadSubtree ()));
+ while (reader.ReadToNextSibling ("release"));
+ this.releases = releases.AsReadOnly ();
+ }
+ break;
+ default:
+ reader.Skip (); // FIXME this is a workaround for Mono bug 334752
+ result = false;
+ break;
+ }
+ }
+ reader.Close ();
+ return result;
+ }
+
+ #region Properties
+
+ [Queryable ("arid")]
+ public override string Id {
+ get { return base.Id; }
+ }
+
+ [Queryable ("artist")]
+ public override string Name {
+ get { return base.Name; }
+ }
+
+ ArtistType? type;
+ [Queryable ("artype")]
+ public ArtistType Type {
+ get { return GetPropertyOrDefault (ref type, ArtistType.Unknown); }
+ }
+
+ ReadOnlyCollection<Release> releases;
+ bool have_all_releases;
+ public ReadOnlyCollection<Release> Releases {
+ get {
+ return releases ?? (have_all_releases
+ ? releases = new ReadOnlyCollection<Release> (new Release [0])
+ : new Artist (Id, artist_release_type).Releases);
+ }
+ }
+
+ #endregion
+
+ #region Static
+
+ public static Artist Get (string mbid)
+ {
+ if (mbid == null) throw new ArgumentNullException ("mbid");
+ return new Artist (mbid);
+ }
+
+ public static Query<Artist> Query (string name)
+ {
+ if (name == null) throw new ArgumentNullException ("name");
+ return new Query<Artist> (EXTENSION, QueryLimit, CreateNameParameter (name));
+ }
+
+ public static Query<Artist> QueryLucene (string luceneQuery)
+ {
+ if (luceneQuery == null) throw new ArgumentNullException ("luceneQuery");
+ return new Query<Artist> (EXTENSION, QueryLimit, CreateLuceneParameter (luceneQuery));
+ }
+
+ public static implicit operator string (Artist artist)
+ {
+ return artist.ToString ();
+ }
+
+ #endregion
+
+ }
+}
Added: trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Disc.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Disc.cs Sat Mar 29 00:05:08 2008
@@ -0,0 +1,41 @@
+/***************************************************************************
+ * Disc.cs
+ *
+ * Authored by Scott Peterson <lunchtimemama gmail com>
+ *
+ * The author disclaims copyright to this source code.
+ ****************************************************************************/
+
+using System;
+using System.Xml;
+
+namespace MusicBrainz
+{
+ public class Disc
+ {
+ string id;
+ int sectors;
+
+ internal Disc ()
+ {
+ }
+
+ internal Disc (XmlReader reader)
+ {
+ reader.Read ();
+ int.TryParse (reader ["sectors"], out sectors);
+ id = reader ["id"];
+ reader.Close ();
+ }
+
+ public string Id {
+ get { return id; }
+ protected set { id = value; }
+ }
+
+ public int Sectors {
+ get { return sectors; }
+ protected set { sectors = value; }
+ }
+ }
+}
Added: trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/DiscLinux.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/DiscLinux.cs Sat Mar 29 00:05:08 2008
@@ -0,0 +1,150 @@
+/***************************************************************************
+ * DiscLinux.cs
+ *
+ * Authored by Scott Peterson <lunchtimemama gmail com>
+ *
+ * The author disclaims copyright to this source code.
+ ****************************************************************************/
+
+// This is based on $Id: disc_linux.c 8505 2006-09-30 00:02:18Z luks $
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace MusicBrainz
+{
+ internal sealed class DiscLinux : LocalDisc
+ {
+ const int O_RDONLY = 0x0;
+ const int O_NONBLOCK = 0x4000;
+ const int CDROMREADTOCHDR = 0x5305;
+ const int CDROMREADTOCENTRY = 0x5306;
+ const int CDROMMULTISESSION = 0x5310;
+ const int CDROM_LBA = 0x01;
+ const int CDROM_LEADOUT = 0xAA;
+ const int CD_FRAMES = 75;
+ const int XA_INTERVAL = ((60 + 90 + 2) * CD_FRAMES);
+
+ [DllImport ("libc.so.6")]
+ static extern int open (string path, int flags);
+
+ [DllImport ("libc.so.6")]
+ static extern int close (int fd);
+
+ [DllImport ("libc.so.6", EntryPoint = "ioctl")]
+ static extern int read_toc_header (int fd, int request, ref cdrom_tochdr header);
+ static int read_toc_header (int fd, ref cdrom_tochdr header)
+ {
+ return read_toc_header (fd, CDROMREADTOCHDR, ref header);
+ }
+
+ [DllImport ("libc.so.6", EntryPoint = "ioctl")]
+ static extern int read_multisession (int fd, int request, ref cdrom_multisession multisession);
+ static int read_multisession (int fd, ref cdrom_multisession multisession)
+ {
+ return read_multisession (fd, CDROMMULTISESSION, ref multisession);
+ }
+
+ [DllImport ("libc.so.6", EntryPoint = "ioctl")]
+ static extern int read_toc_entry (int fd, int request, ref cdrom_tocentry entry);
+ static int read_toc_entry (int fd, ref cdrom_tocentry entry)
+ {
+ return read_toc_entry (fd, CDROMREADTOCENTRY, ref entry);
+ }
+
+ struct cdrom_tochdr
+ {
+ public byte cdth_trk0;
+ public byte cdth_trk1;
+ }
+
+ struct cdrom_tocentry
+ {
+ public byte cdte_track;
+ public byte adr_ctrl;
+ public byte cdte_format;
+ public int lba;
+ public byte cdte_datamode;
+ }
+
+ struct cdrom_multisession
+ {
+ public int lba;
+ public byte xa_flag;
+ public byte addr_format;
+ }
+
+ int ReadTocHeader (int fd)
+ {
+ cdrom_tochdr th = new cdrom_tochdr ();
+ cdrom_multisession ms = new cdrom_multisession ();
+
+ int ret = read_toc_header (fd, ref th);
+
+ if (ret < 0) return ret;
+
+ FirstTrack = th.cdth_trk0;
+ LastTrack = th.cdth_trk1;
+
+ ms.addr_format = CDROM_LBA;
+ ret = read_multisession (fd, ref ms);
+
+ if(ms.xa_flag != 0) LastTrack--;
+
+ return ret;
+ }
+
+ int ReadTocEntry (int fd, byte track_number, ref ulong lba)
+ {
+ cdrom_tocentry te = new cdrom_tocentry ();
+ te.cdte_track = track_number;
+ te.cdte_format = CDROM_LBA;
+
+ int ret = read_toc_entry (fd, ref te);
+
+ if(ret == 0) lba = (ulong)te.lba;
+
+ return ret;
+ }
+
+ int ReadLeadout (int fd, ref ulong lba)
+ {
+ cdrom_multisession ms = new cdrom_multisession ();
+ ms.addr_format = CDROM_LBA;
+
+ int ret = read_multisession (fd, ref ms);
+
+ if (ms.xa_flag != 0) {
+ lba = (ulong)(ms.lba - XA_INTERVAL);
+ return ret;
+ }
+
+ return ReadTocEntry (fd, CDROM_LEADOUT, ref lba);
+ }
+
+ internal DiscLinux (string device)
+ {
+ int fd = open (device, O_RDONLY | O_NONBLOCK);
+
+ if (fd < 0) throw new Exception (String.Format ("Cannot open device '{0}'", device));
+
+ try {
+ if (ReadTocHeader(fd) < 0) throw new Exception ("Cannot read table of contents");
+ if (LastTrack == 0) throw new Exception ("This disc has no tracks");
+
+ ulong lba = 0;
+ ReadLeadout (fd, ref lba);
+ TrackOffsets [0] = (int)lba + 150;
+
+ for (byte i = FirstTrack; i <= LastTrack; i++) {
+ ReadTocEntry (fd, i, ref lba);
+ TrackOffsets[i] = (int)lba + 150;
+ }
+ } finally {
+ close (fd);
+ }
+
+ Init ();
+ }
+ }
+}
Added: trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/DiscWin32.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/DiscWin32.cs Sat Mar 29 00:05:08 2008
@@ -0,0 +1,108 @@
+/***************************************************************************
+ * DiscWin32.cs
+ *
+ * Authored by Scott Peterson <lunchtimemama gmail com>
+ *
+ * The author disclaims copyright to this source code.
+ ****************************************************************************/
+
+// This is based on $Id: disc_win32.c 8506 2006-09-30 19:02:57Z luks $
+
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
+
+namespace MusicBrainz
+{
+ internal sealed class DiscWin32 : LocalDisc
+ {
+ [DllImport ("winmm")]
+ static extern Int32 mciSendString (String command,
+ StringBuilder buffer,
+ Int32 bufferSize,
+ IntPtr hwndCallback);
+
+ [DllImport ("winmm")]
+ static extern Int32 mciGetErrorString (Int32 errorCode,
+ StringBuilder errorText,
+ Int32 errorTextSize);
+
+ delegate void MciCall (string result);
+
+ internal DiscWin32 (string device)
+ {
+ string device_string = device.Length == 0
+ ? "cdaudio" : string.Format ("{0} type cdaudio", device);
+
+ string alias = string.Format ("musicbrainz_cdio_{0}_{1}",
+ Environment.TickCount, Thread.CurrentThread.ManagedThreadId);
+
+ MciClosure (
+ "sysinfo cdaudio quantity wait",
+ "Could not get the list of CD audio devices",
+ delegate (string result) {
+ if (int.Parse (result.ToString ()) <= 0)
+ throw new Exception ("No CD audio devices present.");
+ });
+
+ MciClosure (
+ string.Format ("open {0} shareable alias {1} wait", device_string, alias),
+ string.Format ("Could not open device {0}", device),
+ null);
+
+ MciClosure (
+ string.Format ("status {0} number of tracks wait", alias),
+ "Could not read number of tracks",
+ delegate (string result) {
+ FirstTrack = 1;
+ LastTrack = byte.Parse (result);
+ });
+
+ MciClosure (
+ string.Format ("set {0} time format msf wait", alias),
+ "Could not set time format",
+ null);
+
+ for (int i = 1; i <= LastTrack; i++)
+ MciClosure (
+ string.Format ("status {0} position track {1} wait", alias, i),
+ string.Format ("Could not get position for track {0}", i),
+ delegate (string result) {
+ TrackOffsets [i] =
+ int.Parse (result.Substring (0,2)) * 4500 +
+ int.Parse (result.Substring (3,2)) * 75 +
+ int.Parse (result.Substring (6,2));
+ });
+
+ MciClosure (
+ string.Format ("status {0} length track {1} wait", alias, LastTrack),
+ "Could not read the length of the last track",
+ delegate (string result) {
+ TrackOffsets [0] =
+ int.Parse (result.Substring (0, 2)) * 4500 +
+ int.Parse (result.Substring (3, 2)) * 75 +
+ int.Parse (result.Substring (6, 2)) +
+ TrackOffsets [LastTrack] + 1;
+ });
+
+ MciClosure (
+ string.Format ("close {0} wait", alias),
+ string.Format ("Could not close device {0}", device),
+ null);
+
+ Init ();
+ }
+
+ static StringBuilder mci_result = new StringBuilder (128);
+ static StringBuilder mci_error = new StringBuilder (256);
+ static void MciClosure (string command, string failure_message, MciCall code)
+ {
+ int ret = mciSendString (command, mci_result, mci_result.Capacity, IntPtr.Zero);
+ if (ret != 0) {
+ mciGetErrorString (ret, mci_error, mci_error.Capacity);
+ throw new Exception (string.Format ("{0} : {1}", failure_message, mci_error.ToString ()));
+ } else if (code != null) code (mci_result.ToString ());
+ }
+ }
+}
Added: trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Event.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Event.cs Sat Mar 29 00:05:08 2008
@@ -0,0 +1,62 @@
+/***************************************************************************
+ * Event.cs
+ *
+ * Authored by Scott Peterson <lunchtimemama gmail com>
+ *
+ * The author disclaims copyright to this source code.
+ ****************************************************************************/
+
+using System;
+using System.Xml;
+
+namespace MusicBrainz
+{
+ public sealed class Event
+ {
+ string date;
+ string country;
+ string catalog_number;
+ string barcode;
+ Label label;
+ ReleaseFormat format = ReleaseFormat.None;
+
+ internal Event (XmlReader reader)
+ {
+ reader.Read ();
+ date = reader ["date"];
+ country = reader ["country"];
+ catalog_number = reader ["catalog-number"];
+ barcode = reader ["barcode"];
+ format = Utils.StringToEnum<ReleaseFormat> (reader ["format"]);
+ if (reader.ReadToDescendant ("label")) {
+ label = new Label (reader.ReadSubtree ());
+ reader.Read (); // FIXME this is a workaround for Mono bug 334752
+ }
+ reader.Close ();
+ }
+
+ public string Date {
+ get { return date; }
+ }
+
+ public string Country {
+ get { return country; }
+ }
+
+ public string CatalogNumber {
+ get { return catalog_number; }
+ }
+
+ public string Barcode {
+ get { return barcode; }
+ }
+
+ public Label Label {
+ get { return label; }
+ }
+
+ public ReleaseFormat Format {
+ get { return format; }
+ }
+ }
+}
Added: trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Label.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Label.cs Sat Mar 29 00:05:08 2008
@@ -0,0 +1,112 @@
+/***************************************************************************
+ * Label.cs
+ *
+ * Authored by Scott Peterson <lunchtimemama gmail com>
+ *
+ * The author disclaims copyright to this source code.
+ ****************************************************************************/
+
+using System;
+using System.Text;
+using System.Xml;
+
+namespace MusicBrainz
+{
+ public enum LabelType
+ {
+ Unspecified,
+ Distributor,
+ Holding,
+ OriginalProduction,
+ BootlegProduction,
+ ReissueProduction
+ }
+
+ public sealed class Label : MusicBrainzEntity
+ {
+ const string EXTENSION = "label";
+
+ protected override string UrlExtension {
+ get { return EXTENSION; }
+ }
+
+ Label (string mbid) : base (mbid, null)
+ {
+ }
+
+ Label (string mbid, string parameters) : base (mbid, parameters)
+ {
+ }
+
+ internal Label (XmlReader reader) : base (reader, false)
+ {
+ }
+
+ protected override void HandleLoadMissingData ()
+ {
+ Label label = new Label (Id, CreateInc ());
+ type = label.Type;
+ base.HandleLoadMissingData (label);
+ }
+
+ protected override bool HandleAttributes (XmlReader reader)
+ {
+ type = Utils.StringToEnum<LabelType> (reader ["type"]);
+ return this.type != null;
+ }
+
+ protected override bool HandleXml (XmlReader reader)
+ {
+ reader.Read ();
+ bool result = base.HandleXml (reader);
+ if (!result) {
+ if (reader.Name == "country") {
+ result = true;
+ reader.Read ();
+ if (reader.NodeType == XmlNodeType.Text)
+ country = reader.ReadContentAsString ();
+ } else reader.Skip (); // FIXME this is a workaround for Mono bug 334752
+ }
+ reader.Close ();
+ return result;
+ }
+
+ string country;
+ public string Country {
+ get { return GetPropertyOrNull (ref country); }
+ }
+
+ LabelType? type;
+ public LabelType Type {
+ get { return GetPropertyOrDefault (ref type, LabelType.Unspecified); }
+ }
+
+ #region Static
+
+ public static Label Get (string mbid)
+ {
+ if (mbid == null) throw new ArgumentNullException ("mbid");
+ return new Label (mbid);
+ }
+
+ public static Query<Label> Query (string name)
+ {
+ if (name == null) throw new ArgumentNullException ("name");
+ return new Query<Label> (EXTENSION, QueryLimit, CreateNameParameter (name));
+ }
+
+ public static Query<Label> QueryLucene (string luceneQuery)
+ {
+ if (luceneQuery == null) throw new ArgumentNullException ("luceneQuery");
+ return new Query<Label> (EXTENSION, QueryLimit, CreateLuceneParameter (luceneQuery));
+ }
+
+ public static implicit operator string (Label label)
+ {
+ return label.ToString ();
+ }
+
+ #endregion
+
+ }
+}
Added: trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/LocalDisc.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/LocalDisc.cs Sat Mar 29 00:05:08 2008
@@ -0,0 +1,113 @@
+/***************************************************************************
+ * LocalDisc.cs
+ *
+ * Authored by Scott Peterson <lunchtimemama gmail com>
+ *
+ * The author disclaims copyright to this source code.
+ ****************************************************************************/
+
+using System;
+using System.Security.Cryptography;
+using System.Text;
+
+namespace MusicBrainz
+{
+ public abstract class LocalDisc : Disc
+ {
+ byte first_track;
+ byte last_track;
+ int [] track_durations;
+ int [] track_offsets = new int [100];
+
+ internal LocalDisc()
+ {
+ }
+
+ protected void Init ()
+ {
+ track_durations = new int [last_track];
+ for (int i = 1; i <= last_track; i++) {
+ track_durations [i - 1] = i < last_track
+ ? track_offsets [i + 1] - track_offsets [i]
+ : track_offsets [0] - track_offsets [i];
+ track_durations [i - 1] /= 75; // 75 frames in a second
+ }
+ GenerateId ();
+ }
+
+ void GenerateId ()
+ {
+ StringBuilder input_builder = new StringBuilder (804);
+
+ input_builder.Append (string.Format ("{0:X2}", FirstTrack));
+ input_builder.Append (string.Format ("{0:X2}", LastTrack));
+
+ for (int i = 0; i < track_offsets.Length; i++)
+ input_builder.Append (string.Format ("{0:X8}", track_offsets [i]));
+
+ // MB uses a slightly modified RFC822 for reasons of URL happiness.
+ string base64 = Convert.ToBase64String (SHA1.Create ()
+ .ComputeHash (Encoding.ASCII.GetBytes (input_builder.ToString ())));
+ StringBuilder hash_builder = new StringBuilder (base64.Length);
+
+ foreach (char c in base64)
+ if (c == '+') hash_builder.Append ('.');
+ else if (c == '/') hash_builder.Append ('_');
+ else if (c == '=') hash_builder.Append ('-');
+ else hash_builder.Append (c);
+
+ Id = hash_builder.ToString ();
+ }
+
+ protected byte FirstTrack {
+ get { return first_track; }
+ set { first_track = value; }
+ }
+
+ protected byte LastTrack {
+ get { return last_track; }
+ set { last_track = value; }
+ }
+
+ protected int [] TrackOffsets {
+ get { return track_offsets; }
+ }
+
+ public int [] TrackDurations {
+ get { return track_durations; }
+ }
+
+ string submission_url;
+ public string SubmissionUrl {
+ get {
+ if (submission_url == null) {
+ StringBuilder builder = new StringBuilder ();
+ builder.Append ("http://mm.musicbrainz.org/bare/cdlookup.html");
+ builder.Append ("?id=");
+ builder.Append (Id);
+ builder.Append ("&tracks=");
+ builder.Append (last_track);
+ builder.Append ("&toc=");
+ builder.Append (first_track);
+ builder.Append ('+');
+ builder.Append (last_track);
+ builder.Append ('+');
+ builder.Append (track_offsets [0]);
+ for (int i = first_track; i <= last_track; i++) {
+ builder.Append ('+');
+ builder.Append (track_offsets [i]);
+ }
+ submission_url = builder.ToString ();
+ }
+ return submission_url;
+ }
+ }
+
+ public static LocalDisc GetFromDevice (string device)
+ {
+ if (device == null) throw new ArgumentNullException ("device");
+ return Environment.OSVersion.Platform != PlatformID.Unix
+ ? (LocalDisc)new DiscWin32 (device) : new DiscLinux (device);
+ }
+ }
+}
Added: trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/MusicBrainzEntity.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/MusicBrainzEntity.cs Sat Mar 29 00:05:08 2008
@@ -0,0 +1,135 @@
+/***************************************************************************
+ * MusicBrainzEntity.cs
+ *
+ * Authored by Scott Peterson <lunchtimemama gmail com>
+ *
+ * The author disclaims copyright to this source code.
+ ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Text;
+using System.Xml;
+
+namespace MusicBrainz
+{
+ // A person-like entity, such as an artist or a label.
+ public abstract class MusicBrainzEntity : MusicBrainzObject
+ {
+ internal MusicBrainzEntity (string mbid, string parameters) : base (mbid, parameters)
+ {
+ }
+
+ internal MusicBrainzEntity (XmlReader reader, bool all_rels_loaded) : base (reader, all_rels_loaded)
+ {
+ }
+
+ protected override void HandleCreateInc (StringBuilder builder)
+ {
+ if (aliases == null) AppendIncParameters (builder, "aliases");
+ base.HandleCreateInc (builder);
+ }
+
+ protected void HandleLoadMissingData (MusicBrainzEntity entity)
+ {
+ name = entity.Name;
+ sort_name = entity.SortName;
+ disambiguation = entity.Disambiguation;
+ begin_date = entity.BeginDate;
+ end_date = entity.EndDate;
+ if (aliases == null) aliases = entity.Aliases;
+ base.HandleLoadMissingData (entity);
+ }
+
+ protected override bool HandleXml (XmlReader reader)
+ {
+ bool result = true;
+ switch (reader.Name) {
+ case "name":
+ reader.Read ();
+ if (reader.NodeType == XmlNodeType.Text)
+ name = reader.ReadContentAsString ();
+ break;
+ case "sort-name":
+ reader.Read ();
+ if (reader.NodeType == XmlNodeType.Text)
+ sort_name = reader.ReadContentAsString ();
+ break;
+ case "disambiguation":
+ reader.Read ();
+ if (reader.NodeType == XmlNodeType.Text)
+ disambiguation = reader.ReadContentAsString ();
+ break;
+ case "life-span":
+ begin_date = reader ["begin"];
+ end_date = reader ["end"];
+ break;
+ case "alias-list":
+ if (reader.ReadToDescendant ("alias")) {
+ List<string> aliases = new List<string> ();
+ do {
+ reader.Read ();
+ if (reader.NodeType == XmlNodeType.Text)
+ aliases.Add (reader.ReadContentAsString ());
+ } while (reader.ReadToNextSibling ("alias"));
+ this.aliases = aliases.AsReadOnly ();
+ }
+ break;
+ default:
+ result = false;
+ break;
+ }
+ return result;
+ }
+
+ # region Properties
+
+ string name;
+ public virtual string Name {
+ get { return GetPropertyOrNull (ref name); }
+ }
+
+ string sort_name;
+ [Queryable]
+ public virtual string SortName {
+ get { return GetPropertyOrNull (ref sort_name); }
+ }
+
+ string disambiguation;
+ [Queryable ("comment")]
+ public virtual string Disambiguation {
+ get { return GetPropertyOrNull (ref disambiguation); }
+ }
+
+ string begin_date;
+ [Queryable ("begin")]
+ public virtual string BeginDate {
+ get { return GetPropertyOrNull (ref begin_date); }
+ }
+
+ string end_date;
+ [Queryable ("end")]
+ public virtual string EndDate {
+ get { return GetPropertyOrNull (ref end_date); }
+ }
+
+ ReadOnlyCollection<string> aliases;
+ [QueryableMember ("Contains", "alias")]
+ public virtual ReadOnlyCollection<string> Aliases {
+ get { return GetPropertyOrNew (ref aliases); }
+ }
+
+ #endregion
+
+ protected static string CreateNameParameter (string name)
+ {
+ return "&name=" + Utils.PercentEncode (name);
+ }
+
+ public override string ToString ()
+ {
+ return name;
+ }
+ }
+}
Added: trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/MusicBrainzException.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/MusicBrainzException.cs Sat Mar 29 00:05:08 2008
@@ -0,0 +1,36 @@
+/***************************************************************************
+ * MusicBrainzException.cs
+ *
+ * Authored by Scott Peterson <lunchtimemama gmail com>
+ *
+ * The author disclaims copyright to this source code.
+ ****************************************************************************/
+
+using System;
+
+namespace MusicBrainz
+{
+ public sealed class MusicBrainzInvalidParameterException : Exception
+ {
+ public MusicBrainzInvalidParameterException ()
+ : base ("One of the parameters is invalid. The MBID may be invalid, or you may be using an illegal parameter for this resource type.")
+ {
+ }
+ }
+
+ public sealed class MusicBrainzNotFoundException : Exception
+ {
+ public MusicBrainzNotFoundException ()
+ : base ("Specified resource was not found. Perhaps it was merged or deleted.")
+ {
+ }
+ }
+
+ public sealed class MusicBrainzUnauthorizedException : Exception
+ {
+ public MusicBrainzUnauthorizedException ()
+ : base ("The client is not authorized to perform this action. You may not have authenticated, or the username or password may be incorrect.")
+ {
+ }
+ }
+}
Added: trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/MusicBrainzItem.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/MusicBrainzItem.cs Sat Mar 29 00:05:08 2008
@@ -0,0 +1,144 @@
+/***************************************************************************
+ * MusicBrainzItem.cs
+ *
+ * Authored by Scott Peterson <lunchtimemama gmail com>
+ *
+ * The author disclaims copyright to this source code.
+ ****************************************************************************/
+
+using System;
+using System.Text;
+using System.Xml;
+
+namespace MusicBrainz
+{
+ public abstract class ItemQueryParameters
+ {
+ internal ItemQueryParameters ()
+ {
+ }
+
+ string title;
+ public string Title {
+ get { return title; }
+ set { title = value; }
+ }
+
+ string artist;
+ public string Artist {
+ get { return artist; }
+ set { artist = value; }
+ }
+
+ string artist_id;
+ public string ArtistId {
+ get { return artist_id; }
+ set { artist_id = value; }
+ }
+
+ ReleaseType? release_type;
+ public ReleaseType? ReleaseType {
+ get { return release_type; }
+ set { release_type = value; }
+ }
+
+ ReleaseStatus? release_status;
+ public ReleaseStatus? ReleaseStatus {
+ get { return release_status; }
+ set { release_status = value; }
+ }
+
+ int? count;
+ public int? TrackCount {
+ get { return count; }
+ set { count = value; }
+ }
+
+ protected void AppendBaseToBuilder (StringBuilder builder)
+ {
+ if (title != null) {
+ builder.Append ("&title=");
+ Utils.PercentEncode (builder, title);
+ }
+ if (artist != null) {
+ builder.Append ("&artist=");
+ Utils.PercentEncode (builder, artist);
+ }
+ if (artist_id != null) {
+ builder.Append ("&artistid=");
+ builder.Append (artist_id);
+ }
+ if (release_type != null) {
+ builder.Append ("&releasetypes=");
+ builder.Append (Utils.EnumToString (release_type.Value));
+ }
+ if (release_status != null) {
+ builder.Append (release_type != null ? "+" : "&releasetypes=");
+ builder.Append (release_status);
+ }
+ if (count != null) {
+ builder.Append ("&count=");
+ builder.Append (count.Value);
+ }
+ }
+ }
+
+ // The item-like product of an artist, such as a track or a release.
+ public abstract class MusicBrainzItem : MusicBrainzObject
+ {
+ internal MusicBrainzItem (string mbid, string parameters) : base (mbid, parameters)
+ {
+ }
+
+ internal MusicBrainzItem (XmlReader reader, bool all_rels_loaded) : base (reader, all_rels_loaded)
+ {
+ }
+
+ protected override void HandleCreateInc (StringBuilder builder)
+ {
+ if (artist == null) AppendIncParameters(builder, "artist");
+ base.HandleCreateInc (builder);
+ }
+
+ protected void HandleLoadMissingData (MusicBrainzItem item)
+ {
+ title = item.Title;
+ if (artist == null) artist = item.Artist;
+ base.HandleLoadMissingData (item);
+ }
+
+ protected override bool HandleXml (XmlReader reader)
+ {
+ bool result = true;
+ switch (reader.Name) {
+ case "title":
+ reader.Read ();
+ if (reader.NodeType == XmlNodeType.Text)
+ title = reader.ReadContentAsString ();
+ break;
+ case "artist":
+ artist = new Artist (reader.ReadSubtree ());
+ break;
+ default:
+ result = false;
+ break;
+ }
+ return result;
+ }
+
+ string title;
+ public virtual string Title {
+ get { return GetPropertyOrNull (ref title); }
+ }
+
+ Artist artist;
+ [Queryable ("artist")]
+ public virtual Artist Artist {
+ get { return GetPropertyOrNull (ref artist); }
+ }
+
+ public override string ToString () {
+ return title;
+ }
+ }
+}
Added: trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/MusicBrainzObject.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/MusicBrainzObject.cs Sat Mar 29 00:05:08 2008
@@ -0,0 +1,421 @@
+/***************************************************************************
+ * MusicBrainzObject.cs
+ *
+ * Authored by Scott Peterson <lunchtimemama gmail com>
+ *
+ * The author disclaims copyright to this source code.
+ ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
+using System.Net;
+using System.Reflection;
+using System.Text;
+using System.Threading;
+using System.Xml;
+
+namespace MusicBrainz
+{
+ internal delegate void XmlProcessingDelegate (XmlReader reader);
+
+ public abstract class MusicBrainzObject
+ {
+ static TimeSpan min_interval = new TimeSpan (0, 0, 1); // 1 second
+ static DateTime last_accessed;
+ static readonly object server_mutex = new object ();
+
+ bool all_data_loaded;
+ protected bool AllDataLoaded {
+ get { return all_data_loaded; }
+ }
+
+ bool all_rels_loaded;
+ protected bool AllRelsLoaded {
+ get { return all_rels_loaded; }
+ set { all_rels_loaded = value; }
+ }
+
+ protected abstract string UrlExtension { get; }
+
+ internal MusicBrainzObject (string mbid, string parameters)
+ {
+ all_data_loaded = true;
+ CreateFromMbid (mbid, parameters ?? CreateInc ());
+ }
+
+ internal MusicBrainzObject (XmlReader reader, bool all_rels_loaded)
+ {
+ this.all_rels_loaded = all_rels_loaded;
+ CreateFromXml (reader);
+ }
+
+ protected string CreateInc ()
+ {
+ StringBuilder builder = new StringBuilder ();
+ HandleCreateInc (builder);
+ return builder.ToString ();
+ }
+
+ static string [] rels_params = new string [] {
+ "artist-rels",
+ "release-rels",
+ "track-rels",
+ "label-rels",
+ "url-rels"
+ };
+
+ protected virtual void HandleCreateInc (StringBuilder builder)
+ {
+ if (!all_rels_loaded)
+ AppendIncParameters (builder, rels_params);
+ }
+
+ protected void AppendIncParameters (StringBuilder builder, string parameter)
+ {
+ builder.Append (builder.Length == 0 ? "&inc=" : "+");
+ builder.Append (parameter);
+ }
+
+ protected void AppendIncParameters (StringBuilder builder, string parameter1, string parameter2)
+ {
+ builder.Append (builder.Length == 0 ? "&inc=" : "+");
+ builder.Append (parameter1);
+ builder.Append ('+');
+ builder.Append (parameter2);
+ }
+
+ protected void AppendIncParameters (StringBuilder builder, string [] parameters)
+ {
+ foreach (string parameter in parameters)
+ AppendIncParameters (builder, parameter);
+ }
+
+ void CreateFromMbid (string mbid, string parameters)
+ {
+ XmlProcessingClosure (
+ CreateUrl (UrlExtension, mbid, parameters),
+ delegate (XmlReader reader) {
+ reader.ReadToFollowing ("metadata");
+ reader.Read ();
+ CreateFromXml (reader.ReadSubtree ());
+ reader.Close ();
+ }
+ );
+ }
+
+ protected abstract bool HandleAttributes (XmlReader reader);
+ protected abstract bool HandleXml (XmlReader reader);
+ void CreateFromXml (XmlReader reader)
+ {
+ reader.Read ();
+ id = reader ["id"];
+ byte.TryParse (reader ["ext:score"], out score);
+ HandleAttributes (reader);
+ while (reader.Read () && reader.NodeType != XmlNodeType.EndElement) {
+ if (reader.Name == "relation-list") {
+ all_rels_loaded = true;
+ switch (reader ["target-type"]) {
+ case "Artist":
+ List<Relation<Artist>> artist_rels = new List<Relation<Artist>> ();
+ CreateRelation (reader.ReadSubtree (), artist_rels);
+ this.artist_rels = artist_rels.AsReadOnly ();
+ break;
+ case "Release":
+ List<Relation<Release>> release_rels = new List<Relation<Release>> ();
+ CreateRelation (reader.ReadSubtree (), release_rels);
+ this.release_rels = release_rels.AsReadOnly ();
+ break;
+ case "Track":
+ List<Relation<Track>> track_rels = new List<Relation<Track>> ();
+ CreateRelation (reader.ReadSubtree (), track_rels);
+ this.track_rels = track_rels.AsReadOnly ();
+ break;
+ case "Label":
+ List<Relation<Label>> label_rels = new List<Relation<Label>> ();
+ CreateRelation (reader.ReadSubtree (), label_rels);
+ this.label_rels = label_rels.AsReadOnly ();
+ break;
+ case "Url":
+ if (!reader.ReadToDescendant ("relation")) break;
+ List<UrlRelation> url_rels = new List<UrlRelation> ();
+ do {
+ RelationDirection direction = RelationDirection.Forward;
+ string direction_string = reader ["direction"];
+ if (direction_string != null && direction_string == "backward")
+ direction = RelationDirection.Backward;
+ string attributes_string = reader ["attributes"];
+ string [] attributes = attributes_string == null
+ ? null : attributes_string.Split (' ');
+ url_rels.Add (new UrlRelation (
+ reader ["type"],
+ reader ["target"],
+ direction,
+ reader ["begin"],
+ reader ["end"],
+ attributes));
+ } while (reader.ReadToNextSibling ("relation"));
+ this.url_rels = url_rels.AsReadOnly ();
+ break;
+ }
+ } else
+ HandleXml (reader.ReadSubtree ());
+ }
+ reader.Close ();
+ }
+
+ protected void LoadMissingData ()
+ {
+ if (!all_data_loaded) {
+ HandleLoadMissingData ();
+ all_data_loaded = true;
+ }
+ }
+
+ protected abstract void HandleLoadMissingData ();
+ protected void HandleLoadMissingData (MusicBrainzObject obj)
+ {
+ if (!all_rels_loaded) {
+ artist_rels = obj.ArtistRelations;
+ release_rels = obj.ReleaseRelations;
+ track_rels = obj.TrackRelations;
+ label_rels = obj.LabelRelations;
+ url_rels = obj.UrlRelations;
+ }
+ }
+
+ #region Properties
+
+ protected T GetPropertyOrNull<T> (ref T field_reference) where T : class
+ {
+ if (field_reference == null) LoadMissingData ();
+ return field_reference;
+ }
+
+ protected T GetPropertyOrDefault<T> (ref T? field_reference, T default_value) where T : struct
+ {
+ if (field_reference == null) LoadMissingData ();
+ return field_reference ?? default_value;
+ }
+
+ protected ReadOnlyCollection<T> GetPropertyOrNew<T> (ref ReadOnlyCollection<T> field_reference)
+ {
+ return GetPropertyOrNew (ref field_reference, true);
+ }
+
+ protected ReadOnlyCollection<T> GetPropertyOrNew<T> (ref ReadOnlyCollection<T> field_reference, bool condition)
+ {
+ if (field_reference == null && condition) LoadMissingData ();
+ return field_reference ?? new ReadOnlyCollection<T> (new T [0]);
+ }
+
+ string id;
+ public virtual string Id {
+ get { return id; }
+ }
+
+ byte score;
+ public virtual byte Score {
+ get { return score; }
+ }
+
+ ReadOnlyCollection<Relation<Artist>> artist_rels;
+ public virtual ReadOnlyCollection<Relation<Artist>> ArtistRelations {
+ get { return GetPropertyOrNew (ref artist_rels, !all_rels_loaded); }
+ }
+
+ ReadOnlyCollection<Relation<Release>> release_rels;
+ public virtual ReadOnlyCollection<Relation<Release>> ReleaseRelations {
+ get { return GetPropertyOrNew (ref release_rels, !all_rels_loaded); }
+ }
+
+ ReadOnlyCollection<Relation<Track>> track_rels;
+ public virtual ReadOnlyCollection<Relation<Track>> TrackRelations {
+ get { return GetPropertyOrNew (ref track_rels, !all_rels_loaded); }
+ }
+
+ ReadOnlyCollection<Relation<Label>> label_rels;
+ public virtual ReadOnlyCollection<Relation<Label>> LabelRelations {
+ get { return GetPropertyOrNew (ref label_rels, !all_rels_loaded); }
+ }
+
+ ReadOnlyCollection<UrlRelation> url_rels;
+ public virtual ReadOnlyCollection<UrlRelation> UrlRelations {
+ get { return GetPropertyOrNew (ref url_rels, !all_rels_loaded); }
+ }
+
+ public override bool Equals (object obj)
+ {
+ MusicBrainzObject mbobj = obj as MusicBrainzObject;
+ return mbobj != null && mbobj.GetType ().Equals (GetType ()) && mbobj.Id == Id;
+ }
+
+ public override int GetHashCode ()
+ {
+ return (GetType ().Name + Id).GetHashCode ();
+ }
+
+ #endregion
+
+ #region Static
+
+ static void CreateRelation<T> (XmlReader reader, List<Relation<T>> relations) where T : MusicBrainzObject
+ {
+ while (reader.ReadToFollowing ("relation")) {
+ string type = reader ["type"];
+ RelationDirection direction = RelationDirection.Forward;
+ string direction_string = reader ["direction"];
+ if (direction_string != null && direction_string == "backward")
+ direction = RelationDirection.Backward;
+ string begin = reader ["begin"];
+ string end = reader ["end"];
+ string attributes_string = reader ["attributes"];
+ string [] attributes = attributes_string == null
+ ? null : attributes_string.Split (' ');
+
+ reader.Read ();
+ relations.Add (new Relation<T> (
+ type,
+ ConstructMusicBrainzObjectFromXml<T> (reader.ReadSubtree ()),
+ direction,
+ begin,
+ end,
+ attributes));
+ }
+ reader.Close ();
+ }
+
+ static string CreateUrl (string url_extension, int limit, int offset, string parameters)
+ {
+ StringBuilder builder = new StringBuilder ();
+ if (limit != 25) {
+ builder.Append ("&limit=");
+ builder.Append (limit);
+ }
+ if (offset != 0) {
+ builder.Append ("&offset=");
+ builder.Append (offset);
+ }
+ builder.Append (parameters);
+ return CreateUrl (url_extension, string.Empty, builder.ToString ());
+ }
+
+ static string CreateUrl (string url_extension, string mbid, string parameters)
+ {
+ StringBuilder builder = new StringBuilder (
+ MusicBrainzService.ProviderUrl.Length + mbid.Length + parameters.Length + 9);
+ builder.Append (MusicBrainzService.ProviderUrl);
+ builder.Append (url_extension);
+ builder.Append ('/');
+ builder.Append (mbid);
+ builder.Append ("?type=xml");
+ builder.Append (parameters);
+ return builder.ToString ();
+ }
+
+ static void XmlProcessingClosure (string url, XmlProcessingDelegate code)
+ {
+ Monitor.Enter (server_mutex);
+
+ // Don't access the MB server twice within a second
+ TimeSpan time = DateTime.Now - last_accessed;
+ if (min_interval > time)
+ Thread.Sleep ((min_interval - time).Milliseconds);
+
+ HttpWebRequest request = WebRequest.Create (url) as HttpWebRequest;
+ bool cache_implemented = false;
+
+ try {
+ request.CachePolicy = MusicBrainzService.CachePolicy;
+ cache_implemented = true;
+ } catch (NotImplementedException) {
+ }
+
+ HttpWebResponse response = null;
+
+ try {
+ response = request.GetResponse () as HttpWebResponse;
+ } catch (WebException e) {
+ response = (HttpWebResponse)e.Response;
+ }
+
+ if (response == null) throw new MusicBrainzNotFoundException ();
+
+ switch (response.StatusCode) {
+ case HttpStatusCode.BadRequest:
+ Monitor.Exit (server_mutex);
+ throw new MusicBrainzInvalidParameterException ();
+ case HttpStatusCode.Unauthorized:
+ Monitor.Exit (server_mutex);
+ throw new MusicBrainzUnauthorizedException ();
+ case HttpStatusCode.NotFound:
+ Monitor.Exit (server_mutex);
+ throw new MusicBrainzNotFoundException ();
+ }
+
+ bool from_cache = cache_implemented && response.IsFromCache;
+
+ MusicBrainzService.OnXmlRequest (url, from_cache);
+
+ if (from_cache) Monitor.Exit (server_mutex);
+
+ // Should we read the stream into a memory stream and run the XmlReader off of that?
+ code (new XmlTextReader (response.GetResponseStream ()));
+ response.Close ();
+
+ if (!from_cache) {
+ last_accessed = DateTime.Now;
+ Monitor.Exit (server_mutex);
+ }
+ }
+
+ #endregion
+
+ #region Query
+
+ protected static byte QueryLimit {
+ get { return 100; }
+ }
+
+ protected static string CreateLuceneParameter (string query)
+ {
+ return "&query=" + Utils.PercentEncode (query);
+ }
+
+ internal static List<T> Query<T> (string url_extension,
+ byte limit, int offset,
+ string parameters,
+ out int? count) where T : MusicBrainzObject
+ {
+ int count_value = 0;
+ List<T> results = new List<T> ();
+ XmlProcessingClosure (
+ CreateUrl (url_extension, limit, offset, parameters),
+ delegate (XmlReader reader) {
+ reader.ReadToFollowing ("metadata");
+ reader.Read ();
+ int.TryParse (reader ["count"], out count_value);
+ while (reader.Read () && reader.NodeType == XmlNodeType.Element)
+ results.Add (ConstructMusicBrainzObjectFromXml<T> (reader.ReadSubtree ()));
+ reader.Close ();
+ }
+ );
+ count = count_value == 0 ? results.Count : count_value;
+ return results;
+ }
+
+ static T ConstructMusicBrainzObjectFromXml<T> (XmlReader reader) where T : MusicBrainzObject
+ {
+ ConstructorInfo constructor = typeof (T).GetConstructor (
+ BindingFlags.NonPublic | BindingFlags.Instance,
+ null,
+ new Type [] { typeof (XmlReader) },
+ null);
+ return (T)constructor.Invoke (new object [] {reader});
+ }
+
+ #endregion
+
+ }
+}
Added: trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/MusicBrainzService.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/MusicBrainzService.cs Sat Mar 29 00:05:08 2008
@@ -0,0 +1,26 @@
+/***************************************************************************
+ * MusicBrainzService.cs
+ *
+ * Authored by Scott Peterson <lunchtimemama gmail com>
+ *
+ * The author disclaims copyright to this source code.
+ ****************************************************************************/
+
+using System;
+using System.Net.Cache;
+
+namespace MusicBrainz
+{
+ public static class MusicBrainzService
+ {
+ public static string ProviderUrl = @"http://musicbrainz.org/ws/1/";
+ public static RequestCachePolicy CachePolicy;
+ public static event EventHandler<XmlRequestEventArgs> XmlRequest;
+
+ internal static void OnXmlRequest (string url, bool fromCache)
+ {
+ EventHandler<XmlRequestEventArgs> handler = XmlRequest;
+ if (handler != null) handler (null, new XmlRequestEventArgs (url, fromCache));
+ }
+ }
+}
Added: trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Query.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Query.cs Sat Mar 29 00:05:08 2008
@@ -0,0 +1,171 @@
+/***************************************************************************
+ * Query.cs
+ *
+ * Authored by Scott Peterson <lunchtimemama gmail com>
+ *
+ * The author disclaims copyright to this source code.
+ ****************************************************************************/
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MusicBrainz
+{
+ public sealed class Query<T> : IEnumerable<T> where T : MusicBrainzObject
+ {
+ string parameters;
+ string url_extension;
+ byte limit;
+
+ internal Query (string url_extension, byte limit, string parameters)
+ {
+ this.url_extension = url_extension;
+ this.limit = limit;
+ this.parameters = parameters;
+ }
+
+ List<T> results;
+ List<T> ResultsWindow {
+ get {
+ if (results == null)
+ results = MusicBrainzObject.Query<T> (url_extension, limit, offset, parameters, out count);
+ return results;
+ }
+ }
+
+ int offset;
+ Dictionary<int, WeakReference> weak_references = new Dictionary<int, WeakReference> ();
+ int Offset {
+ get { return offset; }
+ set {
+ if (value == offset) return;
+ // We WeakReference the results from previous offsets just in case.
+ if (results != null)
+ if (!weak_references.ContainsKey (offset))
+ weak_references.Add (offset, new WeakReference (results));
+ else weak_references [offset].Target = results;
+ results = null;
+ offset = value;
+ if (weak_references.ContainsKey (offset)) {
+ WeakReference weak_reference = weak_references [offset];
+ if (weak_reference.IsAlive)
+ results = weak_reference.Target as List<T>;
+ }
+ }
+ }
+
+ int? count;
+ public int Count {
+ get {
+ if(count == null && ResultsWindow == null) { } // just accessing ResultsWindow will give count a value
+ return count.Value;
+ }
+ }
+
+ public T this [int i] {
+ get {
+ if (i < 0 || i >= Count) throw new IndexOutOfRangeException ();
+ if (i <= offset || i >= offset + limit)
+ Offset = i;
+ return ResultsWindow [i - offset];
+ }
+ }
+
+ public List<T> ToList ()
+ {
+ return ToList (0);
+ }
+
+ public List<T> ToList (int score_threshold)
+ {
+ List<T> list = new List<T> (score_threshold == 0 ? Count : 0);
+ foreach (T result in Best(score_threshold)) list.Add (result);
+ return list;
+ }
+
+ public T [] ToArray ()
+ {
+ T [] array = new T [Count];
+ for(int i = 0; i < Count; i++) array [i] = this [i];
+ return array;
+ }
+
+ public IEnumerator<T> GetEnumerator ()
+ {
+ for (int i = 0; i < Count; i++) yield return this [i];
+ }
+
+ IEnumerator IEnumerable.GetEnumerator ()
+ {
+ return GetEnumerator ();
+ }
+
+ public IEnumerable<T> Best ()
+ {
+ return Best (100);
+ }
+
+ public IEnumerable<T> Best (int score_threshold)
+ {
+ foreach (T result in this) {
+ if (result.Score < score_threshold) yield break;
+ yield return result;
+ }
+ }
+
+ public T PerfectMatch ()
+ {
+ byte tmp_limit = limit;
+ limit = 2;
+ T result1 = Count > 0 ? this [0] : null;
+ T result2 = Count > 1 ? this [1] : null;
+ limit = tmp_limit;
+
+ return (result1 != null && result1.Score == 100 && (result2 == null || result2.Score < 100))
+ ? result1 : null;
+ }
+
+ public T First ()
+ {
+ byte tmp_limit = limit;
+ limit = 1;
+ T result = Count > 0 ? this [0] : null;
+ limit = tmp_limit;
+ return result;
+ }
+
+ public static implicit operator T (Query<T> query)
+ {
+ return query.First ();
+ }
+ }
+
+ [AttributeUsage (AttributeTargets.Property)]
+ internal sealed class QueryableAttribute : Attribute
+ {
+ public readonly string Name;
+
+ public QueryableAttribute ()
+ {
+ }
+
+ public QueryableAttribute (string name)
+ {
+ Name = name;
+ }
+ }
+
+ [AttributeUsage (AttributeTargets.Property)]
+ internal sealed class QueryableMemberAttribute : Attribute
+ {
+ public readonly string Name;
+ public readonly string Member;
+ public QueryableMemberAttribute (string member, string name)
+ {
+ Member = member;
+ Name = name;
+ }
+ }
+}
Added: trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Relation.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Relation.cs Sat Mar 29 00:05:08 2008
@@ -0,0 +1,89 @@
+/***************************************************************************
+ * Relation.cs
+ *
+ * Authored by Scott Peterson <lunchtimemama gmail com>
+ *
+ * The author disclaims copyright to this source code.
+ ****************************************************************************/
+
+using System;
+
+namespace MusicBrainz
+{
+ public enum RelationDirection
+ {
+ Forward,
+ Backward
+ }
+
+ public abstract class RelationPrimative<T>
+ {
+ T target;
+ string type;
+ string[] attributes;
+ RelationDirection direction;
+ string begin;
+ string end;
+
+ internal RelationPrimative (string type, T target, RelationDirection direction,
+ string begin, string end, string[] attributes)
+ {
+ this.type = type;
+ this.target = target;
+ this.direction = direction;
+ this.begin = begin;
+ this.end = end;
+ this.attributes = attributes;
+ }
+
+ public T Target {
+ get { return target; }
+ }
+
+ public string Type {
+ get { return type; }
+ }
+
+ public string [] Attributes {
+ get { return attributes; }
+ }
+
+ public RelationDirection Direction {
+ get { return direction; }
+ }
+
+ public string BeginDate {
+ get { return begin; }
+ }
+
+ public string EndDate {
+ get { return end; }
+ }
+ }
+
+ public sealed class Relation<T> : RelationPrimative<T> where T : MusicBrainzObject
+ {
+ internal Relation (string type,
+ T target,
+ RelationDirection direction,
+ string begin,
+ string end,
+ string [] attributes)
+ : base (type, target, direction, begin, end, attributes)
+ {
+ }
+ }
+
+ public sealed class UrlRelation : RelationPrimative<string>
+ {
+ internal UrlRelation(string type,
+ string target,
+ RelationDirection direction,
+ string begin,
+ string end,
+ string [] attributes)
+ : base (type, target, direction, begin, end, attributes)
+ {
+ }
+ }
+}
Added: trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Release.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Release.cs Sat Mar 29 00:05:08 2008
@@ -0,0 +1,364 @@
+/***************************************************************************
+ * Release.cs
+ *
+ * Authored by Scott Peterson <lunchtimemama gmail com>
+ *
+ * The author disclaims copyright to this source code.
+ ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Text;
+using System.Xml;
+
+namespace MusicBrainz
+{
+ # region Enums
+
+ public enum ReleaseType
+ {
+ None,
+ Album,
+ Single,
+ EP,
+ Compilation,
+ Soundtrack,
+ Spokenword,
+ Interview,
+ Audiobook,
+ Live,
+ Remix,
+ Other
+ }
+
+ public enum ReleaseStatus
+ {
+ None,
+ Official,
+ Promotion,
+ Bootleg,
+ PsudoRelease
+ }
+
+ public enum ReleaseFormat
+ {
+ None,
+ Cartridge,
+ Cassette,
+ CD,
+ DAT,
+ Digital,
+ DualDisc,
+ DVD,
+ LaserDisc,
+ MiniDisc,
+ Other,
+ ReelToReel,
+ SACD,
+ Vinyl
+ }
+
+ #endregion
+
+ public sealed class ReleaseQueryParameters : ItemQueryParameters
+ {
+ string disc_id;
+ public string DiscID {
+ get { return disc_id; }
+ set { disc_id = value; }
+ }
+
+ string date;
+ public string Date {
+ get { return date; }
+ set { date = value; }
+ }
+
+ string asin;
+ public string Asin {
+ get { return asin; }
+ set { asin = value; }
+ }
+
+ string language;
+ public string Language {
+ get { return language; }
+ set { language = value; }
+ }
+
+ string script;
+ public string Script {
+ get { return script; }
+ set { script = value; }
+ }
+
+ public override string ToString ()
+ {
+ StringBuilder builder = new StringBuilder ();
+ if (disc_id != null) {
+ builder.Append ("&discid=");
+ builder.Append (disc_id);
+ }
+ if (date != null) {
+ builder.Append ("&date=");
+ Utils.PercentEncode (builder, date);
+ }
+ if (asin != null) {
+ builder.Append ("&asin=");
+ builder.Append (asin);
+ }
+ if (language != null) {
+ builder.Append ("&lang=");
+ builder.Append (language);
+ }
+ if (script != null) {
+ builder.Append ("&script=");
+ builder.Append (script);
+ }
+ AppendBaseToBuilder (builder);
+ return builder.ToString ();
+ }
+ }
+
+ public sealed class Release : MusicBrainzItem
+ {
+ const string EXTENSION = "release";
+
+ protected override string UrlExtension {
+ get { return EXTENSION; }
+ }
+
+ Release (string mbid) : base (mbid, null)
+ {
+ }
+
+ Release (string mbid, string parameters) : base (mbid, parameters)
+ {
+ }
+
+ internal Release (XmlReader reader) : base(reader, false)
+ {
+ }
+
+ protected override void HandleCreateInc (StringBuilder builder)
+ {
+ AppendIncParameters (builder, "release-events", "labels");
+ if (discs == null) AppendIncParameters (builder, "discs");
+ if (tracks == null) {
+ AppendIncParameters (builder, "tracks", "track-level-rels");
+ AllRelsLoaded = false;
+ }
+ base.HandleCreateInc (builder);
+ }
+
+ protected override void HandleLoadMissingData ()
+ {
+ Release release = new Release (Id, CreateInc ());
+ type = release.Type;
+ status = release.Status;
+ language = release.Language;
+ script = release.Script;
+ asin = release.Asin;
+ events = release.Events;
+ if (discs == null) discs = release.Discs;
+ if (tracks == null) tracks = release.Tracks;
+ base.HandleLoadMissingData (release);
+ }
+
+ protected override bool HandleAttributes (XmlReader reader)
+ {
+ // How sure am I about getting the type and status in the "Type Status" format?
+ // MB really ought to specify these two things seperatly.
+ string type_string = reader ["type"];
+ if (type_string != null)
+ foreach (string token in type_string.Split (' ')) {
+ if (type == null) {
+ type = Utils.StringToEnumOrNull<ReleaseType> (token);
+ if (type != null) continue;
+ }
+ this.status = Utils.StringToEnumOrNull<ReleaseStatus> (token);
+ }
+ return this.type != null || this.status != null;
+ }
+
+ protected override bool HandleXml (XmlReader reader)
+ {
+ reader.Read ();
+ bool result = base.HandleXml (reader);
+ if (!result) {
+ result = true;
+ switch (reader.Name) {
+ case "text-representation":
+ language = reader ["language"];
+ script = reader ["script"];
+ break;
+ case "asin":
+ reader.Read ();
+ if (reader.NodeType == XmlNodeType.Text)
+ asin = reader.ReadContentAsString ();
+ break;
+ case "disc-list": {
+ if (reader.ReadToDescendant ("disc")) {
+ List<Disc> discs = new List<Disc> ();
+ do discs.Add (new Disc (reader.ReadSubtree ()));
+ while (reader.ReadToNextSibling ("disc"));
+ this.discs = discs.AsReadOnly ();
+ }
+ break;
+ }
+ case "release-event-list":
+ if (!AllDataLoaded) reader.Skip(); // FIXME this is a workaround for Mono bug 334752
+ if (reader.ReadToDescendant ("event")) {
+ List<Event> events = new List<Event> ();
+ do events.Add (new Event (reader.ReadSubtree ()));
+ while (reader.ReadToNextSibling ("event"));
+ this.events = events.AsReadOnly ();
+ }
+ break;
+ case "track-list": {
+ string offset = reader ["offset"];
+ if (offset != null)
+ track_number = int.Parse (offset) + 1;
+ if (reader.ReadToDescendant ("track")) {
+ List<Track> tracks = new List<Track> ();
+ do tracks.Add (new Track (reader.ReadSubtree (), AllDataLoaded));
+ while (reader.ReadToNextSibling ("track"));
+ this.tracks = tracks.AsReadOnly ();
+ }
+ break;
+ }
+ default:
+ reader.Skip (); // FIXME this is a workaround for Mono bug 334752
+ result = false;
+ break;
+ }
+ }
+ reader.Close ();
+ return result;
+ }
+
+ #region Properties
+
+ [Queryable ("reid")]
+ public override string Id {
+ get { return base.Id; }
+ }
+
+ [Queryable ("release")]
+ public override string Title {
+ get { return base.Title; }
+ }
+
+ ReleaseType? type;
+ [Queryable]
+ public ReleaseType Type {
+ get { return GetPropertyOrDefault (ref type, ReleaseType.None); }
+ }
+
+ ReleaseStatus? status;
+ [Queryable]
+ public ReleaseStatus Status {
+ get { return GetPropertyOrDefault (ref status, ReleaseStatus.None); }
+
+ }
+
+ string language;
+ public string Language {
+ get { return GetPropertyOrNull (ref language); }
+ }
+
+ string script;
+ [Queryable]
+ public string Script {
+ get { return GetPropertyOrNull (ref script); }
+ }
+
+ string asin;
+ [Queryable]
+ public string Asin {
+ get { return GetPropertyOrNull (ref asin); }
+ }
+
+ ReadOnlyCollection<Disc> discs;
+ [QueryableMember("Count", "discids")]
+ public ReadOnlyCollection<Disc> Discs {
+ get { return GetPropertyOrNew (ref discs); }
+ }
+
+ ReadOnlyCollection<Event> events;
+ public ReadOnlyCollection<Event> Events {
+ get { return GetPropertyOrNew (ref events); }
+ }
+
+ ReadOnlyCollection<Track> tracks;
+ [QueryableMember ("Count", "tracks")]
+ public ReadOnlyCollection<Track> Tracks {
+ get { return GetPropertyOrNew (ref tracks); }
+ }
+
+ int? track_number;
+ internal int TrackNumber {
+ get { return track_number != null ? track_number.Value : -1; }
+ }
+
+ #endregion
+
+ #region Static
+
+ public static Release Get (string mbid)
+ {
+ if (mbid == null) throw new ArgumentNullException ("mbid");
+ return new Release (mbid);
+ }
+
+ public static Query<Release> Query (string title)
+ {
+ if (title == null) throw new ArgumentNullException ("title");
+
+ ReleaseQueryParameters parameters = new ReleaseQueryParameters ();
+ parameters.Title = title;
+ return Query (parameters);
+ }
+
+ public static Query<Release> Query (string title, string artist)
+ {
+ if (title == null) throw new ArgumentNullException ("title");
+ if (artist == null) throw new ArgumentNullException ("artist");
+
+ ReleaseQueryParameters parameters = new ReleaseQueryParameters ();
+ parameters.Title = title;
+ parameters.Artist = artist;
+ return Query (parameters);
+ }
+
+ public static Query<Release> Query (ReleaseQueryParameters parameters)
+ {
+ if (parameters == null) throw new ArgumentNullException ("parameters");
+ return new Query<Release> (EXTENSION, QueryLimit, parameters.ToString ());
+ }
+
+ public static Query<Release> QueryFromDevice(string device)
+ {
+ if (device == null) throw new ArgumentNullException ("device");
+
+ ReleaseQueryParameters parameters = new ReleaseQueryParameters ();
+ parameters.DiscID = LocalDisc.GetFromDevice (device).Id;
+ return Query (parameters);
+ }
+
+ public static Query<Release> QueryLucene (string luceneQuery)
+ {
+ if (luceneQuery == null) throw new ArgumentNullException ("luceneQuery");
+ return new Query<Release> (EXTENSION, QueryLimit, CreateLuceneParameter (luceneQuery));
+ }
+
+ public static implicit operator string (Release release)
+ {
+ return release.ToString ();
+ }
+
+ #endregion
+
+ }
+}
Added: trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Track.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Track.cs Sat Mar 29 00:05:08 2008
@@ -0,0 +1,263 @@
+/***************************************************************************
+ * Track.cs
+ *
+ * Authored by Scott Peterson <lunchtimemama gmail com>
+ *
+ * The author disclaims copyright to this source code.
+ ****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Text;
+using System.Xml;
+
+namespace MusicBrainz
+{
+ public sealed class TrackQueryParameters : ItemQueryParameters
+ {
+ string release;
+ public string Release {
+ get { return release; }
+ set { release = value; }
+ }
+
+ string release_id;
+ public string ReleaseId {
+ get { return release_id; }
+ set { release_id = value; }
+ }
+
+ uint? duration;
+ public uint? Duration {
+ get { return duration; }
+ set { duration = value; }
+ }
+
+ int? track_number;
+ public int? TrackNumber {
+ get { return track_number; }
+ set { track_number = value; }
+ }
+
+ string puid;
+ public string Puid {
+ get { return puid; }
+ set { puid = value; }
+ }
+
+ public override string ToString ()
+ {
+ StringBuilder builder = new StringBuilder ();
+ if (release != null) {
+ builder.Append ("&release=");
+ Utils.PercentEncode (builder, release);
+ }
+ if (release_id != null) {
+ builder.Append ("&releaseid=");
+ builder.Append (release_id);
+ }
+ if (duration != null) {
+ builder.Append ("&duration=");
+ builder.Append (duration.Value);
+ }
+ if (track_number != null) {
+ builder.Append ("&tracknumber=");
+ builder.Append (track_number.Value);
+ }
+ if (puid != null) {
+ builder.Append ("&puid=");
+ builder.Append (puid);
+ }
+ AppendBaseToBuilder (builder);
+ return builder.ToString ();
+ }
+ }
+
+ public sealed class Track : MusicBrainzItem
+ {
+ const string EXTENSION = "track";
+
+ protected override string UrlExtension {
+ get { return EXTENSION; }
+ }
+
+ Track (string mbid) : base (mbid, null)
+ {
+ }
+
+ Track (string mbid, string parameters) : base (mbid, parameters)
+ {
+ }
+
+ internal Track (XmlReader reader) : base (reader, false)
+ {
+ }
+
+ internal Track (XmlReader reader, bool all_rels_loaded) : base (reader, all_rels_loaded)
+ {
+ }
+
+ protected override void HandleCreateInc (StringBuilder builder)
+ {
+ if (releases == null) AppendIncParameters (builder, "releases");
+ if (puids == null) AppendIncParameters (builder, "puids");
+ base.HandleCreateInc (builder);
+ }
+
+ protected override void HandleLoadMissingData ()
+ {
+ Track track = new Track (Id, CreateInc ());
+ duration = track.Duration;
+ if (releases == null) releases = track.Releases;
+ if (puids == null) puids = track.Puids;
+ base.HandleLoadMissingData (track);
+ }
+
+ protected override bool HandleAttributes (XmlReader reader)
+ {
+ return true;
+ }
+
+ protected override bool HandleXml (XmlReader reader)
+ {
+ reader.Read ();
+ bool result = base.HandleXml (reader);
+ if (!result) {
+ result = true;
+ switch (reader.Name) {
+ case "duration":
+ reader.Read ();
+ if (reader.NodeType == XmlNodeType.Text)
+ duration = uint.Parse (reader.ReadContentAsString ());
+ break;
+ case "release-list":
+ if(reader.ReadToDescendant ("release")) {
+ List<Release> releases = new List<Release> ();
+ do releases.Add (new Release (reader.ReadSubtree ()));
+ while (reader.ReadToNextSibling ("release"));
+ this.releases = releases.AsReadOnly ();
+ }
+ break;
+ case "puid-list":
+ if(reader.ReadToDescendant ("puid")) {
+ List<string> puids = new List<string> ();
+ do puids.Add (reader ["id"]);
+ while (reader.ReadToNextSibling ("puid"));
+ this.puids = puids.AsReadOnly ();
+ }
+ break;
+ default:
+ reader.Skip (); // FIXME this is a workaround for Mono bug 334752
+ result = false;
+ break;
+ }
+ }
+ reader.Close ();
+ return result;
+ }
+
+ #region Properties
+
+ [Queryable ("trid")]
+ public override string Id {
+ get { return base.Id; }
+ }
+
+ [Queryable ("track")]
+ public override string Title {
+ get { return base.Title; }
+ }
+
+ uint duration;
+ [Queryable ("dur")]
+ public uint Duration {
+ get { return duration; }
+ }
+
+ ReadOnlyCollection<Release> releases;
+ [QueryableMember ("Contains", "release")]
+ public ReadOnlyCollection<Release> Releases {
+ get { return GetPropertyOrNew (ref releases); }
+
+ }
+
+ ReadOnlyCollection<string> puids;
+ public ReadOnlyCollection<string> Puids {
+ get { return GetPropertyOrNew (ref puids); }
+ }
+
+ public int GetTrackNumber (Release release)
+ {
+ if (release == null) throw new ArgumentNullException ("release");
+
+ foreach (Release r in Releases)
+ if (r.Equals (release))
+ return r.TrackNumber;
+ return -1;
+ }
+
+ #endregion
+
+ #region Static
+
+ public static Track Get (string mbid)
+ {
+ if (mbid == null) throw new ArgumentNullException ("mbid");
+ return new Track (mbid);
+ }
+
+ public static Query<Track> Query (string title)
+ {
+ if (title == null) throw new ArgumentNullException ("title");
+
+ TrackQueryParameters parameters = new TrackQueryParameters ();
+ parameters.Title = title;
+ return Query (parameters);
+ }
+
+ public static Query<Track> Query (string title, string release)
+ {
+ if (title == null) throw new ArgumentNullException ("title");
+ if (release == null) throw new ArgumentNullException ("release");
+
+ TrackQueryParameters parameters = new TrackQueryParameters ();
+ parameters.Title = title;
+ parameters.Release = release;
+ return Query (parameters);
+ }
+
+ public static Query<Track> Query (string title, string release, string artist)
+ {
+ if (title == null) throw new ArgumentNullException ("title");
+ if (release == null) throw new ArgumentNullException ("release");
+ if (artist == null) throw new ArgumentNullException ("artist");
+
+ TrackQueryParameters parameters = new TrackQueryParameters ();
+ parameters.Title = title;
+ parameters.Release = release;
+ parameters.Artist = artist;
+ return Query (parameters);
+ }
+
+ public static Query<Track> Query (TrackQueryParameters parameters)
+ {
+ if (parameters == null) throw new ArgumentNullException ("parameters");
+ return new Query<Track> (EXTENSION, QueryLimit, parameters.ToString ());
+ }
+
+ public static Query<Track> QueryLucene (string luceneQuery)
+ {
+ if(luceneQuery == null) throw new ArgumentNullException ("luceneQuery");
+ return new Query<Track> (EXTENSION, QueryLimit, CreateLuceneParameter (luceneQuery));
+ }
+
+ public static implicit operator string (Track track)
+ {
+ return track.ToString ();
+ }
+
+ #endregion
+
+ }
+}
Added: trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Utils.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/Utils.cs Sat Mar 29 00:05:08 2008
@@ -0,0 +1,64 @@
+/***************************************************************************
+ * Utils.cs
+ *
+ * Authored by Scott Peterson <lunchtimemama gmail com>
+ *
+ * The author disclaims copyright to this source code.
+ ****************************************************************************/
+
+using System;
+using System.Text;
+
+namespace MusicBrainz
+{
+ internal static class Utils
+ {
+ public static string EnumToString (Enum enumeration)
+ {
+ string str = enumeration.ToString ();
+ StringBuilder builder = new StringBuilder (str.Length);
+ builder.Append (str [0]);
+ for (int i = 1; i < str.Length; i++) {
+ if (str [i] >= 'A' && str [i] <= 'Z')
+ builder.Append ('-');
+ builder.Append (str [i]);
+ }
+ return builder.ToString ();
+ }
+
+ public static T StringToEnum<T> (string name) where T : struct
+ {
+ return StringToEnumOrNull<T> (name) ?? default (T);
+ }
+
+ public static T? StringToEnumOrNull<T> (string name) where T : struct
+ {
+ if (name != null)
+ foreach (T value in Enum.GetValues (typeof (T)))
+ if (Enum.GetName (typeof (T), value) == name)
+ return value;
+ return null;
+ }
+
+ public static string PercentEncode (string value)
+ {
+ StringBuilder builder = new StringBuilder ();
+ PercentEncode (builder, value);
+ return builder.ToString ();
+ }
+
+ public static void PercentEncode (StringBuilder builder, string value)
+ {
+ foreach (char c in value) {
+ if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') ||
+ c == '-' || c == '_' || c == '.' || c == '~')
+ builder.Append (c);
+ else {
+ builder.Append ('%');
+ foreach (byte b in Encoding.UTF8.GetBytes (new char [] { c }))
+ builder.Append (string.Format ("{0:X}", b));
+ }
+ }
+ }
+ }
+}
Added: trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/XmlRequestEventArgs.cs
==============================================================================
--- (empty file)
+++ trunk/banshee/src/Libraries/MusicBrainz/MusicBrainz/XmlRequestEventArgs.cs Sat Mar 29 00:05:08 2008
@@ -0,0 +1,24 @@
+/***************************************************************************
+ * XmlRequestEventArgs.cs
+ *
+ * Authored by Scott Peterson <lunchtimemama gmail com>
+ *
+ * The author disclaims copyright to this source code.
+ ****************************************************************************/
+
+using System;
+
+namespace MusicBrainz
+{
+ public sealed class XmlRequestEventArgs : EventArgs
+ {
+ public readonly string Uri;
+ public readonly bool FromCache;
+
+ public XmlRequestEventArgs(string uri, bool fromCache)
+ {
+ Uri = uri;
+ FromCache = fromCache;
+ }
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]