mirror of
https://github.com/claunia/cuetools.net.git
synced 2025-12-16 18:14:25 +00:00
MusicBrainz support
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace CUETools.CDImage
|
||||
@@ -283,7 +284,7 @@ namespace CUETools.CDImage
|
||||
}
|
||||
}
|
||||
|
||||
public String Catalog
|
||||
public string Catalog
|
||||
{
|
||||
get
|
||||
{
|
||||
@@ -295,6 +296,20 @@ namespace CUETools.CDImage
|
||||
}
|
||||
}
|
||||
|
||||
public string MusicBrainzId
|
||||
{
|
||||
get
|
||||
{
|
||||
StringBuilder mbSB = new StringBuilder();
|
||||
mbSB.AppendFormat("{0:X2}{1:X2}{2:X8}", 1, AudioTracks, _tracks[(int)AudioTracks-1].End + 1 + 150);
|
||||
for (int iTrack = 0; iTrack < AudioTracks; iTrack++)
|
||||
mbSB.AppendFormat("{0:X8}", _tracks[iTrack].Start + 150);
|
||||
mbSB.Append(new string('0', (99 - (int)AudioTracks) * 8));
|
||||
byte[] hashBytes = (new SHA1CryptoServiceProvider()).ComputeHash(Encoding.ASCII.GetBytes(mbSB.ToString()));
|
||||
return Convert.ToBase64String(hashBytes).Replace('+', '.').Replace('/', '_').Replace('=', '-');
|
||||
}
|
||||
}
|
||||
|
||||
public void AddTrack(CDTrack track)
|
||||
{
|
||||
_tracks.Add(track);
|
||||
|
||||
@@ -97,6 +97,10 @@
|
||||
<Project>{8CF07381-BEA2-4AFC-B3DD-9B2F21C65A3A}</Project>
|
||||
<Name>CUETools.Ripper.SCSI</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\MusicBrainz\MusicBrainz.csproj">
|
||||
<Project>{74C2036B-2C9B-4FC8-B7BD-AE81A8DCE533}</Project>
|
||||
<Name>MusicBrainz</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
|
||||
@@ -27,6 +27,7 @@ using CUETools.Ripper.SCSI;
|
||||
using CUETools.Codecs;
|
||||
using CUETools.CDImage;
|
||||
using CUETools.AccurateRip;
|
||||
using MusicBrainz;
|
||||
|
||||
namespace CUERipper
|
||||
{
|
||||
@@ -40,7 +41,7 @@ namespace CUERipper
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
string programVersion = "CUERipper v1.9.3";
|
||||
string programVersion = "CUERipper v1.9.3 Copyright (C) 2008 Gregory S. Chudov";
|
||||
Console.SetOut(Console.Error);
|
||||
Console.WriteLine("{0}", programVersion);
|
||||
Console.WriteLine("This is free software under the GNU GPLv3+ license; There is NO WARRANTY, to");
|
||||
@@ -68,19 +69,37 @@ namespace CUERipper
|
||||
|
||||
bool toStdout = false;
|
||||
AccurateRipVerify arVerify = new AccurateRipVerify(audioSource.TOC);
|
||||
WAVWriter audioDest = new WAVWriter(destFile, audioSource.BitsPerSample, audioSource.ChannelCount, audioSource.SampleRate, toStdout ? Console.OpenStandardOutput() : null);
|
||||
int[,] buff = new int[audioSource.BestBlockSize, audioSource.ChannelCount];
|
||||
string CDDBId = AccurateRipVerify.CalculateCDDBId(audioSource.TOC);
|
||||
string ArId = AccurateRipVerify.CalculateAccurateRipId(audioSource.TOC);
|
||||
Release release;
|
||||
ReleaseQueryParameters p = new ReleaseQueryParameters();
|
||||
p.DiscId = audioSource.TOC.MusicBrainzId;
|
||||
Query<Release> results = Release.Query(p);
|
||||
|
||||
arVerify.ContactAccurateRip(ArId);
|
||||
|
||||
Console.WriteLine("Drive : {0}", audioSource.Path);
|
||||
Console.WriteLine("File Info : {0}kHz; {1} channel; {2} bit; {3}", audioSource.SampleRate, audioSource.ChannelCount, audioSource.BitsPerSample, CDImageLayout.TimeToString((uint)(audioSource.Length / 588)));
|
||||
Console.WriteLine("Filename : {0}", destFile);
|
||||
Console.WriteLine("AR status : {0}", arVerify.ARStatus == null ? "ok" : arVerify.ARStatus);
|
||||
try
|
||||
{
|
||||
release = results.First();
|
||||
}
|
||||
catch
|
||||
{
|
||||
release = null;
|
||||
}
|
||||
|
||||
if (destFile == null || destFile == "")
|
||||
destFile = (release == null) ? "cdimage.wav" : release.GetArtist() + " - " + release.GetTitle() + ".wav";
|
||||
|
||||
Console.WriteLine("Drive : {0}", audioSource.Path);
|
||||
Console.WriteLine("Filename : {0}", destFile);
|
||||
Console.WriteLine("Disk length : {0}", CDImageLayout.TimeToString((uint)(audioSource.Length / 588)));
|
||||
Console.WriteLine("AccurateRip : {0}", arVerify.ARStatus == null ? "ok" : arVerify.ARStatus);
|
||||
Console.WriteLine("MusicBrainz : {0}", release == null ? "not found" : release.GetArtist() + " - " + release.GetTitle());
|
||||
|
||||
WAVWriter audioDest = new WAVWriter(destFile, audioSource.BitsPerSample, audioSource.ChannelCount, audioSource.SampleRate, toStdout ? Console.OpenStandardOutput() : null);
|
||||
audioDest.FinalSampleCount = (long)audioSource.Length;
|
||||
|
||||
audioDest.FinalSampleCount = (long) audioSource.Length;
|
||||
|
||||
DateTime start = DateTime.Now;
|
||||
TimeSpan lastPrint = TimeSpan.FromMilliseconds(0);
|
||||
@@ -94,7 +113,7 @@ namespace CUERipper
|
||||
TimeSpan elapsed = DateTime.Now - start;
|
||||
if ((elapsed - lastPrint).TotalMilliseconds > 60)
|
||||
{
|
||||
Console.Error.Write("\rProgress : {0:00}%; {1:0.00}x; {2}/{3}",
|
||||
Console.Write("\rProgress : {0:00}%; {1:0.00}x; {2}/{3}",
|
||||
100.0 * audioSource.Position / audioSource.Length,
|
||||
audioSource.Position / elapsed.TotalSeconds / audioSource.SampleRate,
|
||||
elapsed,
|
||||
@@ -105,8 +124,8 @@ namespace CUERipper
|
||||
} while (true);
|
||||
|
||||
TimeSpan totalElapsed = DateTime.Now - start;
|
||||
Console.Error.Write("\r \r");
|
||||
Console.WriteLine("Results : {0:0.00}x; {1}",
|
||||
Console.Write("\r \r");
|
||||
Console.WriteLine("Results : {0:0.00}x; {1}",
|
||||
audioSource.Length / totalElapsed.TotalSeconds / audioSource.SampleRate,
|
||||
totalElapsed
|
||||
);
|
||||
@@ -146,11 +165,23 @@ namespace CUERipper
|
||||
cueWriter.WriteLine("REM COMMENT \"{0}\"", programVersion);
|
||||
if (audioSource.TOC.Catalog != null)
|
||||
cueWriter.WriteLine("CATALOG {0}", audioSource.TOC.Catalog);
|
||||
if (release != null)
|
||||
{
|
||||
if (release.GetEvents().Count > 0)
|
||||
cueWriter.WriteLine("DATE {0}", release.GetEvents()[0].Date);
|
||||
cueWriter.WriteLine("PERFORMER {0}", release.GetArtist());
|
||||
cueWriter.WriteLine("TITLE {0}", release.GetTitle());
|
||||
}
|
||||
cueWriter.WriteLine("FILE \"{0}\" WAVE", destFile);
|
||||
for (int track = 1; track <= audioSource.TOC.TrackCount; track++)
|
||||
if (audioSource.TOC[track].IsAudio)
|
||||
{
|
||||
cueWriter.WriteLine(" TRACK {0:00} AUDIO", audioSource.TOC[track].Number);
|
||||
if (release != null && release.GetTracks().Count >= audioSource.TOC[track].Number)
|
||||
{
|
||||
cueWriter.WriteLine(" TITLE {0}", release.GetTracks()[(int)audioSource.TOC[track].Number - 1].GetTitle());
|
||||
cueWriter.WriteLine(" PERFORMER {0}", release.GetTracks()[(int)audioSource.TOC[track].Number - 1].GetArtist());
|
||||
}
|
||||
if (audioSource.TOC[track].ISRC != null)
|
||||
cueWriter.WriteLine(" ISRC {0}", audioSource.TOC[track].ISRC);
|
||||
for (int index = audioSource.TOC[track].Pregap > 0 ? 0 : 1; index <= audioSource.TOC[track].LastIndex; index++)
|
||||
|
||||
@@ -71,6 +71,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CUETools.CDImage", "..\CUET
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CUETools.AccurateRip", "..\CUETools.AccurateRip\CUETools.AccurateRip.csproj", "{5802C7E9-157E-4124-946D-70B5AE48A5A1}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MusicBrainz", "..\MusicBrainz\MusicBrainz.csproj", "{74C2036B-2C9B-4FC8-B7BD-AE81A8DCE533}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@@ -342,6 +344,18 @@ Global
|
||||
{5802C7E9-157E-4124-946D-70B5AE48A5A1}.Release|x64.Build.0 = Release|x64
|
||||
{5802C7E9-157E-4124-946D-70B5AE48A5A1}.Release|x86.ActiveCfg = Release|x86
|
||||
{5802C7E9-157E-4124-946D-70B5AE48A5A1}.Release|x86.Build.0 = Release|x86
|
||||
{74C2036B-2C9B-4FC8-B7BD-AE81A8DCE533}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{74C2036B-2C9B-4FC8-B7BD-AE81A8DCE533}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{74C2036B-2C9B-4FC8-B7BD-AE81A8DCE533}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{74C2036B-2C9B-4FC8-B7BD-AE81A8DCE533}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{74C2036B-2C9B-4FC8-B7BD-AE81A8DCE533}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{74C2036B-2C9B-4FC8-B7BD-AE81A8DCE533}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{74C2036B-2C9B-4FC8-B7BD-AE81A8DCE533}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{74C2036B-2C9B-4FC8-B7BD-AE81A8DCE533}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{74C2036B-2C9B-4FC8-B7BD-AE81A8DCE533}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{74C2036B-2C9B-4FC8-B7BD-AE81A8DCE533}.Release|x64.Build.0 = Release|Any CPU
|
||||
{74C2036B-2C9B-4FC8-B7BD-AE81A8DCE533}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{74C2036B-2C9B-4FC8-B7BD-AE81A8DCE533}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
3
MusicBrainz/AUTHORS
Normal file
3
MusicBrainz/AUTHORS
Normal file
@@ -0,0 +1,3 @@
|
||||
Scott Peterson
|
||||
E-mail: lunchtimemama@gmail.com
|
||||
Userid: scottp
|
||||
17
MusicBrainz/COPYING
Normal file
17
MusicBrainz/COPYING
Normal file
@@ -0,0 +1,17 @@
|
||||
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.
|
||||
503
MusicBrainz/ChangeLog
Normal file
503
MusicBrainz/ChangeLog
Normal file
@@ -0,0 +1,503 @@
|
||||
2008-09-20 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
|
||||
|
||||
2008-09-20 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/Track.cs : GetDuration now returns a TimeSpan rather
|
||||
than a uint. Don't know how I missed that.
|
||||
* MusicBrainz/MusicBrainzObject.cs: Added GetPropertyOrDefault
|
||||
overload which uses the "default" keyword for the default value.
|
||||
|
||||
2008-08-17 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs, MusicBrainz/Release.cs,
|
||||
MusicBrainz/Track.cs: Made protected members internal. Minor
|
||||
refactoring.
|
||||
* MusicBrainz/Relation.cs: UrlRelations uses Uri instead of string.
|
||||
* MusicBrainz/Label.cs: Made protected members internal. Minor
|
||||
refactoring. Fixed bug with Country.
|
||||
* MusicBrainz/MusicBrainzEntity.cs, MusicBrainz/MusicBrainzItem.cs:
|
||||
Made protected members internal.
|
||||
* MusicBrainz/XmlRequestEventArgs.cs: Use Uri instead of string.
|
||||
* MusicBrainz/LocalDisc.cs: Made protected members internal. Removed
|
||||
ThreadStatic attributes and went for locks instead. This is the way
|
||||
we concurentize our code, concurentize our code, concurentize our
|
||||
code. TrackDuration is now an array of TimeSpans rather than ints.
|
||||
Because that's more awesome. SubissionUrl is now a Uri rather than
|
||||
a string. For the same reason. Added LocalDiscException class to
|
||||
wrap problems with the hardware layer code.
|
||||
* MusicBrainz/MusicBrainzException.cs: Minor refactoring.
|
||||
* MusicBrainz/Query.cs: Throw ArgumentOutOfRangeException instead of
|
||||
IndexOutOfRangeException because Framework Design Guidelines told
|
||||
me to. Removed ToList and ToArray. People can use the
|
||||
IEnumerable<T> extension methods if they want.
|
||||
* MusicBrainz/Artist.cs: Made protected members internal. Removed
|
||||
ThreadStatic attribute from static field and added locks for proper
|
||||
concurrency handling. GetReleases (ArtistReleaseType) no longer
|
||||
changes the Artist.ArtistReleaseType to the provided argument.
|
||||
Added ReleaseArtistType enum to replace the various bool for
|
||||
ArtistReleaseType (confusing names, I know. Tough titties).
|
||||
* MusicBrainz/MusicBrainzService.cs: Got rid of ThreadStatic and added
|
||||
locks. Yeah! Changed ServiceUrl to Uri from string. Yeah again!
|
||||
|
||||
2008-08-05 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs: Made some protected methods static.
|
||||
* MusicBrainz/LocalDisc.cs: Changed protected properties to protected
|
||||
fields and changed an array property to a method.
|
||||
* MusicBrainz/DiscLinux.cs, MusicBrainz/DiscWin32.cs: Changed class
|
||||
name to match file name and changed protected properties to
|
||||
protected fields.
|
||||
* MusicBrainz/Query.cs: Changed attribute public readonly fields to
|
||||
public readonly properties.
|
||||
* MusicBrainz/Artist.cs: Made public static field ThreadStatic and made
|
||||
a private method static.
|
||||
* MusicBrainz/MusicBrainzService.cs: Made public static fields
|
||||
ThreadStatic.
|
||||
|
||||
2008-07-21 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs: Simplified relation creation
|
||||
slightly and added equivilance operator overload.
|
||||
* MusicBrainz/LinuxDisc.cs, MusicBrainz/DiscLinux.cs: Renamed back to
|
||||
DiscLinux
|
||||
* MusicBrainz/Query.cs: Renamed some public parameters to follow FDG
|
||||
style and changed some public methods to return IList instead of
|
||||
List.
|
||||
* MusicBrainz/Win32Disc.cs, MusicBrainz/DiscWin32.cs: Renamed back to
|
||||
DiscWin32
|
||||
* MusicBrainz/Artist.cs: Added equivilance operator overload to
|
||||
ArtistReleaseType type.
|
||||
|
||||
2008-04-15 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs, MusicBrainz/Relation.cs,
|
||||
MusicBrainz/Label.cs, MusicBrainz/Release.cs, MusicBrainz/Event.cs,
|
||||
MusicBrainz/Disc.cs, MusicBrainz/MusicBrainzEntity.cs,
|
||||
MusicBrainz/XmlRequestEventArgs.cs, MusicBrainz/LocalDisc.cs,
|
||||
MusicBrainz/Utils.cs, MusicBrainz/LinuxDisc.cs,
|
||||
MusicBrainz/Track.cs, MusicBrainz/MusicBrainzException.cs,
|
||||
MusicBrainz/MusicBrainzItem.cs, MusicBrainz/Query.cs,
|
||||
MusicBrainz/Win32Disc.cs, MusicBrainz/Artist.cs,
|
||||
MusicBrainz/MusicBrainzService.cs: API BREAKING CHANGE!!! We now
|
||||
use methods rather than properties if accessing the member can
|
||||
incur an HTTP request. Update your code accordingly.
|
||||
|
||||
2008-04-05 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs, MusicBrainz/Release.cs,
|
||||
MusicBrainz/MusicBrainzEntity.cs, MusicBrainz/Utils.cs,
|
||||
MusicBrainz/Track.cs, MusicBrainz/MusicBrainzItem.cs: Some better
|
||||
string building.
|
||||
|
||||
2008-04-05 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz.mdp, MusicBrainz/Relation.cs,
|
||||
MusicBrainz/MusicBrainzObject.cs, MusicBrainz/Label.cs,
|
||||
MusicBrainz/Release.cs, MusicBrainz/MusicBrainzEntity.cs,
|
||||
MusicBrainz/LocalDisc.cs, MusicBrainz/Track.cs,
|
||||
MusicBrainz/Query.cs, MusicBrainz/MusicBrainzItem.cs,
|
||||
MusicBrainz/Artist.cs, MusicBrainz/MusicBrainzService.cs:
|
||||
Reorganized some code.
|
||||
* MusicBrainz/DiscLinux.cs, MusicBrainz/LinuxDisc.cs,
|
||||
MusicBrainz/DiscWin32.cs, MusicBrainz/Win32Disc.cs: Renamed
|
||||
|
||||
2008-04-05 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs, MusicBrainz/Relation.cs,
|
||||
MusicBrainz/Label.cs, MusicBrainz/Release.cs, MusicBrainz/Event.cs,
|
||||
MusicBrainz/Disc.cs, MusicBrainz/MusicBrainzEntity.cs,
|
||||
MusicBrainz/XmlRequestEventArgs.cs, MusicBrainz/LocalDisc.cs,
|
||||
MusicBrainz/Utils.cs, MusicBrainz/DiscLinux.cs,
|
||||
MusicBrainz/Track.cs, MusicBrainz/MusicBrainzException.cs,
|
||||
MusicBrainz/MusicBrainzItem.cs, MusicBrainz/Query.cs,
|
||||
MusicBrainz/DiscWin32.cs, MusicBrainz/Artist.cs,
|
||||
MusicBrainz/MusicBrainzService.cs: Put the license in a region
|
||||
(yeah for the managed MD text editor!) and a few whitespace fixes.
|
||||
|
||||
2008-03-31 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/Relation.cs: Renamed RelationPrimitive to RelationBase.
|
||||
|
||||
2008-03-31 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs, MusicBrainz/Label.cs,
|
||||
MusicBrainz/Release.cs, MusicBrainz/Event.cs,
|
||||
MusicBrainz/MusicBrainzEntity.cs, MusicBrainz/Track.cs,
|
||||
MusicBrainz/MusicBrainzItem.cs, MusicBrainz/Artist.cs: Formatting
|
||||
fixes.
|
||||
|
||||
2008-03-31 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/Release.cs: Changed ReleaseQueryParameters.DiscID to
|
||||
DiscId. This is an API breaking change (good thing we're not at
|
||||
1.0!)
|
||||
|
||||
2008-03-31 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs, MusicBrainz/Relation.cs,
|
||||
MusicBrainz/Label.cs, MusicBrainz/Release.cs, MusicBrainz/Event.cs,
|
||||
MusicBrainz/Disc.cs, MusicBrainz/MusicBrainzEntity.cs,
|
||||
MusicBrainz/XmlRequestEventArgs.cs, MusicBrainz/LocalDisc.cs,
|
||||
MusicBrainz/DiscLinux.cs, MusicBrainz/Track.cs,
|
||||
MusicBrainz/MusicBrainzException.cs,
|
||||
MusicBrainz/MusicBrainzItem.cs, MusicBrainz/Query.cs,
|
||||
MusicBrainz/DiscWin32.cs, MusicBrainz/MusicBrainzService.cs:
|
||||
Relicensed to MIT/X11
|
||||
* MusicBrainz/Utils.cs: Relicensed to MIT/X11. New override for
|
||||
EnumToString takes a StringBuider.
|
||||
* MusicBrainz/Artist.cs: Relicensed to MIT/X11. ArtistReleaseType now
|
||||
support specifying a ReleaseType and a ReleaseStatus.
|
||||
|
||||
2008-03-30 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/Release.cs: Instantiate tracks with the artist of the
|
||||
release.
|
||||
* MusicBrainz/Track.cs: Use new constructor.
|
||||
* MusicBrainz/MusicBrainzItem.cs: Added the ability for a
|
||||
MusicBrainzItem to be instantiated with an Artist. This artist will
|
||||
only be used if no artist was found in the XML.
|
||||
|
||||
2008-03-25 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs, MusicBrainz/Release.cs,
|
||||
MusicBrainz/MusicBrainzEntity.cs, MusicBrainz/Track.cs,
|
||||
MusicBrainz/Artist.cs: Whitespace fixes which have somehow managed
|
||||
to escape my attention, and used the AsReadOnly convenience method.
|
||||
|
||||
2008-03-21 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/Query.cs: Add new PerfectMatch() method which returns a
|
||||
result if it is the only result with a score of 100. If no result
|
||||
has a score of 100, or if more than one result have a score of 100,
|
||||
null is returned.
|
||||
|
||||
2008-03-14 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs, MusicBrainz/Label.cs,
|
||||
MusicBrainz/Release.cs, MusicBrainz/Event.cs,
|
||||
MusicBrainz/MusicBrainzEntity.cs, MusicBrainz/Track.cs,
|
||||
MusicBrainz/MusicBrainzItem.cs, MusicBrainz/Artist.cs: Whitespace fixes.
|
||||
I don't know where these tabs come from.
|
||||
|
||||
2008-02-13 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
Got rid of unused Properties direcotry and AssemblyInfo.cs
|
||||
|
||||
2008-02-25 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/Disc.cs: Use TryParse instead of a bunch of stuff.
|
||||
|
||||
2008-02-25 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/LocalDisc.cs: Added SubmissionUrl property.
|
||||
|
||||
2008-02-25 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs: Whatspace fixes.
|
||||
|
||||
2008-02-25 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs: Fixed bug w/ Release getting and
|
||||
querying.
|
||||
|
||||
2008-02-25 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs: Improved a params method performance.
|
||||
Used TimeSpan and DateTime operators.
|
||||
* MusicBrainz/Release.cs: Improved a params method performance.
|
||||
|
||||
2008-02-23 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
Renamed MusicBrainzObject.Mbid to just Id.
|
||||
|
||||
* MusicBrainz/MusicBrainzService.cs: Added static class for containing all
|
||||
static setting pertaining globally to the use of the library. I think
|
||||
this is more logical than sticking this stuff in the abstract
|
||||
MusicBrainzObject type.
|
||||
|
||||
2008-02-22 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/Relation.cs: Got rid of unneeded using.
|
||||
|
||||
2008-02-22 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
Various whitespace fixes, refactoring, and using immutable collections
|
||||
|
||||
* MusicBrainz/Utilities.cs, MusicBrainz/Utils.cs: Renamed Utilities class to
|
||||
Utils. It's internal, so an abriviated name is just fine.
|
||||
* MusicBrainz/MusicBrainzObject.cs, MusicBrainz/Release.cs,
|
||||
MusicBrainz/MusicBrainzEntity.cs, MusicBrainz/Track.cs,
|
||||
MusicBrainz/MusicBrainzItem.cs, MusicBrainz/Artist.cs: Renamed MBID to
|
||||
Mbid, made to use ReadOnlyCollection instead of List.
|
||||
* MusicBrainz/Label.cs: Renamed MBID to Mbid
|
||||
* MusicBrainz/Disc.cs, MusicBrainz/LocalDisc.cs: Split off local-disc
|
||||
specific stuff into LocalDisc.
|
||||
* MusicBrainz/DiscLinux.cs, MusicBrainz/DiscWin32.cs: Inherit from LocalDisc
|
||||
* MusicBrainz/Query.cs: Added First () method which returns just the first
|
||||
result (same as the implicit conversion to T).
|
||||
|
||||
2008-02-22 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
More white space fixes
|
||||
|
||||
2008-02-21 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
Whitespace changes. I'll probably work things a little more.
|
||||
|
||||
2008-02-21 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/Track.cs: Added new overload to Query().
|
||||
|
||||
2008-02-20 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs, MusicBrainz/MusicBrainzEntity.cs,
|
||||
MusicBrainz/MusicBrainzItem.cs: Made the abstract classes' constructors
|
||||
internal. Since the all of the concrete classes are sealed, this
|
||||
prevents any external assembly from inheriting from MusicBrainzObject &
|
||||
al.
|
||||
|
||||
2008-02-13 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/Release.cs: Changed return type of QueryFromDevice from
|
||||
Release to Query<Release> (since Query<T> can now be implicitly
|
||||
converted to T).
|
||||
* MusicBrainz/Query.cs: Improvement to implicit conversion to prevent bad
|
||||
performance after the conversion has been made when attempting to
|
||||
enumerate.
|
||||
|
||||
2008-02-13 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/Utilities.cs: Fixed bug in EnumToString.
|
||||
* MusicBrainz/Query.cs: Minor changes
|
||||
|
||||
2008-02-13 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/Label.cs, MusicBrainz/Release.cs, MusicBrainz/Track.cs,
|
||||
MusicBrainz/Artist.cs: Got rid of Query*Single methods.
|
||||
* MusicBrainz/Query.cs: Fancy new methods and operators.
|
||||
|
||||
2008-02-13 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs, MusicBrainz/Label.cs,
|
||||
MusicBrainz/Release.cs, MusicBrainz/DiscLinux.cs, MusicBrainz/Track.cs,
|
||||
MusicBrainz/MusicBrainzItem.cs, MusicBrainz/Query.cs: More aesthetic use
|
||||
of nullable types.
|
||||
|
||||
2008-02-09 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/DiscLinux.cs: Minor refactor.
|
||||
* MusicBrainz/DiscWin32.cs: Removed unnessisary ref.
|
||||
|
||||
2008-02-09 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/DiscLinux.cs: Fixed linux disc id code.
|
||||
* MusicBrainz/DiscWin32.cs: Whitespace.
|
||||
|
||||
2008-02-09 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/Disc.cs, MusicBrainz/DiscLinux.cs: More work on the linux
|
||||
discid. Still not there yet. Damn marshaling.
|
||||
|
||||
2008-02-09 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/DiscLinux.cs: Improvements to the linux discid implimentation.
|
||||
Still doesn't work, but getting closer.
|
||||
|
||||
2008-02-09 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs: Fixed bug when query returns no results.
|
||||
* MusicBrainz/Label.cs, MusicBrainz/Release.cs, MusicBrainz/Track.cs,
|
||||
MusicBrainz/Artist.cs: Whitespace fixes
|
||||
* MusicBrainz/Disc.cs, MusicBrainz/DiscWin32.cs: Rejiggered
|
||||
* MusicBrainz/DiscLinux.cs: Added linux DiscId implementation
|
||||
|
||||
2008-02-07 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/Release.cs, MusicBrainz/MusicBrainzEntity.cs,
|
||||
MusicBrainz/Track.cs, MusicBrainz/MusicBrainzItem.cs,
|
||||
MusicBrainz/Query.cs, MusicBrainz/Artist.cs: Refactored LINQ-related
|
||||
attributes.
|
||||
|
||||
2008-02-03 Scott Peterson <lunchtimemama@gmail.com>
|
||||
|
||||
* MusicBrainz/Utilities.cs: Minor improvement to enum-to-string method.
|
||||
* MusicBrainz/MusicBrainzObject.cs, MusicBrainz/Event.cs,
|
||||
MusicBrainz/MusicBrainzException.cs, MusicBrainz/Query.cs: Sealed some
|
||||
classes.
|
||||
|
||||
2007-12-31 Scott Peterson <lunchtimemama>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs: Fixed generic constraint syntax that was
|
||||
a problem for csc.
|
||||
|
||||
2007-12-09 Scott Peterson <scottp@gnome.org>
|
||||
|
||||
* MusicBrainz/Label.cs, MusicBrainz/Release.cs, MusicBrainz/Event.cs,
|
||||
MusicBrainz/MusicBrainzItem.cs, MusicBrainz/Artist.cs: Reverted
|
||||
pluralization (my mistake)
|
||||
|
||||
2007-12-08 Scott Peterson <scottp@gnome.org>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs, MusicBrainz/Label.cs,
|
||||
MusicBrainz/Release.cs, MusicBrainz/Event.cs, MusicBrainz/Track.cs,
|
||||
MusicBrainz/MusicBrainzItem.cs, MusicBrainz/Artist.cs: Refactored
|
||||
enumeration names to be plural.
|
||||
|
||||
2007-12-08 Scott Peterson <scottp@gnome.org>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs: Slight improvement to property handling.
|
||||
|
||||
2007-12-08 Scott Peterson <scottp@gnome.org>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs, MusicBrainz/Label.cs,
|
||||
MusicBrainz/Release.cs, MusicBrainz/MusicBrainzEntity.cs,
|
||||
MusicBrainz/Track.cs, MusicBrainz/MusicBrainzItem.cs,
|
||||
MusicBrainz/Artist.cs: Property access is now nicer.
|
||||
|
||||
2007-11-13 Scott Peterson <scottp@gnome.org>
|
||||
|
||||
* MusicBrainz/Track.cs: Added null argument check and a LINQ attribute.
|
||||
|
||||
2007-11-13 Scott Peterson <scottp@gnome.org>
|
||||
|
||||
* MusicBrainz/Label.cs, MusicBrainz/Release.cs, MusicBrainz/Disc.cs,
|
||||
MusicBrainz/Track.cs, MusicBrainz/Artist.cs: Added argument null-checks
|
||||
for public methods.
|
||||
|
||||
2007-11-12 Scott Peterson <scottp@gnome.org>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs: Fixed bug when queries returned no
|
||||
results.
|
||||
|
||||
2007-11-09 Scott Peterson <scottp@gnome.org>
|
||||
|
||||
* MusicBrainz/Utilities.cs, MusicBrainz/MusicBrainzObject.cs,
|
||||
MusicBrainz/Relation.cs, MusicBrainz/Label.cs, MusicBrainz/Release.cs,
|
||||
MusicBrainz/Event.cs, MusicBrainz/Disc.cs,
|
||||
MusicBrainz/MusicBrainzEntity.cs, MusicBrainz/Track.cs,
|
||||
MusicBrainz/MusicBrainzException.cs, MusicBrainz/MusicBrainzItem.cs,
|
||||
MusicBrainz/Query.cs, MusicBrainz/DiscWin32.cs, MusicBrainz/Artist.cs:
|
||||
Relicenced.
|
||||
* MusicBrainz/LinqBoilerplate.cs, MusicBrainz/Linq.cs: Removed for now.
|
||||
|
||||
2007-11-06 Scott Peterson <scottp@gnome.org>
|
||||
|
||||
* MusicBrainz/Release.cs: Fixed bug with events list.
|
||||
|
||||
2007-11-06 Scott Peterson <scottp@gnome.org>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs, MusicBrainz/Label.cs,
|
||||
MusicBrainz/Release.cs, MusicBrainz/MusicBrainzEntity.cs,
|
||||
MusicBrainz/Track.cs, MusicBrainz/MusicBrainzItem.cs: Made LINQ-ready.
|
||||
* MusicBrainz/LinqBoilerplate.cs, MusicBrainz/Linq.cs: Created a LINQ
|
||||
provider.
|
||||
* MusicBrainz/Query.cs: Added some custom atts used by the LINQ provider.
|
||||
* MusicBrainz/Artist.cs: Made LINQ-ready. Fixed a silly sintax thing that
|
||||
makes MSBuild barf. BWAAA!
|
||||
* Makefile.am: Changed from wildcard *.cs to specific enumeration of source
|
||||
files (because we now have some .cs files (the LINQ ones) which we do
|
||||
not want to compile (... yet!)).
|
||||
|
||||
2007-10-31 Scott Peterson <scottp@gnome.org>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs: Made the ProviderUrl a public field.
|
||||
Renamed a few methods.
|
||||
* MusicBrainz/Query.cs: Refactored a method.
|
||||
|
||||
2007-10-31 Scott Peterson <scottp@gnome.org>
|
||||
|
||||
* MusicBrainz/Release.cs: Fixed bug with ReleaseQueryParameter using
|
||||
"language" instead of "lang" as a query parameter.
|
||||
|
||||
2007-10-30 Scott Peterson <scottp@gnome.org>
|
||||
|
||||
* MusicBrainz/Artist.cs: Artist's will now fetch their Releases during
|
||||
Artist.Get().
|
||||
|
||||
2007-10-30 Scott Peterson <scottp@gnome.org>
|
||||
|
||||
* MusicBrainz/Utilities.cs: Moved percent-encoding code to Utilities class.
|
||||
* MusicBrainz/MusicBrainzObject.cs, MusicBrainz/Release.cs,
|
||||
MusicBrainz/MusicBrainzEntity.cs, MusicBrainz/Track.cs,
|
||||
MusicBrainz/MusicBrainzItem.cs: Made to use Utilities.PercentEncoding().
|
||||
* MusicBrainz/Query.cs: Got rid of stupid class QueryParameters.
|
||||
* MusicBrainz/Artist.cs: Got rid of stupid overload for Get()
|
||||
|
||||
2007-10-30 Scott Peterson <scottp@gnome.org>
|
||||
|
||||
* MusicBrainz/Utilities.cs, MusicBrainz/Relation.cs,
|
||||
MusicBrainz/MusicBrainzObject.cs, MusicBrainz/Label.cs,
|
||||
MusicBrainz/Release.cs, MusicBrainz/Event.cs, MusicBrainz/Disc.cs,
|
||||
MusicBrainz/MusicBrainzEntity.cs, MusicBrainz/Track.cs,
|
||||
MusicBrainz/Query.cs, MusicBrainz/MusicBrainzItem.cs,
|
||||
MusicBrainz/MusicBrainzException.cs, MusicBrainz/DiscWin32.cs,
|
||||
MusicBrainz/Artist.cs: Added copyright notice and MIT licence.
|
||||
|
||||
2007-10-30 Scott Peterson <scottp@gnome.org>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs: Refactored Query methods (got rid of
|
||||
them).
|
||||
* MusicBrainz/Label.cs, MusicBrainz/Track.cs, MusicBrainz/Artist.cs:
|
||||
Refactored Query methods.
|
||||
* MusicBrainz/Release.cs: Refactored Query methods, spelling correction in
|
||||
ReleaseFormat.Cassette.
|
||||
* MusicBrainz/Disc.cs: Changed Id to ID. It seems better.
|
||||
* MusicBrainz/MusicBrainzEntity.cs: Got rid of EntityQueryParameters (a
|
||||
stupid class).
|
||||
* MusicBrainz/Query.cs: Removed non-generic Query class (a stupid class to
|
||||
begin with) and made a bunch of things private because the client really
|
||||
shouldn't need to know about how we're doing things. Refactored
|
||||
constructor a little.
|
||||
|
||||
2007-10-27 Scott Peterson <scottp@gnome.org>
|
||||
|
||||
* MusicBrainz/MusicBrainzObject.cs, MusicBrainz/MusicBrainzItem.cs: Method
|
||||
accessor tightened up and method name changed.
|
||||
* MusicBrainz/Label.cs, MusicBrainz/Release.cs, MusicBrainz/Track.cs,
|
||||
MusicBrainz/Artist.cs: Method accessor tightened up.
|
||||
* MusicBrainz/MusicBrainzEntity.cs: Method name changed.
|
||||
|
||||
2007-10-27 Scott Peterson <scottp@gnome.org>
|
||||
|
||||
* MusicBrainz/Disc.cs: Made to use System.Security.Cryptography.SHA1.
|
||||
* MusicBrainz/SHA1MusicBrainz.cs: Removed. It turns out
|
||||
System.Security.Cryptography.SHA1 does the trick.
|
||||
|
||||
2007-10-27 Scott Peterson <scottp@gnome.org>
|
||||
|
||||
* ChangeLog: ChangeLog updated.
|
||||
|
||||
2007-10-27 Scott Peterson <scottp@gnome.org>
|
||||
* MusicBrainz/Utilities.cs: Cleaned out a bunch of obsolete code.
|
||||
* MusicBrainz/MusicBrainzObject.cs: Made HaveAllRels a protected
|
||||
property and removed redundant constructors.
|
||||
* MusicBrainz/Label.cs, MusicBrainz/Track.cs: Minor changes to
|
||||
constructors.
|
||||
* MusicBrainz/Release.cs: Minor changes to constructors and change
|
||||
which fixes a theoretical bug where Tracks would not have
|
||||
relations.
|
||||
* MusicBrainz/MusicBrainzEntity.cs, MusicBrainz/MusicBrainzItem.cs:
|
||||
Removed redundant constructors as per changes in MusicBrainzObject.
|
||||
* MusicBrainz/Query.cs: Removed obsolete ArtistReleaseIncs field.
|
||||
* MusicBrainz/Artist.cs: Minor changes to constructors and a new way of
|
||||
specifying releases: Added ArtistRelease class and simplified code
|
||||
regarding releases. Also made very fancy use of the coalesces
|
||||
operator!
|
||||
* MusicBrainz/Inc.cs: Removed. Changes in the way artists' handle
|
||||
releases finally obsoletes this class.
|
||||
|
||||
2007-10-27 Aaron Bockover <abock@gnome.org>
|
||||
|
||||
* src/MusicBrainz/MusicBrainz/*.cs: Renamed the namespace from
|
||||
MusicBrainzSharp to MusicBrainz
|
||||
|
||||
* configure.ac:
|
||||
* m4/monodoc.m4:
|
||||
* docs/: Added Monodoc support
|
||||
|
||||
2007-10-27 Aaron Bockover <abock@gnome.org>
|
||||
|
||||
* musicbrainz-sharp: Set up initial project infrastructure for Scott
|
||||
|
||||
7
MusicBrainz/HACKING
Normal file
7
MusicBrainz/HACKING
Normal file
@@ -0,0 +1,7 @@
|
||||
When writing code for MusicBrainz-Sharp, follow the Mono coding guidlines [1].
|
||||
|
||||
MusicBrainz-Sharp is in the public domain. In order to preserve the freedom of the code, any patches or code which is submitted to MusicBrainz-Sharp must include the following disclaimer:
|
||||
|
||||
The author or authors of this code dedicate any and all copyright interest in this code to the public domain. We make this dedication for the benefit of the public at large and to the detriment of our heirs and successors. We intend this dedication to be an overt act of relinquishment in perpetuity of all present and future rights to this code under copyright law.
|
||||
|
||||
[1] http://www.mono-project.com/Coding_Guidelines
|
||||
3
MusicBrainz/MAINTAINERS
Normal file
3
MusicBrainz/MAINTAINERS
Normal file
@@ -0,0 +1,3 @@
|
||||
Scott Peterson
|
||||
E-mail: lunchtimemama@gmail.com
|
||||
Userid: scottp
|
||||
38
MusicBrainz/Makefile.am
Normal file
38
MusicBrainz/Makefile.am
Normal file
@@ -0,0 +1,38 @@
|
||||
ASSEMBLY = MusicBrainz.dll
|
||||
REFERENCES = \
|
||||
-r:System \
|
||||
-r:System.Xml
|
||||
SOURCES = \
|
||||
MusicBrainz/Artist.cs \
|
||||
MusicBrainz/Disc.cs \
|
||||
MusicBrainz/DiscLinux.cs \
|
||||
MusicBrainz/DiscWin32.cs \
|
||||
MusicBrainz/DiscWin32NT.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
|
||||
|
||||
instdir = $(prefix)/lib/musicbrainz-sharp
|
||||
inst_SCRIPTS = $(ASSEMBLY) $(ASSEMBLY).mdb
|
||||
|
||||
$(ASSEMBLY): $(SOURCES)
|
||||
$(MCS) -out:$@ -debug -target:library -unsafe $(REFERENCES) $(SOURCES)
|
||||
|
||||
all: $(ASSEMBLY)
|
||||
|
||||
EXTRA_DIST = $(SOURCES) MusicBrainz.csproj
|
||||
|
||||
CLEANFILES = $(ASSEMBLY) $(ASSEMBLY).mdb
|
||||
DISTCLEANFILES = *.pidb
|
||||
MAINTAINERCLEANFILES = Makefile Makefile.in
|
||||
79
MusicBrainz/MusicBrainz.csproj
Normal file
79
MusicBrainz/MusicBrainz.csproj
Normal file
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.50727</ProductVersion>
|
||||
<ProjectGuid>{74C2036B-2C9B-4FC8-B7BD-AE81A8DCE533}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>MusicBrainz</RootNamespace>
|
||||
<AssemblyName>MusicBrainz</AssemblyName>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<OldToolsVersion>2.0</OldToolsVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>.</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AssemblyKeyFile>.</AssemblyKeyFile>
|
||||
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
|
||||
<RunWithWarnings>false</RunWithWarnings>
|
||||
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>none</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>.</OutputPath>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<AssemblyKeyFile>.</AssemblyKeyFile>
|
||||
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
|
||||
<TargetFrameworkVersion>v1.1</TargetFrameworkVersion>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="MusicBrainz\Artist.cs" />
|
||||
<Compile Include="MusicBrainz\Disc.cs" />
|
||||
<Compile Include="MusicBrainz\Event.cs" />
|
||||
<Compile Include="MusicBrainz\Label.cs" />
|
||||
<Compile Include="MusicBrainz\MusicBrainzEntity.cs" />
|
||||
<Compile Include="MusicBrainz\MusicBrainzException.cs" />
|
||||
<Compile Include="MusicBrainz\MusicBrainzItem.cs" />
|
||||
<Compile Include="MusicBrainz\MusicBrainzObject.cs" />
|
||||
<Compile Include="MusicBrainz\Query.cs" />
|
||||
<Compile Include="MusicBrainz\Relation.cs" />
|
||||
<Compile Include="MusicBrainz\Release.cs" />
|
||||
<Compile Include="MusicBrainz\Track.cs" />
|
||||
<Compile Include="MusicBrainz\Utils.cs" />
|
||||
<Compile Include="MusicBrainz\XmlRequestEventArgs.cs" />
|
||||
<Compile Include="MusicBrainz\MusicBrainzService.cs" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ProjectExtensions>
|
||||
<MonoDevelop>
|
||||
<Properties xmlns="">
|
||||
<MonoDevelop.Autotools.MakefileInfo IntegrationEnabled="true" RelativeMakefileName="Makefile.am" BuildTargetName="" CleanTargetName="" SyncReferences="true" IsAutotoolsProject="true" RelativeConfigureInPath="../..">
|
||||
<BuildFilesVar Sync="true" Name="SOURCES" />
|
||||
<DeployFilesVar />
|
||||
<ResourcesVar Name="REFERENCES" />
|
||||
<OthersVar />
|
||||
<GacRefVar Sync="true" Name="REFERENCES" Prefix="-r:" />
|
||||
<AsmRefVar Sync="true" Name="REFERENCES" Prefix="-r:" />
|
||||
<ProjectRefVar Sync="true" Name="REFERENCES" Prefix="-r:" />
|
||||
</MonoDevelop.Autotools.MakefileInfo>
|
||||
<MonoDevelop.ChangeLogAddIn.ChangeLogInfo policy="UseParentPolicy" />
|
||||
</Properties>
|
||||
</MonoDevelop>
|
||||
<VisualStudio />
|
||||
</ProjectExtensions>
|
||||
</Project>
|
||||
276
MusicBrainz/MusicBrainz/Artist.cs
Normal file
276
MusicBrainz/MusicBrainz/Artist.cs
Normal file
@@ -0,0 +1,276 @@
|
||||
// Artist.cs
|
||||
//
|
||||
// Copyright (c) 2008 Scott Peterson <lunchtimemama@gmail.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace MusicBrainz
|
||||
{
|
||||
public sealed class Artist : MusicBrainzEntity
|
||||
{
|
||||
|
||||
#region Private
|
||||
|
||||
const string EXTENSION = "artist";
|
||||
ArtistReleaseType artist_release_type = DefaultArtistReleaseType;
|
||||
ArtistType? type;
|
||||
ReadOnlyCollection<Release> releases;
|
||||
bool have_all_releases;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
Artist (string id) : base (id, null)
|
||||
{
|
||||
}
|
||||
|
||||
Artist (string id, ArtistReleaseType artist_release_type)
|
||||
: base (id, "&inc=" + artist_release_type.ToString ())
|
||||
{
|
||||
have_all_releases = true;
|
||||
this.artist_release_type = artist_release_type;
|
||||
}
|
||||
|
||||
internal Artist (XmlReader reader) : base (reader, false)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected
|
||||
|
||||
internal override string UrlExtension {
|
||||
get { return EXTENSION; }
|
||||
}
|
||||
|
||||
internal override void CreateIncCore (StringBuilder builder)
|
||||
{
|
||||
AppendIncParameters (builder, artist_release_type.ToString ());
|
||||
base.CreateIncCore (builder);
|
||||
}
|
||||
|
||||
internal override void LoadMissingDataCore ()
|
||||
{
|
||||
Artist artist = new Artist (Id);
|
||||
type = artist.GetArtistType ();
|
||||
base.LoadMissingDataCore (artist);
|
||||
}
|
||||
|
||||
internal override void ProcessAttributes (XmlReader reader)
|
||||
{
|
||||
switch (reader ["type"]) {
|
||||
case "Group":
|
||||
type = ArtistType.Group;
|
||||
break;
|
||||
case "Person":
|
||||
type = ArtistType.Person;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
internal override void ProcessXmlCore (XmlReader reader)
|
||||
{
|
||||
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:
|
||||
base.ProcessXmlCore (reader);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public
|
||||
|
||||
static ArtistReleaseType default_artist_release_type = new ArtistReleaseType (ReleaseStatus.Official, ReleaseArtistType.SingleArtist);
|
||||
public static ArtistReleaseType DefaultArtistReleaseType {
|
||||
get { return default_artist_release_type; }
|
||||
set {
|
||||
if (value == null) throw new ArgumentNullException ("value");
|
||||
default_artist_release_type = value;
|
||||
}
|
||||
}
|
||||
|
||||
public ArtistReleaseType ArtistReleaseType {
|
||||
get { return artist_release_type; }
|
||||
set {
|
||||
if (artist_release_type == value) {
|
||||
return;
|
||||
}
|
||||
artist_release_type = value;
|
||||
releases = null;
|
||||
have_all_releases = false;
|
||||
}
|
||||
}
|
||||
|
||||
[Queryable ("arid")]
|
||||
public override string Id {
|
||||
get { return base.Id; }
|
||||
}
|
||||
|
||||
[Queryable ("artist")]
|
||||
public override string GetName ()
|
||||
{
|
||||
return base.GetName ();
|
||||
}
|
||||
|
||||
[Queryable ("artype")]
|
||||
public ArtistType GetArtistType ()
|
||||
{
|
||||
return GetPropertyOrDefault (ref type, ArtistType.Unknown);
|
||||
}
|
||||
|
||||
public ReadOnlyCollection<Release> GetReleases ()
|
||||
{
|
||||
return releases ?? (have_all_releases
|
||||
? releases = new ReadOnlyCollection<Release> (new Release [0])
|
||||
: new Artist (Id, ArtistReleaseType).GetReleases ());
|
||||
}
|
||||
|
||||
public ReadOnlyCollection<Release> GetReleases (ArtistReleaseType artistReleaseType)
|
||||
{
|
||||
return new Artist (Id, artistReleaseType).GetReleases ();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static
|
||||
|
||||
public static Artist Get (string id)
|
||||
{
|
||||
if (id == null) throw new ArgumentNullException ("id");
|
||||
return new Artist (id);
|
||||
}
|
||||
|
||||
public static Query<Artist> Query (string name)
|
||||
{
|
||||
if (name == null) throw new ArgumentNullException ("name");
|
||||
return new Query<Artist> (EXTENSION, CreateNameParameter (name));
|
||||
}
|
||||
|
||||
public static Query<Artist> QueryLucene (string luceneQuery)
|
||||
{
|
||||
if (luceneQuery == null) throw new ArgumentNullException ("luceneQuery");
|
||||
return new Query<Artist> (EXTENSION, CreateLuceneParameter (luceneQuery));
|
||||
}
|
||||
|
||||
public static implicit operator string (Artist artist)
|
||||
{
|
||||
return artist.ToString ();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
#region Ancillary Types
|
||||
|
||||
public enum ArtistType
|
||||
{
|
||||
Unknown,
|
||||
Group,
|
||||
Person
|
||||
}
|
||||
|
||||
public enum ReleaseArtistType
|
||||
{
|
||||
VariousArtists,
|
||||
SingleArtist
|
||||
}
|
||||
|
||||
public sealed class ArtistReleaseType
|
||||
{
|
||||
string str;
|
||||
|
||||
public ArtistReleaseType (ReleaseType type, ReleaseArtistType artistType) : this ((Enum)type, artistType)
|
||||
{
|
||||
}
|
||||
|
||||
public ArtistReleaseType (ReleaseStatus status, ReleaseArtistType artistType) : this ((Enum)status, artistType)
|
||||
{
|
||||
}
|
||||
|
||||
public ArtistReleaseType (ReleaseType type, ReleaseStatus status, ReleaseArtistType artistType)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder ();
|
||||
Format (builder, type, artistType);
|
||||
builder.Append ('+');
|
||||
Format (builder, status, artistType);
|
||||
str = builder.ToString ();
|
||||
}
|
||||
|
||||
ArtistReleaseType (Enum enumeration, ReleaseArtistType artistType)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder ();
|
||||
Format (builder, enumeration, artistType);
|
||||
str = builder.ToString ();
|
||||
}
|
||||
|
||||
static void Format (StringBuilder builder, Enum enumeration, ReleaseArtistType artistType)
|
||||
{
|
||||
builder.Append (artistType == ReleaseArtistType.VariousArtists ? "va-" : "sa-");
|
||||
Utils.EnumToString (builder, enumeration.ToString ());
|
||||
}
|
||||
|
||||
public override string ToString ()
|
||||
{
|
||||
return str;
|
||||
}
|
||||
|
||||
public override bool Equals (object o)
|
||||
{
|
||||
return this == o as ArtistReleaseType;
|
||||
}
|
||||
|
||||
public static bool operator ==(ArtistReleaseType artistReleaseType1, ArtistReleaseType artistReleaseType2)
|
||||
{
|
||||
if (Object.ReferenceEquals (artistReleaseType1, null)) {
|
||||
return Object.ReferenceEquals (artistReleaseType2, null);
|
||||
}
|
||||
return !Object.ReferenceEquals (artistReleaseType2, null) && artistReleaseType1.str == artistReleaseType2.str;
|
||||
}
|
||||
|
||||
public static bool operator !=(ArtistReleaseType artistReleaseType1, ArtistReleaseType artistReleaseType2)
|
||||
{
|
||||
return !(artistReleaseType1 == artistReleaseType2);
|
||||
}
|
||||
|
||||
public override int GetHashCode ()
|
||||
{
|
||||
return str.GetHashCode ();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
55
MusicBrainz/MusicBrainz/Disc.cs
Normal file
55
MusicBrainz/MusicBrainz/Disc.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
// Disc.cs
|
||||
//
|
||||
// Copyright (c) 2008 Scott Peterson <lunchtimemama@gmail.com>
|
||||
//
|
||||
// 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.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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
76
MusicBrainz/MusicBrainz/Event.cs
Normal file
76
MusicBrainz/MusicBrainz/Event.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
// Event.cs
|
||||
//
|
||||
// Copyright (c) 2008 Scott Peterson <lunchtimemama@gmail.com>
|
||||
//
|
||||
// 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.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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
137
MusicBrainz/MusicBrainz/Label.cs
Normal file
137
MusicBrainz/MusicBrainz/Label.cs
Normal file
@@ -0,0 +1,137 @@
|
||||
// Label.cs
|
||||
//
|
||||
// Copyright (c) 2008 Scott Peterson <lunchtimemama@gmail.com>
|
||||
//
|
||||
// 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.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace MusicBrainz
|
||||
{
|
||||
public sealed class Label : MusicBrainzEntity
|
||||
{
|
||||
|
||||
#region Private
|
||||
|
||||
const string EXTENSION = "label";
|
||||
string country;
|
||||
LabelType? type;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
Label (string id) : base (id, null)
|
||||
{
|
||||
}
|
||||
|
||||
internal Label (XmlReader reader) : base (reader, false)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected
|
||||
|
||||
internal override string UrlExtension {
|
||||
get { return EXTENSION; }
|
||||
}
|
||||
|
||||
internal override void LoadMissingDataCore ()
|
||||
{
|
||||
Label label = new Label (Id);
|
||||
type = label.GetLabelType ();
|
||||
country = label.GetCountry ();
|
||||
base.LoadMissingDataCore (label);
|
||||
}
|
||||
|
||||
internal override void ProcessAttributes (XmlReader reader)
|
||||
{
|
||||
type = Utils.StringToEnum<LabelType> (reader ["type"]);
|
||||
}
|
||||
|
||||
internal override void ProcessXmlCore (XmlReader reader)
|
||||
{
|
||||
if (reader.Name == "country") {
|
||||
country = reader.ReadString ();
|
||||
} else base.ProcessXmlCore (reader);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public
|
||||
|
||||
public string GetCountry ()
|
||||
{
|
||||
return GetPropertyOrNull (ref country);
|
||||
}
|
||||
|
||||
public LabelType GetLabelType ()
|
||||
{
|
||||
return GetPropertyOrDefault (ref type, LabelType.None);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static
|
||||
|
||||
public static Label Get (string id)
|
||||
{
|
||||
if (id == null) throw new ArgumentNullException ("id");
|
||||
return new Label (id);
|
||||
}
|
||||
|
||||
public static Query<Label> Query (string name)
|
||||
{
|
||||
if (name == null) throw new ArgumentNullException ("name");
|
||||
return new Query<Label> (EXTENSION, CreateNameParameter (name));
|
||||
}
|
||||
|
||||
public static Query<Label> QueryLucene (string luceneQuery)
|
||||
{
|
||||
if (luceneQuery == null) throw new ArgumentNullException ("luceneQuery");
|
||||
return new Query<Label> (EXTENSION, CreateLuceneParameter (luceneQuery));
|
||||
}
|
||||
|
||||
public static implicit operator string (Label label)
|
||||
{
|
||||
return label.ToString ();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
#region Ancillary Types
|
||||
|
||||
public enum LabelType
|
||||
{
|
||||
None,
|
||||
Distributor,
|
||||
Holding,
|
||||
OriginalProduction,
|
||||
BootlegProduction,
|
||||
ReissueProduction
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
162
MusicBrainz/MusicBrainz/MusicBrainzEntity.cs
Normal file
162
MusicBrainz/MusicBrainz/MusicBrainzEntity.cs
Normal file
@@ -0,0 +1,162 @@
|
||||
// MusicBrainzEntity.cs
|
||||
//
|
||||
// Copyright (c) 2008 Scott Peterson <lunchtimemama@gmail.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.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
|
||||
{
|
||||
|
||||
#region Private
|
||||
|
||||
string name;
|
||||
string sort_name;
|
||||
string disambiguation;
|
||||
string begin_date;
|
||||
string end_date;
|
||||
ReadOnlyCollection<string> aliases;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
internal MusicBrainzEntity (string id, string parameters) : base (id, parameters)
|
||||
{
|
||||
}
|
||||
|
||||
internal MusicBrainzEntity (XmlReader reader, bool all_rels_loaded) : base (reader, all_rels_loaded)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected
|
||||
|
||||
internal override void CreateIncCore (StringBuilder builder)
|
||||
{
|
||||
if (aliases == null) AppendIncParameters (builder, "aliases");
|
||||
base.CreateIncCore (builder);
|
||||
}
|
||||
|
||||
internal void LoadMissingDataCore (MusicBrainzEntity entity)
|
||||
{
|
||||
name = entity.GetName ();
|
||||
sort_name = entity.GetSortName ();
|
||||
disambiguation = entity.GetDisambiguation ();
|
||||
begin_date = entity.GetBeginDate ();
|
||||
end_date = entity.GetEndDate ();
|
||||
if (aliases == null) aliases = entity.GetAliases ();
|
||||
base.LoadMissingDataCore (entity);
|
||||
}
|
||||
|
||||
internal override void ProcessXmlCore (XmlReader reader)
|
||||
{
|
||||
switch (reader.Name) {
|
||||
case "name":
|
||||
name = reader.ReadString ();
|
||||
break;
|
||||
case "sort-name":
|
||||
sort_name = reader.ReadString ();
|
||||
break;
|
||||
case "disambiguation":
|
||||
disambiguation = reader.ReadString ();
|
||||
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 aliases.Add (reader.ReadString ());
|
||||
while (reader.ReadToNextSibling ("alias"));
|
||||
this.aliases = aliases.AsReadOnly ();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
base.ProcessXmlCore (reader);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
internal static string CreateNameParameter (string name)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder (name.Length + 6);
|
||||
builder.Append ("&name=");
|
||||
Utils.PercentEncode (builder, name);
|
||||
return builder.ToString ();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public
|
||||
|
||||
public virtual string GetName ()
|
||||
{
|
||||
return GetPropertyOrNull (ref name);
|
||||
}
|
||||
|
||||
[Queryable ("sortname")]
|
||||
public virtual string GetSortName ()
|
||||
{
|
||||
return GetPropertyOrNull (ref sort_name);
|
||||
}
|
||||
|
||||
[Queryable ("comment")]
|
||||
public virtual string GetDisambiguation ()
|
||||
{
|
||||
return GetPropertyOrNull (ref disambiguation);
|
||||
}
|
||||
|
||||
[Queryable ("begin")]
|
||||
public virtual string GetBeginDate ()
|
||||
{
|
||||
return GetPropertyOrNull (ref begin_date);
|
||||
}
|
||||
|
||||
[Queryable ("end")]
|
||||
public virtual string GetEndDate ()
|
||||
{
|
||||
return GetPropertyOrNull (ref end_date);
|
||||
}
|
||||
|
||||
[QueryableMember ("Contains", "alias")]
|
||||
public virtual ReadOnlyCollection<string> GetAliases ()
|
||||
{
|
||||
return GetPropertyOrNew (ref aliases);
|
||||
}
|
||||
|
||||
public override string ToString ()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
50
MusicBrainz/MusicBrainz/MusicBrainzException.cs
Normal file
50
MusicBrainz/MusicBrainz/MusicBrainzException.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
// MusicBrainzException.cs
|
||||
//
|
||||
// Copyright (c) 2008 Scott Peterson <lunchtimemama@gmail.com>
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace MusicBrainz
|
||||
{
|
||||
public sealed class MusicBrainzInvalidParameterException : Exception
|
||||
{
|
||||
public MusicBrainzInvalidParameterException ()
|
||||
: base ("One of the parameters is invalid. The ID 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.")
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
187
MusicBrainz/MusicBrainz/MusicBrainzItem.cs
Normal file
187
MusicBrainz/MusicBrainz/MusicBrainzItem.cs
Normal file
@@ -0,0 +1,187 @@
|
||||
// MusicBrainzItem.cs
|
||||
//
|
||||
// Copyright (c) 2008 Scott Peterson <lunchtimemama@gmail.com>
|
||||
//
|
||||
// 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.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace MusicBrainz
|
||||
{
|
||||
// The item-like product of an artist, such as a track or a release.
|
||||
public abstract class MusicBrainzItem : MusicBrainzObject
|
||||
{
|
||||
|
||||
#region Private
|
||||
|
||||
string title;
|
||||
Artist artist;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
internal MusicBrainzItem (string id) : base (id, null)
|
||||
{
|
||||
}
|
||||
|
||||
internal MusicBrainzItem (XmlReader reader, Artist artist, bool all_rels_loaded) : base (reader, all_rels_loaded)
|
||||
{
|
||||
if (this.artist == null) this.artist = artist;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected Overrides
|
||||
|
||||
internal override void CreateIncCore (StringBuilder builder)
|
||||
{
|
||||
if (artist == null) AppendIncParameters(builder, "artist");
|
||||
base.CreateIncCore (builder);
|
||||
}
|
||||
|
||||
internal void LoadMissingDataCore (MusicBrainzItem item)
|
||||
{
|
||||
title = item.GetTitle ();
|
||||
if (artist == null) artist = item.GetArtist ();
|
||||
base.LoadMissingDataCore (item);
|
||||
}
|
||||
|
||||
internal override void ProcessXmlCore (XmlReader reader)
|
||||
{
|
||||
switch (reader.Name) {
|
||||
case "title":
|
||||
title = reader.ReadString ();
|
||||
break;
|
||||
case "artist":
|
||||
artist = new Artist (reader.ReadSubtree ());
|
||||
break;
|
||||
default:
|
||||
base.ProcessXmlCore (reader);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public
|
||||
|
||||
public virtual string GetTitle ()
|
||||
{
|
||||
return GetPropertyOrNull (ref title);
|
||||
}
|
||||
|
||||
[Queryable ("artist")]
|
||||
public virtual Artist GetArtist ()
|
||||
{
|
||||
return GetPropertyOrNull (ref artist);
|
||||
}
|
||||
|
||||
public override string ToString ()
|
||||
{
|
||||
return title;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
#region Ancillary Types
|
||||
|
||||
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; }
|
||||
}
|
||||
|
||||
internal abstract void ToStringCore (StringBuilder builder);
|
||||
|
||||
public override string ToString ()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder ();
|
||||
ToStringCore (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);
|
||||
}
|
||||
return builder.ToString ();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
485
MusicBrainz/MusicBrainz/MusicBrainzObject.cs
Normal file
485
MusicBrainz/MusicBrainz/MusicBrainzObject.cs
Normal file
@@ -0,0 +1,485 @@
|
||||
// MusicBrainzObject.cs
|
||||
//
|
||||
// Copyright (c) 2008 Scott Peterson <lunchtimemama@gmail.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Xml;
|
||||
|
||||
namespace MusicBrainz
|
||||
{
|
||||
public abstract class MusicBrainzObject
|
||||
{
|
||||
|
||||
#region Private Fields
|
||||
|
||||
static DateTime last_accessed;
|
||||
static readonly TimeSpan min_interval = new TimeSpan (0, 0, 1); // 1 second
|
||||
static readonly object server_mutex = new object ();
|
||||
static readonly string [] rels_params = new string [] {
|
||||
"artist-rels",
|
||||
"release-rels",
|
||||
"track-rels",
|
||||
"label-rels",
|
||||
"url-rels"
|
||||
};
|
||||
|
||||
bool all_data_loaded;
|
||||
bool all_rels_loaded;
|
||||
|
||||
string id;
|
||||
byte score;
|
||||
ReadOnlyCollection<Relation<Artist>> artist_rels;
|
||||
ReadOnlyCollection<Relation<Release>> release_rels;
|
||||
ReadOnlyCollection<Relation<Track>> track_rels;
|
||||
ReadOnlyCollection<Relation<Label>> label_rels;
|
||||
ReadOnlyCollection<UrlRelation> url_rels;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
internal MusicBrainzObject (string id, string parameters)
|
||||
{
|
||||
all_data_loaded = true;
|
||||
CreateFromId (id, parameters ?? CreateInc ());
|
||||
}
|
||||
|
||||
internal MusicBrainzObject (XmlReader reader, bool all_rels_loaded)
|
||||
{
|
||||
this.all_rels_loaded = all_rels_loaded;
|
||||
CreateFromXml (reader);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
string CreateInc ()
|
||||
{
|
||||
StringBuilder builder = new StringBuilder ();
|
||||
CreateIncCore (builder);
|
||||
return builder.ToString ();
|
||||
}
|
||||
|
||||
void CreateFromId (string id, string parameters)
|
||||
{
|
||||
XmlProcessingClosure (
|
||||
CreateUrl (UrlExtension, id, parameters),
|
||||
delegate (XmlReader reader) {
|
||||
reader.ReadToFollowing ("metadata");
|
||||
reader.Read ();
|
||||
CreateFromXml (reader.ReadSubtree ());
|
||||
reader.Close ();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void CreateFromXml (XmlReader reader)
|
||||
{
|
||||
reader.Read ();
|
||||
id = reader ["id"];
|
||||
byte.TryParse (reader ["ext:score"], out score);
|
||||
ProcessAttributes (reader);
|
||||
while (reader.Read () && reader.NodeType != XmlNodeType.EndElement) {
|
||||
if (reader.Name == "relation-list") {
|
||||
all_rels_loaded = true;
|
||||
switch (reader ["target-type"]) {
|
||||
case "Artist":
|
||||
artist_rels = CreateRelation<Artist> (reader.ReadSubtree ());
|
||||
break;
|
||||
case "Release":
|
||||
release_rels = CreateRelation<Release> (reader.ReadSubtree ());
|
||||
break;
|
||||
case "Track":
|
||||
track_rels = CreateRelation<Track> (reader.ReadSubtree ());
|
||||
break;
|
||||
case "Label":
|
||||
label_rels = CreateRelation<Label> (reader.ReadSubtree ());
|
||||
break;
|
||||
case "Url":
|
||||
url_rels = CreateUrlRelation (reader.ReadSubtree ());
|
||||
break;
|
||||
}
|
||||
} else
|
||||
ProcessXml (reader.ReadSubtree ());
|
||||
}
|
||||
reader.Close ();
|
||||
}
|
||||
|
||||
void ProcessXml (XmlReader reader)
|
||||
{
|
||||
reader.Read ();
|
||||
ProcessXmlCore (reader);
|
||||
reader.Close ();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected
|
||||
|
||||
internal bool AllDataLoaded {
|
||||
get { return all_data_loaded; }
|
||||
}
|
||||
|
||||
internal bool AllRelsLoaded {
|
||||
get { return all_rels_loaded; }
|
||||
set { all_rels_loaded = value; }
|
||||
}
|
||||
|
||||
internal virtual void CreateIncCore (StringBuilder builder)
|
||||
{
|
||||
if (!all_rels_loaded)
|
||||
AppendIncParameters (builder, rels_params);
|
||||
}
|
||||
|
||||
internal static void AppendIncParameters (StringBuilder builder, string parameter)
|
||||
{
|
||||
builder.Append (builder.Length == 0 ? "&inc=" : "+");
|
||||
builder.Append (parameter);
|
||||
}
|
||||
|
||||
internal static void AppendIncParameters (StringBuilder builder, string parameter1, string parameter2)
|
||||
{
|
||||
builder.Append (builder.Length == 0 ? "&inc=" : "+");
|
||||
builder.Append (parameter1);
|
||||
builder.Append ('+');
|
||||
builder.Append (parameter2);
|
||||
}
|
||||
|
||||
internal static void AppendIncParameters (StringBuilder builder, string [] parameters)
|
||||
{
|
||||
foreach (string parameter in parameters)
|
||||
AppendIncParameters (builder, parameter);
|
||||
}
|
||||
|
||||
internal void LoadMissingData ()
|
||||
{
|
||||
if (!all_data_loaded) {
|
||||
LoadMissingDataCore ();
|
||||
all_data_loaded = true;
|
||||
}
|
||||
}
|
||||
|
||||
internal void LoadMissingDataCore (MusicBrainzObject obj)
|
||||
{
|
||||
if (!all_rels_loaded) {
|
||||
artist_rels = obj.GetArtistRelations ();
|
||||
release_rels = obj.GetReleaseRelations ();
|
||||
track_rels = obj.GetTrackRelations ();
|
||||
label_rels = obj.GetLabelRelations ();
|
||||
url_rels = obj.GetUrlRelations ();
|
||||
}
|
||||
}
|
||||
|
||||
internal T GetPropertyOrNull<T> (ref T field_reference) where T : class
|
||||
{
|
||||
if (field_reference == null) LoadMissingData ();
|
||||
return field_reference;
|
||||
}
|
||||
|
||||
internal T GetPropertyOrDefault<T> (ref T? field_reference) where T : struct
|
||||
{
|
||||
return GetPropertyOrDefault (ref field_reference, default (T));
|
||||
}
|
||||
|
||||
internal T GetPropertyOrDefault<T> (ref T? field_reference, T default_value) where T : struct
|
||||
{
|
||||
if (field_reference == null) LoadMissingData ();
|
||||
return field_reference ?? default_value;
|
||||
}
|
||||
|
||||
internal ReadOnlyCollection<T> GetPropertyOrNew<T> (ref ReadOnlyCollection<T> field_reference)
|
||||
{
|
||||
return GetPropertyOrNew (ref field_reference, true);
|
||||
}
|
||||
|
||||
internal 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]);
|
||||
}
|
||||
|
||||
internal virtual void ProcessXmlCore (XmlReader reader)
|
||||
{
|
||||
reader.Skip (); // FIXME this is a workaround for Mono bug 334752
|
||||
}
|
||||
|
||||
internal virtual void ProcessAttributes (XmlReader reader)
|
||||
{
|
||||
}
|
||||
|
||||
internal abstract void LoadMissingDataCore ();
|
||||
internal abstract string UrlExtension { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public
|
||||
|
||||
public virtual string Id {
|
||||
get { return id; }
|
||||
}
|
||||
|
||||
public virtual byte Score {
|
||||
get { return score; }
|
||||
}
|
||||
|
||||
public virtual ReadOnlyCollection<Relation<Artist>> GetArtistRelations ()
|
||||
{
|
||||
return GetPropertyOrNew (ref artist_rels, !all_rels_loaded);
|
||||
}
|
||||
|
||||
public virtual ReadOnlyCollection<Relation<Release>> GetReleaseRelations ()
|
||||
{
|
||||
return GetPropertyOrNew (ref release_rels, !all_rels_loaded);
|
||||
}
|
||||
|
||||
public virtual ReadOnlyCollection<Relation<Track>> GetTrackRelations ()
|
||||
{
|
||||
return GetPropertyOrNew (ref track_rels, !all_rels_loaded);
|
||||
}
|
||||
|
||||
public virtual ReadOnlyCollection<Relation<Label>> GetLabelRelations ()
|
||||
{
|
||||
return GetPropertyOrNew (ref label_rels, !all_rels_loaded);
|
||||
}
|
||||
|
||||
public virtual ReadOnlyCollection<UrlRelation> GetUrlRelations ()
|
||||
{
|
||||
return GetPropertyOrNew (ref url_rels, !all_rels_loaded);
|
||||
}
|
||||
|
||||
public override bool Equals (object obj)
|
||||
{
|
||||
return this == obj as MusicBrainzObject;
|
||||
}
|
||||
|
||||
public static bool operator ==(MusicBrainzObject obj1, MusicBrainzObject obj2)
|
||||
{
|
||||
if (Object.ReferenceEquals (obj1, null)) {
|
||||
return Object.ReferenceEquals (obj2, null);
|
||||
}
|
||||
return !Object.ReferenceEquals (obj2, null) && obj1.GetType () == obj2.GetType () && obj1.Id == obj2.Id;
|
||||
}
|
||||
|
||||
public static bool operator !=(MusicBrainzObject obj1, MusicBrainzObject obj2)
|
||||
{
|
||||
return !(obj1 == obj2);
|
||||
}
|
||||
|
||||
public override int GetHashCode ()
|
||||
{
|
||||
return (GetType ().Name + Id).GetHashCode ();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static
|
||||
|
||||
static ReadOnlyCollection<Relation<T>> CreateRelation<T> (XmlReader reader) where T : MusicBrainzObject
|
||||
{
|
||||
List<Relation<T>> relations = new List<Relation<T>> ();
|
||||
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 ();
|
||||
return relations.AsReadOnly ();
|
||||
}
|
||||
|
||||
static ReadOnlyCollection<UrlRelation> CreateUrlRelation (XmlReader reader)
|
||||
{
|
||||
List<UrlRelation> url_rels = new List<UrlRelation> ();
|
||||
while (reader.ReadToDescendant ("relation")) {
|
||||
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));
|
||||
}
|
||||
return url_rels.AsReadOnly ();
|
||||
}
|
||||
|
||||
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 id, string parameters)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder (
|
||||
MusicBrainzService.ServiceUrl.AbsoluteUri.Length + id.Length + parameters.Length + 9);
|
||||
builder.Append (MusicBrainzService.ServiceUrl.AbsoluteUri);
|
||||
builder.Append (url_extension);
|
||||
builder.Append ('/');
|
||||
builder.Append (id);
|
||||
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);
|
||||
|
||||
WebRequest request = WebRequest.Create (url);
|
||||
bool cache_implemented = false;
|
||||
|
||||
try {
|
||||
request.CachePolicy = MusicBrainzService.CachePolicy;
|
||||
cache_implemented = true;
|
||||
} catch (NotImplementedException) {}
|
||||
|
||||
HttpWebResponse response = null;
|
||||
|
||||
try {
|
||||
response = (HttpWebResponse)request.GetResponse ();
|
||||
} 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;
|
||||
|
||||
if (from_cache) Monitor.Exit (server_mutex);
|
||||
|
||||
MusicBrainzService.OnXmlRequest (url, from_cache);
|
||||
|
||||
// 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
|
||||
|
||||
internal static string CreateLuceneParameter (string query)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder (query.Length + 7);
|
||||
builder.Append ("&query=");
|
||||
Utils.PercentEncode (builder, query);
|
||||
return builder.ToString ();
|
||||
}
|
||||
|
||||
internal static List<T> Query<T> (string url_extension,
|
||||
int 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
|
||||
|
||||
}
|
||||
|
||||
internal delegate void XmlProcessingDelegate (XmlReader reader);
|
||||
}
|
||||
53
MusicBrainz/MusicBrainz/MusicBrainzService.cs
Normal file
53
MusicBrainz/MusicBrainz/MusicBrainzService.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
// MusicBrainzService.cs
|
||||
//
|
||||
// Copyright (c) 2008 Scott Peterson <lunchtimemama@gmail.com>
|
||||
//
|
||||
// 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.Net.Cache;
|
||||
|
||||
namespace MusicBrainz
|
||||
{
|
||||
public static class MusicBrainzService
|
||||
{
|
||||
static Uri service_url = new Uri (@"http://musicbrainz.org/ws/1/");
|
||||
public static Uri ServiceUrl {
|
||||
get { return service_url; }
|
||||
set {
|
||||
if (value == null) throw new ArgumentNullException ("value");
|
||||
service_url = value;
|
||||
}
|
||||
}
|
||||
|
||||
static RequestCachePolicy cache_policy;
|
||||
public static RequestCachePolicy CachePolicy {
|
||||
get { return cache_policy; }
|
||||
set { cache_policy = value; }
|
||||
}
|
||||
|
||||
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 (new Uri (url), fromCache));
|
||||
}
|
||||
}
|
||||
}
|
||||
197
MusicBrainz/MusicBrainz/Query.cs
Normal file
197
MusicBrainz/MusicBrainz/Query.cs
Normal file
@@ -0,0 +1,197 @@
|
||||
// Query.cs
|
||||
//
|
||||
// Copyright (c) 2008 Scott Peterson <lunchtimemama@gmail.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace MusicBrainz
|
||||
{
|
||||
public sealed class Query<T> : IEnumerable<T> where T : MusicBrainzObject
|
||||
{
|
||||
|
||||
#region Private
|
||||
|
||||
const int default_limit = 100;
|
||||
|
||||
string parameters;
|
||||
string url_extension;
|
||||
int limit = default_limit;
|
||||
|
||||
int offset;
|
||||
int? count;
|
||||
|
||||
List<T> results;
|
||||
List<T> ResultsWindow {
|
||||
get {
|
||||
if (results == null)
|
||||
LoadResults ();
|
||||
return results;
|
||||
}
|
||||
}
|
||||
|
||||
void LoadResults ()
|
||||
{
|
||||
results = MusicBrainzObject.Query<T> (url_extension, limit, offset, parameters, out count);
|
||||
}
|
||||
|
||||
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 = (List<T>)weak_reference.Target;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
internal Query (string url_extension, string parameters)
|
||||
{
|
||||
this.url_extension = url_extension;
|
||||
this.parameters = parameters;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public
|
||||
|
||||
public int Count {
|
||||
get {
|
||||
if (count == null)
|
||||
LoadResults ();
|
||||
return count.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public T this [int index] {
|
||||
get {
|
||||
if (index < 0 || index >= Count) throw new ArgumentOutOfRangeException ("index");
|
||||
if (index < offset || index >= offset + limit)
|
||||
Offset = index;
|
||||
return ResultsWindow[index - offset];
|
||||
}
|
||||
}
|
||||
|
||||
public T First ()
|
||||
{
|
||||
int tmp_limit = limit;
|
||||
limit = 1;
|
||||
T result = Count > 0 ? this [0] : null;
|
||||
limit = tmp_limit;
|
||||
return result;
|
||||
}
|
||||
|
||||
public T PerfectMatch ()
|
||||
{
|
||||
int 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 IEnumerable<T> Best ()
|
||||
{
|
||||
return Best (100);
|
||||
}
|
||||
|
||||
public IEnumerable<T> Best (int scoreThreshold)
|
||||
{
|
||||
foreach (T result in this) {
|
||||
if (result.Score < scoreThreshold) yield break;
|
||||
yield return result;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator<T> GetEnumerator ()
|
||||
{
|
||||
for (int i = 0; i < Count; i++) yield return this [i];
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator ()
|
||||
{
|
||||
return GetEnumerator ();
|
||||
}
|
||||
|
||||
public static implicit operator T (Query<T> query)
|
||||
{
|
||||
return query.First ();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
[AttributeUsage (AttributeTargets.Method | AttributeTargets.Property)]
|
||||
internal sealed class QueryableAttribute : Attribute
|
||||
{
|
||||
readonly string name;
|
||||
|
||||
public QueryableAttribute (string name)
|
||||
{
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public string Name {
|
||||
get { return name; }
|
||||
}
|
||||
}
|
||||
|
||||
[AttributeUsage (AttributeTargets.Method | AttributeTargets.Property)]
|
||||
internal sealed class QueryableMemberAttribute : Attribute
|
||||
{
|
||||
readonly string member;
|
||||
readonly string name;
|
||||
|
||||
public QueryableMemberAttribute (string member, string name)
|
||||
{
|
||||
this.member = member;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public string Member {
|
||||
get { return member; }
|
||||
}
|
||||
|
||||
public string Name {
|
||||
get { return name; }
|
||||
}
|
||||
}
|
||||
}
|
||||
104
MusicBrainz/MusicBrainz/Relation.cs
Normal file
104
MusicBrainz/MusicBrainz/Relation.cs
Normal file
@@ -0,0 +1,104 @@
|
||||
// Relation.cs
|
||||
//
|
||||
// Copyright (c) 2008 Scott Peterson <lunchtimemama@gmail.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace MusicBrainz
|
||||
{
|
||||
public abstract class RelationBase<T>
|
||||
{
|
||||
T target;
|
||||
string type;
|
||||
ReadOnlyCollection<string> attributes;
|
||||
RelationDirection direction;
|
||||
string begin;
|
||||
string end;
|
||||
|
||||
internal RelationBase (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 = new ReadOnlyCollection<string> (attributes ?? new string [0]);
|
||||
}
|
||||
|
||||
public T Target {
|
||||
get { return target; }
|
||||
}
|
||||
|
||||
public string Type {
|
||||
get { return type; }
|
||||
}
|
||||
|
||||
public ReadOnlyCollection<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> : RelationBase<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 : RelationBase<Uri>
|
||||
{
|
||||
internal UrlRelation(string type,
|
||||
string target,
|
||||
RelationDirection direction,
|
||||
string begin,
|
||||
string end,
|
||||
string [] attributes)
|
||||
: base (type, new Uri (target), direction, begin, end, attributes)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public enum RelationDirection
|
||||
{
|
||||
Forward,
|
||||
Backward
|
||||
}
|
||||
}
|
||||
395
MusicBrainz/MusicBrainz/Release.cs
Normal file
395
MusicBrainz/MusicBrainz/Release.cs
Normal file
@@ -0,0 +1,395 @@
|
||||
// Release.cs
|
||||
//
|
||||
// Copyright (c) 2008 Scott Peterson <lunchtimemama@gmail.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace MusicBrainz
|
||||
{
|
||||
public sealed class Release : MusicBrainzItem
|
||||
{
|
||||
|
||||
#region Private
|
||||
|
||||
const string EXTENSION = "release";
|
||||
ReleaseType? type;
|
||||
ReleaseStatus? status;
|
||||
string language;
|
||||
string script;
|
||||
string asin;
|
||||
ReadOnlyCollection<Disc> discs;
|
||||
ReadOnlyCollection<Event> events;
|
||||
ReadOnlyCollection<Track> tracks;
|
||||
int? track_number;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
Release (string id) : base (id)
|
||||
{
|
||||
}
|
||||
|
||||
internal Release (XmlReader reader) : base (reader, null, false)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected
|
||||
|
||||
internal override string UrlExtension {
|
||||
get { return EXTENSION; }
|
||||
}
|
||||
|
||||
static readonly string [] track_params = new string [] { "tracks", "track-level-rels", "artist" };
|
||||
|
||||
internal override void CreateIncCore (StringBuilder builder)
|
||||
{
|
||||
AppendIncParameters (builder, "release-events", "labels");
|
||||
if (discs == null) AppendIncParameters (builder, "discs");
|
||||
if (tracks == null) {
|
||||
AppendIncParameters (builder, track_params);
|
||||
AllRelsLoaded = false;
|
||||
}
|
||||
base.CreateIncCore (builder);
|
||||
}
|
||||
|
||||
internal override void LoadMissingDataCore ()
|
||||
{
|
||||
Release release = new Release (Id);
|
||||
type = release.GetReleaseType ();
|
||||
status = release.GetReleaseStatus ();
|
||||
language = release.GetLanguage ();
|
||||
script = release.GetScript ();
|
||||
asin = release.GetAsin ();
|
||||
events = release.GetEvents ();
|
||||
if (discs == null) discs = release.GetDiscs ();
|
||||
if (tracks == null) tracks = release.GetTracks ();
|
||||
base.LoadMissingDataCore (release);
|
||||
}
|
||||
|
||||
internal override void ProcessAttributes (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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal override void ProcessXmlCore (XmlReader reader)
|
||||
{
|
||||
switch (reader.Name) {
|
||||
case "text-representation":
|
||||
language = reader["language"];
|
||||
script = reader["script"];
|
||||
break;
|
||||
case "asin":
|
||||
asin = reader.ReadString ();
|
||||
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
|
||||
return;
|
||||
}
|
||||
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 (), GetArtist (), AllDataLoaded));
|
||||
while (reader.ReadToNextSibling ("track"));
|
||||
this.tracks = tracks.AsReadOnly ();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
base.ProcessXmlCore (reader);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public
|
||||
|
||||
[Queryable ("reid")]
|
||||
public override string Id {
|
||||
get { return base.Id; }
|
||||
}
|
||||
|
||||
[Queryable ("release")]
|
||||
public override string GetTitle ()
|
||||
{
|
||||
return base.GetTitle ();
|
||||
}
|
||||
|
||||
[Queryable ("type")]
|
||||
public ReleaseType GetReleaseType ()
|
||||
{
|
||||
return GetPropertyOrDefault (ref type, ReleaseType.None);
|
||||
}
|
||||
|
||||
[Queryable ("status")]
|
||||
public ReleaseStatus GetReleaseStatus ()
|
||||
{
|
||||
return GetPropertyOrDefault (ref status, ReleaseStatus.None);
|
||||
}
|
||||
|
||||
public string GetLanguage ()
|
||||
{
|
||||
return GetPropertyOrNull (ref language);
|
||||
}
|
||||
|
||||
[Queryable ("script")]
|
||||
public string GetScript ()
|
||||
{
|
||||
return GetPropertyOrNull (ref script);
|
||||
}
|
||||
|
||||
[Queryable ("asin")]
|
||||
public string GetAsin ()
|
||||
{
|
||||
return GetPropertyOrNull (ref asin);
|
||||
}
|
||||
|
||||
[QueryableMember("Count", "discids")]
|
||||
public ReadOnlyCollection<Disc> GetDiscs ()
|
||||
{
|
||||
return GetPropertyOrNew (ref discs);
|
||||
}
|
||||
|
||||
public ReadOnlyCollection<Event> GetEvents ()
|
||||
{
|
||||
return GetPropertyOrNew (ref events);
|
||||
}
|
||||
|
||||
[QueryableMember ("Count", "tracks")]
|
||||
public ReadOnlyCollection<Track> GetTracks ()
|
||||
{
|
||||
return GetPropertyOrNew (ref tracks);
|
||||
}
|
||||
|
||||
internal int TrackNumber {
|
||||
get { return track_number ?? -1; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static
|
||||
|
||||
public static Release Get (string id)
|
||||
{
|
||||
if (id == null) throw new ArgumentNullException ("id");
|
||||
return new Release (id);
|
||||
}
|
||||
|
||||
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 (Disc disc)
|
||||
{
|
||||
if (disc == null) throw new ArgumentNullException ("disc");
|
||||
|
||||
ReleaseQueryParameters parameters = new ReleaseQueryParameters ();
|
||||
parameters.DiscId = disc.Id;
|
||||
return Query (parameters);
|
||||
}
|
||||
|
||||
public static Query<Release> Query (ReleaseQueryParameters parameters)
|
||||
{
|
||||
if (parameters == null) throw new ArgumentNullException ("parameters");
|
||||
return new Query<Release> (EXTENSION, 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, CreateLuceneParameter (luceneQuery));
|
||||
}
|
||||
|
||||
public static implicit operator string (Release release)
|
||||
{
|
||||
return release.ToString ();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
#region Ancillary Types
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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; }
|
||||
}
|
||||
|
||||
internal override void ToStringCore (StringBuilder builder)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
276
MusicBrainz/MusicBrainz/Track.cs
Normal file
276
MusicBrainz/MusicBrainz/Track.cs
Normal file
@@ -0,0 +1,276 @@
|
||||
// Track.cs
|
||||
//
|
||||
// Copyright (c) 2008 Scott Peterson <lunchtimemama@gmail.com>
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text;
|
||||
using System.Xml;
|
||||
|
||||
namespace MusicBrainz
|
||||
{
|
||||
public sealed class Track : MusicBrainzItem
|
||||
{
|
||||
|
||||
#region Private
|
||||
|
||||
const string EXTENSION = "track";
|
||||
TimeSpan? duration;
|
||||
ReadOnlyCollection<Release> releases;
|
||||
ReadOnlyCollection<string> puids;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
Track (string id) : base (id)
|
||||
{
|
||||
}
|
||||
|
||||
internal Track (XmlReader reader) : base (reader, null, false)
|
||||
{
|
||||
}
|
||||
|
||||
internal Track (XmlReader reader, Artist artist, bool all_rels_loaded) : base (reader, artist, all_rels_loaded)
|
||||
{
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Protected
|
||||
|
||||
internal override string UrlExtension {
|
||||
get { return EXTENSION; }
|
||||
}
|
||||
|
||||
internal override void CreateIncCore (StringBuilder builder)
|
||||
{
|
||||
if (releases == null) AppendIncParameters (builder, "releases");
|
||||
if (puids == null) AppendIncParameters (builder, "puids");
|
||||
base.CreateIncCore (builder);
|
||||
}
|
||||
|
||||
internal override void LoadMissingDataCore ()
|
||||
{
|
||||
Track track = new Track (Id);
|
||||
duration = track.GetDuration ();
|
||||
if (releases == null) releases = track.GetReleases ();
|
||||
if (puids == null) puids = track.GetPuids ();
|
||||
base.LoadMissingDataCore (track);
|
||||
}
|
||||
|
||||
internal override void ProcessXmlCore (XmlReader reader)
|
||||
{
|
||||
switch (reader.Name) {
|
||||
case "duration":
|
||||
duration = TimeSpan.FromMilliseconds (reader.ReadElementContentAsDouble ());
|
||||
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:
|
||||
base.ProcessXmlCore (reader);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public
|
||||
|
||||
[Queryable ("trid")]
|
||||
public override string Id {
|
||||
get { return base.Id; }
|
||||
}
|
||||
|
||||
[Queryable ("track")]
|
||||
public override string GetTitle ()
|
||||
{
|
||||
return base.GetTitle ();
|
||||
}
|
||||
|
||||
[Queryable ("dur")]
|
||||
public TimeSpan GetDuration ()
|
||||
{
|
||||
return GetPropertyOrDefault (ref duration);
|
||||
}
|
||||
|
||||
[QueryableMember ("Contains", "release")]
|
||||
public ReadOnlyCollection<Release> GetReleases ()
|
||||
{
|
||||
return GetPropertyOrNew (ref releases);
|
||||
}
|
||||
|
||||
public ReadOnlyCollection<string> GetPuids ()
|
||||
{
|
||||
return GetPropertyOrNew (ref puids);
|
||||
}
|
||||
|
||||
public int GetTrackNumber (Release release)
|
||||
{
|
||||
if (release == null) throw new ArgumentNullException ("release");
|
||||
|
||||
foreach (Release r in GetReleases ())
|
||||
if (r.Equals (release))
|
||||
return r.TrackNumber;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Static
|
||||
|
||||
public static Track Get (string id)
|
||||
{
|
||||
if (id == null) throw new ArgumentNullException ("id");
|
||||
return new Track (id);
|
||||
}
|
||||
|
||||
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 artist)
|
||||
{
|
||||
if (title == null) throw new ArgumentNullException ("title");
|
||||
if (artist == null) throw new ArgumentNullException ("artist");
|
||||
|
||||
TrackQueryParameters parameters = new TrackQueryParameters ();
|
||||
parameters.Title = title;
|
||||
parameters.Artist = artist;
|
||||
return Query (parameters);
|
||||
}
|
||||
|
||||
public static Query<Track> Query (string title, string artist, string release)
|
||||
{
|
||||
if (title == null) throw new ArgumentNullException ("title");
|
||||
if (artist == null) throw new ArgumentNullException ("artist");
|
||||
if (release == null) throw new ArgumentNullException ("release");
|
||||
|
||||
TrackQueryParameters parameters = new TrackQueryParameters ();
|
||||
parameters.Title = title;
|
||||
parameters.Artist = artist;
|
||||
parameters.Release = release;
|
||||
return Query (parameters);
|
||||
}
|
||||
|
||||
public static Query<Track> Query (TrackQueryParameters parameters)
|
||||
{
|
||||
if (parameters == null) throw new ArgumentNullException ("parameters");
|
||||
return new Query<Track> (EXTENSION, parameters.ToString ());
|
||||
}
|
||||
|
||||
public static Query<Track> QueryLucene (string luceneQuery)
|
||||
{
|
||||
if(luceneQuery == null) throw new ArgumentNullException ("luceneQuery");
|
||||
return new Query<Track> (EXTENSION, CreateLuceneParameter (luceneQuery));
|
||||
}
|
||||
|
||||
public static implicit operator string (Track track)
|
||||
{
|
||||
return track.ToString ();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
|
||||
#region Ancillary Types
|
||||
|
||||
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; }
|
||||
}
|
||||
|
||||
internal override void ToStringCore (StringBuilder builder)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
76
MusicBrainz/MusicBrainz/Utils.cs
Normal file
76
MusicBrainz/MusicBrainz/Utils.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
// Utils.cs
|
||||
//
|
||||
// Copyright (c) 2008 Scott Peterson <lunchtimemama@gmail.com>
|
||||
//
|
||||
// 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.Text;
|
||||
|
||||
namespace MusicBrainz
|
||||
{
|
||||
internal static class Utils
|
||||
{
|
||||
public static string EnumToString (Enum enumeration)
|
||||
{
|
||||
string str = enumeration.ToString ();
|
||||
StringBuilder builder = new StringBuilder (str.Length);
|
||||
EnumToString (builder, str);
|
||||
return builder.ToString ();
|
||||
}
|
||||
|
||||
public static void EnumToString (StringBuilder builder, string str)
|
||||
{
|
||||
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]);
|
||||
}
|
||||
}
|
||||
|
||||
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 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.AppendFormat ("{0:X}", b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
38
MusicBrainz/MusicBrainz/XmlRequestEventArgs.cs
Normal file
38
MusicBrainz/MusicBrainz/XmlRequestEventArgs.cs
Normal file
@@ -0,0 +1,38 @@
|
||||
// XmlRequestEventArgs.cs
|
||||
//
|
||||
// Copyright (c) 2008 Scott Peterson <lunchtimemama@gmail.com>
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace MusicBrainz
|
||||
{
|
||||
public sealed class XmlRequestEventArgs : EventArgs
|
||||
{
|
||||
public readonly Uri Uri;
|
||||
public readonly bool FromCache;
|
||||
|
||||
internal XmlRequestEventArgs (Uri uri, bool fromCache)
|
||||
{
|
||||
Uri = uri;
|
||||
FromCache = fromCache;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user