PageRenderTime 158ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/src/Libraries/MusicBrainz/MusicBrainz/Release.cs

https://github.com/dufoli/banshee
C# | 395 lines | 315 code | 57 blank | 23 comment | 50 complexity | dc738b9451d716ef1b30beb1ce5ae66c MD5 | raw file
  1. // Release.cs
  2. //
  3. // Copyright (c) 2008 Scott Peterson <lunchtimemama@gmail.com>
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. using System;
  23. using System.Collections.Generic;
  24. using System.Collections.ObjectModel;
  25. using System.Text;
  26. using System.Xml;
  27. namespace MusicBrainz
  28. {
  29. public sealed class Release : MusicBrainzItem
  30. {
  31. #region Private
  32. const string EXTENSION = "release";
  33. ReleaseType? type;
  34. ReleaseStatus? status;
  35. string language;
  36. string script;
  37. string asin;
  38. ReadOnlyCollection<Disc> discs;
  39. ReadOnlyCollection<Event> events;
  40. ReadOnlyCollection<Track> tracks;
  41. int? track_number;
  42. #endregion
  43. #region Constructors
  44. Release (string id) : base (id)
  45. {
  46. }
  47. internal Release (XmlReader reader) : base (reader, null, false)
  48. {
  49. }
  50. #endregion
  51. #region Protected
  52. internal override string UrlExtension {
  53. get { return EXTENSION; }
  54. }
  55. static readonly string [] track_params = new string [] { "tracks", "track-level-rels", "artist", "isrcs" };
  56. internal override void CreateIncCore (StringBuilder builder)
  57. {
  58. AppendIncParameters (builder, "release-events", "labels");
  59. if (discs == null) AppendIncParameters (builder, "discs");
  60. if (tracks == null) {
  61. AppendIncParameters (builder, track_params);
  62. AllRelsLoaded = false;
  63. }
  64. base.CreateIncCore (builder);
  65. }
  66. internal override void LoadMissingDataCore ()
  67. {
  68. Release release = new Release (Id);
  69. type = release.GetReleaseType ();
  70. status = release.GetReleaseStatus ();
  71. language = release.GetLanguage ();
  72. script = release.GetScript ();
  73. asin = release.GetAsin ();
  74. events = release.GetEvents ();
  75. if (discs == null) discs = release.GetDiscs ();
  76. if (tracks == null) tracks = release.GetTracks ();
  77. base.LoadMissingDataCore (release);
  78. }
  79. internal override void ProcessAttributes (XmlReader reader)
  80. {
  81. // How sure am I about getting the type and status in the "Type Status" format?
  82. // MB really ought to specify these two things seperatly.
  83. string type_string = reader ["type"];
  84. if (type_string != null) {
  85. foreach (string token in type_string.Split (' ')) {
  86. if (type == null) {
  87. type = Utils.StringToEnumOrNull<ReleaseType> (token);
  88. if (type != null) continue;
  89. }
  90. this.status = Utils.StringToEnumOrNull<ReleaseStatus> (token);
  91. }
  92. }
  93. }
  94. internal override void ProcessXmlCore (XmlReader reader)
  95. {
  96. switch (reader.Name) {
  97. case "text-representation":
  98. language = reader["language"];
  99. script = reader["script"];
  100. break;
  101. case "asin":
  102. asin = reader.ReadString ();
  103. break;
  104. case "disc-list":
  105. if (reader.ReadToDescendant ("disc")) {
  106. List<Disc> discs = new List<Disc> ();
  107. do discs.Add (new Disc (reader.ReadSubtree ()));
  108. while (reader.ReadToNextSibling ("disc"));
  109. this.discs = discs.AsReadOnly ();
  110. }
  111. break;
  112. case "release-event-list":
  113. if (!AllDataLoaded) {
  114. reader.Skip (); // FIXME this is a workaround for Mono bug 334752
  115. return;
  116. }
  117. if (reader.ReadToDescendant ("event")) {
  118. List<Event> events = new List<Event> ();
  119. do events.Add (new Event (reader.ReadSubtree ()));
  120. while (reader.ReadToNextSibling ("event"));
  121. this.events = events.AsReadOnly ();
  122. }
  123. break;
  124. case "track-list":
  125. string offset = reader["offset"];
  126. if (offset != null)
  127. track_number = int.Parse (offset) + 1;
  128. if (reader.ReadToDescendant ("track")) {
  129. List<Track> tracks = new List<Track> ();
  130. do tracks.Add (new Track (reader.ReadSubtree (), GetArtist (), AllDataLoaded));
  131. while (reader.ReadToNextSibling ("track"));
  132. this.tracks = tracks.AsReadOnly ();
  133. }
  134. break;
  135. default:
  136. base.ProcessXmlCore (reader);
  137. break;
  138. }
  139. }
  140. #endregion
  141. #region Public
  142. [Queryable ("reid")]
  143. public override string Id {
  144. get { return base.Id; }
  145. }
  146. [Queryable ("release")]
  147. public override string GetTitle ()
  148. {
  149. return base.GetTitle ();
  150. }
  151. [Queryable ("type")]
  152. public ReleaseType GetReleaseType ()
  153. {
  154. return GetPropertyOrDefault (ref type, ReleaseType.None);
  155. }
  156. [Queryable ("status")]
  157. public ReleaseStatus GetReleaseStatus ()
  158. {
  159. return GetPropertyOrDefault (ref status, ReleaseStatus.None);
  160. }
  161. public string GetLanguage ()
  162. {
  163. return GetPropertyOrNull (ref language);
  164. }
  165. [Queryable ("script")]
  166. public string GetScript ()
  167. {
  168. return GetPropertyOrNull (ref script);
  169. }
  170. [Queryable ("asin")]
  171. public string GetAsin ()
  172. {
  173. return GetPropertyOrNull (ref asin);
  174. }
  175. [QueryableMember("Count", "discids")]
  176. public ReadOnlyCollection<Disc> GetDiscs ()
  177. {
  178. return GetPropertyOrNew (ref discs);
  179. }
  180. public ReadOnlyCollection<Event> GetEvents ()
  181. {
  182. return GetPropertyOrNew (ref events);
  183. }
  184. [QueryableMember ("Count", "tracks")]
  185. public ReadOnlyCollection<Track> GetTracks ()
  186. {
  187. return GetPropertyOrNew (ref tracks);
  188. }
  189. internal int TrackNumber {
  190. get { return track_number ?? -1; }
  191. }
  192. #endregion
  193. #region Static
  194. public static Release Get (string id)
  195. {
  196. if (id == null) throw new ArgumentNullException ("id");
  197. return new Release (id);
  198. }
  199. public static Query<Release> Query (string title)
  200. {
  201. if (title == null) throw new ArgumentNullException ("title");
  202. ReleaseQueryParameters parameters = new ReleaseQueryParameters ();
  203. parameters.Title = title;
  204. return Query (parameters);
  205. }
  206. public static Query<Release> Query (string title, string artist)
  207. {
  208. if (title == null) throw new ArgumentNullException ("title");
  209. if (artist == null) throw new ArgumentNullException ("artist");
  210. ReleaseQueryParameters parameters = new ReleaseQueryParameters ();
  211. parameters.Title = title;
  212. parameters.Artist = artist;
  213. return Query (parameters);
  214. }
  215. public static Query<Release> Query (Disc disc)
  216. {
  217. if (disc == null) throw new ArgumentNullException ("disc");
  218. ReleaseQueryParameters parameters = new ReleaseQueryParameters ();
  219. parameters.DiscId = disc.Id;
  220. return Query (parameters);
  221. }
  222. public static Query<Release> Query (ReleaseQueryParameters parameters)
  223. {
  224. if (parameters == null) throw new ArgumentNullException ("parameters");
  225. return new Query<Release> (EXTENSION, parameters.ToString ());
  226. }
  227. public static Query<Release> QueryFromDevice(string device)
  228. {
  229. if (device == null) throw new ArgumentNullException ("device");
  230. ReleaseQueryParameters parameters = new ReleaseQueryParameters ();
  231. parameters.DiscId = LocalDisc.GetFromDevice (device).Id;
  232. return Query (parameters);
  233. }
  234. public static Query<Release> QueryLucene (string luceneQuery)
  235. {
  236. if (luceneQuery == null) throw new ArgumentNullException ("luceneQuery");
  237. return new Query<Release> (EXTENSION, CreateLuceneParameter (luceneQuery));
  238. }
  239. public static implicit operator string (Release release)
  240. {
  241. return release.ToString ();
  242. }
  243. #endregion
  244. }
  245. #region Ancillary Types
  246. public enum ReleaseType
  247. {
  248. None,
  249. Album,
  250. Single,
  251. EP,
  252. Compilation,
  253. Soundtrack,
  254. Spokenword,
  255. Interview,
  256. Audiobook,
  257. Live,
  258. Remix,
  259. Other
  260. }
  261. public enum ReleaseStatus
  262. {
  263. None,
  264. Official,
  265. Promotion,
  266. Bootleg,
  267. PsudoRelease
  268. }
  269. public enum ReleaseFormat
  270. {
  271. None,
  272. Cartridge,
  273. Cassette,
  274. CD,
  275. DAT,
  276. Digital,
  277. DualDisc,
  278. DVD,
  279. LaserDisc,
  280. MiniDisc,
  281. Other,
  282. ReelToReel,
  283. SACD,
  284. Vinyl
  285. }
  286. public sealed class ReleaseQueryParameters : ItemQueryParameters
  287. {
  288. string disc_id;
  289. public string DiscId {
  290. get { return disc_id; }
  291. set { disc_id = value; }
  292. }
  293. string date;
  294. public string Date {
  295. get { return date; }
  296. set { date = value; }
  297. }
  298. string asin;
  299. public string Asin {
  300. get { return asin; }
  301. set { asin = value; }
  302. }
  303. string language;
  304. public string Language {
  305. get { return language; }
  306. set { language = value; }
  307. }
  308. string script;
  309. public string Script {
  310. get { return script; }
  311. set { script = value; }
  312. }
  313. internal override void ToStringCore (StringBuilder builder)
  314. {
  315. if (disc_id != null) {
  316. builder.Append ("&discid=");
  317. builder.Append (disc_id);
  318. }
  319. if (date != null) {
  320. builder.Append ("&date=");
  321. Utils.PercentEncode (builder, date);
  322. }
  323. if (asin != null) {
  324. builder.Append ("&asin=");
  325. builder.Append (asin);
  326. }
  327. if (language != null) {
  328. builder.Append ("&lang=");
  329. builder.Append (language);
  330. }
  331. if (script != null) {
  332. builder.Append ("&script=");
  333. builder.Append (script);
  334. }
  335. }
  336. }
  337. #endregion
  338. }