1 /*
2  * Copyright 2022 XXIV
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 module audiodb;
17 
18 import std.stdio;
19 import std.string: strip;
20 import std.format: format;
21 import std.net.curl: byLineAsync, CurlException;
22 import std.uri: encode;
23 import std.json: JSONValue, parseJSON, JSONException, JSONType;
24 
25 struct Artist {
26     string idArtist;
27     string strArtist;
28     string strArtistStripped;
29     string strArtistAlternate;
30     string strLabel;
31     string idLabel;
32     string intFormedYear;
33     string intBornYear;
34     string intDiedYear;
35     string strDisbanded;
36     string strStyle;
37     string strGenre;
38     string strMood;
39     string strWebsite;
40     string strFacebook;
41     string strTwitter;
42     string strBiographyEN;
43     string strBiographyDE;
44     string strBiographyFR;
45     string strBiographyCN;
46     string strBiographyIT;
47     string strBiographyJP;
48     string strBiographyRU;
49     string strBiographyES;
50     string strBiographyPT;
51     string strBiographySE;
52     string strBiographyNL;
53     string strBiographyHU;
54     string strBiographyNO;
55     string strBiographyIL;
56     string strBiographyPL;
57     string strGender;
58     string intMembers;
59     string strCountry;
60     string strCountryCode;
61     string strArtistThumb;
62     string strArtistLogo;
63     string strArtistCutout;
64     string strArtistClearart;
65     string strArtistWideThumb;
66     string strArtistFanart;
67     string strArtistFanart2;
68     string strArtistFanart3;
69     string strArtistFanart4;
70     string strArtistBanner;
71     string strMusicBrainzID;
72     string strISNIcode;
73     string strLastFMChart;
74     string intCharted;
75     string strLocked;
76 }
77 
78 struct Discography
79 {
80     string strAlbum;
81     string intYearReleased;
82 }
83 
84 struct Album
85 {
86     string idAlbum;
87     string idArtist;
88     string idLabel;
89     string strAlbum;
90     string strAlbumStripped;
91     string strArtist;
92     string strArtistStripped;
93     string intYearReleased;
94     string strStyle;
95     string strGenre;
96     string strLabel;
97     string strReleaseFormat;
98     string intSales;
99     string strAlbumThumb;
100     string strAlbumThumbHQ;
101     string strAlbumThumbBack;
102     string strAlbumCDart;
103     string strAlbumSpine;
104     string strAlbum3DCase;
105     string strAlbum3DFlat;
106     string strAlbum3DFace;
107     string strAlbum3DThumb;
108     string strDescriptionEN;
109     string strDescriptionDE;
110     string strDescriptionFR;
111     string strDescriptionCN;
112     string strDescriptionIT;
113     string strDescriptionJP;
114     string strDescriptionRU;
115     string strDescriptionES;
116     string strDescriptionPT;
117     string strDescriptionSE;
118     string strDescriptionNL;
119     string strDescriptionHU;
120     string strDescriptionNO;
121     string strDescriptionIL;
122     string strDescriptionPL;
123     string intLoved;
124     string intScore;
125     string intScoreVotes;
126     string strReview;
127     string strMood;
128     string strTheme;
129     string strSpeed;
130     string strLocation;
131     string strMusicBrainzID;
132     string strMusicBrainzArtistID;
133     string strAllMusicID;
134     string strBBCReviewID;
135     string strRateYourMusicID;
136     string strDiscogsID;
137     string strWikidataID;
138     string strWikipediaID;
139     string strGeniusID;
140     string strLyricWikiID;
141     string strMusicMozID;
142     string strItunesID;
143     string strAmazonID;
144     string strLocked;
145 }
146 
147 struct Track
148 {
149     string idTrack;
150     string idAlbum;
151     string idArtist;
152     string idLyric;
153     string idIMVDB;
154     string strTrack;
155     string strAlbum;
156     string strArtist;
157     string strArtistAlternate;
158     string intCD;
159     string intDuration;
160     string strGenre;
161     string strMood;
162     string strStyle;
163     string strTheme;
164     string strDescriptionEN;
165     string strDescriptionDE;
166     string strDescriptionFR;
167     string strDescriptionCN;
168     string strDescriptionIT;
169     string strDescriptionJP;
170     string strDescriptionRU;
171     string strDescriptionES;
172     string strDescriptionPT;
173     string strDescriptionSE;
174     string strDescriptionNL;
175     string strDescriptionHU;
176     string strDescriptionNO;
177     string strDescriptionIL;
178     string strDescriptionPL;
179     string strTrackThumb;
180     string strTrack3DCase;
181     string strTrackLyrics;
182     string strMusicVid;
183     string strMusicVidDirector;
184     string strMusicVidCompany;
185     string strMusicVidScreen1;
186     string strMusicVidScreen2;
187     string strMusicVidScreen3;
188     string intMusicVidViews;
189     string intMusicVidLikes;
190     string intMusicVidDislikes;
191     string intMusicVidFavorites;
192     string intMusicVidComments;
193     string intTrackNumber;
194     string intLoved;
195     string intScore;
196     string intScoreVotes;
197     string intTotalListeners;
198     string intTotalPlays;
199     string strMusicBrainzID;
200     string strMusicBrainzAlbumID;
201     string strMusicBrainzArtistID;
202     string strLocked;
203 }
204 
205 struct MusicVideo
206 {
207     string idArtist;
208     string idAlbum;
209     string idTrack;
210     string strTrack;
211     string strTrackThumb;
212     string strMusicVid;
213     string strDescriptionEN;
214 }
215 
216 class AudioDBException : Exception
217 {
218     this(string msg, string file = __FILE__, size_t line = __LINE__)
219     {
220         super(msg, file, line);
221     }
222 }
223 
224 private string getRequest(string endpoint) {
225     auto response = byLineAsync(format("https://theaudiodb.com/api/v1/json/2/%s", endpoint));
226     string content = "";
227     foreach (line; response)
228         content ~= line;
229     return content;
230 }
231 
232 /** 
233  * Params:
234  *   s
235  * Returns: Artist details from artist name
236  * Throws: AudioDBException on failure
237  */
238 Artist searchArtist(string s) {
239     try
240     {
241         auto response = getRequest(format("search.php?s=%s", s.encode));
242         if (response.length == 0)
243         {
244             throw new Exception("no results found");
245         }
246         JSONValue json = parseJSON(response); 
247         if (json["artists"].type != JSONType.null_ && json["artists"].array.length != 0) {
248             Artist data = {
249                 json["artists"][0]["idArtist"].isNull() ? json["artists"][0]["idArtist"].toString : strip(json["artists"][0]["idArtist"].str).length == 0 ? "null" :json["artists"][0]["idArtist"].str,
250                 json["artists"][0]["strArtist"].isNull() ? json["artists"][0]["strArtist"].toString : strip(json["artists"][0]["strArtist"].str).length == 0 ? "null" :json["artists"][0]["strArtist"].str,
251                 json["artists"][0]["strArtistStripped"].isNull() ? json["artists"][0]["strArtistStripped"].toString : strip(json["artists"][0]["strArtistStripped"].str).length == 0 ? "null" :json["artists"][0]["strArtistStripped"].str,
252                 json["artists"][0]["strArtistAlternate"].isNull() ? json["artists"][0]["strArtistAlternate"].toString : strip(json["artists"][0]["strArtistAlternate"].str).length == 0 ? "null" :json["artists"][0]["strArtistAlternate"].str,
253                 json["artists"][0]["strLabel"].isNull() ? json["artists"][0]["strLabel"].toString : strip(json["artists"][0]["strLabel"].str).length == 0 ? "null" :json["artists"][0]["strLabel"].str,
254                 json["artists"][0]["idLabel"].isNull() ? json["artists"][0]["idLabel"].toString : strip(json["artists"][0]["idLabel"].str).length == 0 ? "null" :json["artists"][0]["idLabel"].str,
255                 json["artists"][0]["intFormedYear"].isNull() ? json["artists"][0]["intFormedYear"].toString : strip(json["artists"][0]["intFormedYear"].str).length == 0 ? "null" :json["artists"][0]["intFormedYear"].str,
256                 json["artists"][0]["intBornYear"].isNull() ? json["artists"][0]["intBornYear"].toString : strip(json["artists"][0]["intBornYear"].str).length == 0 ? "null" :json["artists"][0]["intBornYear"].str,
257                 json["artists"][0]["intDiedYear"].isNull() ? json["artists"][0]["intDiedYear"].toString : strip(json["artists"][0]["intDiedYear"].str).length == 0 ? "null" :json["artists"][0]["intDiedYear"].str,
258                 json["artists"][0]["strDisbanded"].isNull() ? json["artists"][0]["strDisbanded"].toString : strip(json["artists"][0]["strDisbanded"].str).length == 0 ? "null" :json["artists"][0]["strDisbanded"].str,
259                 json["artists"][0]["strStyle"].isNull() ? json["artists"][0]["strStyle"].toString : strip(json["artists"][0]["strStyle"].str).length == 0 ? "null" :json["artists"][0]["strStyle"].str,
260                 json["artists"][0]["strGenre"].isNull() ? json["artists"][0]["strGenre"].toString : strip(json["artists"][0]["strGenre"].str).length == 0 ? "null" :json["artists"][0]["strGenre"].str,
261                 json["artists"][0]["strMood"].isNull() ? json["artists"][0]["strMood"].toString : strip(json["artists"][0]["strMood"].str).length == 0 ? "null" :json["artists"][0]["strMood"].str,
262                 json["artists"][0]["strWebsite"].isNull() ? json["artists"][0]["strWebsite"].toString : strip(json["artists"][0]["strWebsite"].str).length == 0 ? "null" :json["artists"][0]["strWebsite"].str,
263                 json["artists"][0]["strFacebook"].isNull() ? json["artists"][0]["strFacebook"].toString : strip(json["artists"][0]["strFacebook"].str).length == 0 ? "null" :json["artists"][0]["strFacebook"].str,
264                 json["artists"][0]["strTwitter"].isNull() ? json["artists"][0]["strTwitter"].toString : strip(json["artists"][0]["strTwitter"].str).length == 0 ? "null" :json["artists"][0]["strTwitter"].str,
265                 json["artists"][0]["strBiographyEN"].isNull() ? json["artists"][0]["strBiographyEN"].toString : strip(json["artists"][0]["strBiographyEN"].str).length == 0 ? "null" :json["artists"][0]["strBiographyEN"].str,
266                 json["artists"][0]["strBiographyDE"].isNull() ? json["artists"][0]["strBiographyDE"].toString : strip(json["artists"][0]["strBiographyDE"].str).length == 0 ? "null" :json["artists"][0]["strBiographyDE"].str,
267                 json["artists"][0]["strBiographyFR"].isNull() ? json["artists"][0]["strBiographyFR"].toString : strip(json["artists"][0]["strBiographyFR"].str).length == 0 ? "null" :json["artists"][0]["strBiographyFR"].str,
268                 json["artists"][0]["strBiographyCN"].isNull() ? json["artists"][0]["strBiographyCN"].toString : strip(json["artists"][0]["strBiographyCN"].str).length == 0 ? "null" :json["artists"][0]["strBiographyCN"].str,
269                 json["artists"][0]["strBiographyIT"].isNull() ? json["artists"][0]["strBiographyIT"].toString : strip(json["artists"][0]["strBiographyIT"].str).length == 0 ? "null" :json["artists"][0]["strBiographyIT"].str,
270                 json["artists"][0]["strBiographyJP"].isNull() ? json["artists"][0]["strBiographyJP"].toString : strip(json["artists"][0]["strBiographyJP"].str).length == 0 ? "null" :json["artists"][0]["strBiographyJP"].str,
271                 json["artists"][0]["strBiographyRU"].isNull() ? json["artists"][0]["strBiographyRU"].toString : strip(json["artists"][0]["strBiographyRU"].str).length == 0 ? "null" :json["artists"][0]["strBiographyRU"].str,
272                 json["artists"][0]["strBiographyES"].isNull() ? json["artists"][0]["strBiographyES"].toString : strip(json["artists"][0]["strBiographyES"].str).length == 0 ? "null" :json["artists"][0]["strBiographyES"].str,
273                 json["artists"][0]["strBiographyPT"].isNull() ? json["artists"][0]["strBiographyPT"].toString : strip(json["artists"][0]["strBiographyPT"].str).length == 0 ? "null" :json["artists"][0]["strBiographyPT"].str,
274                 json["artists"][0]["strBiographySE"].isNull() ? json["artists"][0]["strBiographySE"].toString : strip(json["artists"][0]["strBiographySE"].str).length == 0 ? "null" :json["artists"][0]["strBiographySE"].str,
275                 json["artists"][0]["strBiographyNL"].isNull() ? json["artists"][0]["strBiographyNL"].toString : strip(json["artists"][0]["strBiographyNL"].str).length == 0 ? "null" :json["artists"][0]["strBiographyNL"].str,
276                 json["artists"][0]["strBiographyHU"].isNull() ? json["artists"][0]["strBiographyHU"].toString : strip(json["artists"][0]["strBiographyHU"].str).length == 0 ? "null" :json["artists"][0]["strBiographyHU"].str,
277                 json["artists"][0]["strBiographyNO"].isNull() ? json["artists"][0]["strBiographyNO"].toString : strip(json["artists"][0]["strBiographyNO"].str).length == 0 ? "null" :json["artists"][0]["strBiographyNO"].str,
278                 json["artists"][0]["strBiographyIL"].isNull() ? json["artists"][0]["strBiographyIL"].toString : strip(json["artists"][0]["strBiographyIL"].str).length == 0 ? "null" :json["artists"][0]["strBiographyIL"].str,
279                 json["artists"][0]["strBiographyPL"].isNull() ? json["artists"][0]["strBiographyPL"].toString : strip(json["artists"][0]["strBiographyPL"].str).length == 0 ? "null" :json["artists"][0]["strBiographyPL"].str,
280                 json["artists"][0]["strGender"].isNull() ? json["artists"][0]["strGender"].toString : strip(json["artists"][0]["strGender"].str).length == 0 ? "null" :json["artists"][0]["strGender"].str,
281                 json["artists"][0]["intMembers"].isNull() ? json["artists"][0]["intMembers"].toString : strip(json["artists"][0]["intMembers"].str).length == 0 ? "null" :json["artists"][0]["intMembers"].str,
282                 json["artists"][0]["strCountry"].isNull() ? json["artists"][0]["strCountry"].toString : strip(json["artists"][0]["strCountry"].str).length == 0 ? "null" :json["artists"][0]["strCountry"].str,
283                 json["artists"][0]["strCountryCode"].isNull() ? json["artists"][0]["strCountryCode"].toString : strip(json["artists"][0]["strCountryCode"].str).length == 0 ? "null" :json["artists"][0]["strCountryCode"].str,
284                 json["artists"][0]["strArtistThumb"].isNull() ? json["artists"][0]["strArtistThumb"].toString : strip(json["artists"][0]["strArtistThumb"].str).length == 0 ? "null" :json["artists"][0]["strArtistThumb"].str,
285                 json["artists"][0]["strArtistLogo"].isNull() ? json["artists"][0]["strArtistLogo"].toString : strip(json["artists"][0]["strArtistLogo"].str).length == 0 ? "null" :json["artists"][0]["strArtistLogo"].str,
286                 json["artists"][0]["strArtistCutout"].isNull() ? json["artists"][0]["strArtistCutout"].toString : strip(json["artists"][0]["strArtistCutout"].str).length == 0 ? "null" :json["artists"][0]["strArtistCutout"].str,
287                 json["artists"][0]["strArtistClearart"].isNull() ? json["artists"][0]["strArtistClearart"].toString : strip(json["artists"][0]["strArtistClearart"].str).length == 0 ? "null" :json["artists"][0]["strArtistClearart"].str,
288                 json["artists"][0]["strArtistWideThumb"].isNull() ? json["artists"][0]["strArtistWideThumb"].toString : strip(json["artists"][0]["strArtistWideThumb"].str).length == 0 ? "null" :json["artists"][0]["strArtistWideThumb"].str,
289                 json["artists"][0]["strArtistFanart"].isNull() ? json["artists"][0]["strArtistFanart"].toString : strip(json["artists"][0]["strArtistFanart"].str).length == 0 ? "null" :json["artists"][0]["strArtistFanart"].str,
290                 json["artists"][0]["strArtistFanart2"].isNull() ? json["artists"][0]["strArtistFanart2"].toString : strip(json["artists"][0]["strArtistFanart2"].str).length == 0 ? "null" :json["artists"][0]["strArtistFanart2"].str,
291                 json["artists"][0]["strArtistFanart3"].isNull() ? json["artists"][0]["strArtistFanart3"].toString : strip(json["artists"][0]["strArtistFanart3"].str).length == 0 ? "null" :json["artists"][0]["strArtistFanart3"].str,
292                 json["artists"][0]["strArtistFanart4"].isNull() ? json["artists"][0]["strArtistFanart4"].toString : strip(json["artists"][0]["strArtistFanart4"].str).length == 0 ? "null" :json["artists"][0]["strArtistFanart4"].str,
293                 json["artists"][0]["strArtistBanner"].isNull() ? json["artists"][0]["strArtistBanner"].toString : strip(json["artists"][0]["strArtistBanner"].str).length == 0 ? "null" :json["artists"][0]["strArtistBanner"].str,
294                 json["artists"][0]["strMusicBrainzID"].isNull() ? json["artists"][0]["strMusicBrainzID"].toString : strip(json["artists"][0]["strMusicBrainzID"].str).length == 0 ? "null" :json["artists"][0]["strMusicBrainzID"].str,
295                 json["artists"][0]["strISNIcode"].isNull() ? json["artists"][0]["strISNIcode"].toString : strip(json["artists"][0]["strISNIcode"].str).length == 0 ? "null" :json["artists"][0]["strISNIcode"].str,
296                 json["artists"][0]["strLastFMChart"].isNull() ? json["artists"][0]["strLastFMChart"].toString : strip(json["artists"][0]["strLastFMChart"].str).length == 0 ? "null" :json["artists"][0]["strLastFMChart"].str,
297                 json["artists"][0]["intCharted"].isNull() ? json["artists"][0]["intCharted"].toString : strip(json["artists"][0]["intCharted"].str).length == 0 ? "null" :json["artists"][0]["intCharted"].str,
298                 json["artists"][0]["strLocked"].isNull() ? json["artists"][0]["strLocked"].toString : strip(json["artists"][0]["strLocked"].str).length == 0 ? "null" :json["artists"][0]["strLocked"].str,
299             };
300             return data;
301         }
302         throw new Exception("no results found");
303     }
304     catch(CurlException ex)
305     {
306         throw new AudioDBException(ex.msg);
307     }
308     catch(JSONException ex)
309     {
310         throw new AudioDBException(format("Something went wrong while parsing json: %s", ex.msg));
311     }
312     catch(Exception ex)
313     {
314         throw new AudioDBException(ex.msg);
315     }
316 }
317 
318 /** 
319  * Params:
320  *   s
321  * Returns: Discography for an Artist with Album names and year only
322  * Throws: AudioDBException on failure
323  */
324 Discography[] discography(string s) {
325     try
326     {
327         auto response = getRequest(format("discography.php?s=%s", s.encode));
328         if (response.length == 0)
329         {
330             throw new Exception("no results found");
331         }
332         JSONValue json = parseJSON(response); 
333         if (json["album"].type != JSONType.null_ && json["album"].array.length != 0) {
334             Discography[] array = [];
335             foreach(ref i; json["album"].array)
336             {
337                 Discography data = {
338                     i["strAlbum"].isNull() ? i["strAlbum"].toString : strip(i["strAlbum"].str).length == 0 ? "null" :i["strAlbum"].str,
339                     i["intYearReleased"].isNull() ? i["intYearReleased"].toString : strip(i["intYearReleased"].str).length == 0 ? "null" :i["intYearReleased"].str,
340                 };
341                 array ~= data;
342             }
343             return array;
344         }
345         throw new Exception("no results found");
346     }
347     catch(CurlException ex)
348     {
349         throw new AudioDBException(ex.msg);
350     }
351     catch(JSONException ex)
352     {
353         throw new AudioDBException(format("Something went wrong while parsing json: %s", ex.msg));
354     }
355     catch(Exception ex)
356     {
357         throw new AudioDBException(ex.msg);
358     }
359 }
360 
361 /** 
362  * Params:
363  *   l
364  * Returns: individual Artist details using known Artist ID
365  * Throws: AudioDBException on failure
366  */
367 Artist searchArtistById(long l) {
368     try
369     {
370         auto response = getRequest(format("artist.php?i=%d", l));
371         if (response.length == 0)
372         {
373             throw new Exception("no results found");
374         }
375         JSONValue json = parseJSON(response); 
376         if (json["artists"].type != JSONType.null_ && json["artists"].array.length != 0) {
377             Artist data = {
378                 json["artists"][0]["idArtist"].isNull() ? json["artists"][0]["idArtist"].toString : strip(json["artists"][0]["idArtist"].str).length == 0 ? "null" :json["artists"][0]["idArtist"].str,
379                 json["artists"][0]["strArtist"].isNull() ? json["artists"][0]["strArtist"].toString : strip(json["artists"][0]["strArtist"].str).length == 0 ? "null" :json["artists"][0]["strArtist"].str,
380                 json["artists"][0]["strArtistStripped"].isNull() ? json["artists"][0]["strArtistStripped"].toString : strip(json["artists"][0]["strArtistStripped"].str).length == 0 ? "null" :json["artists"][0]["strArtistStripped"].str,
381                 json["artists"][0]["strArtistAlternate"].isNull() ? json["artists"][0]["strArtistAlternate"].toString : strip(json["artists"][0]["strArtistAlternate"].str).length == 0 ? "null" :json["artists"][0]["strArtistAlternate"].str,
382                 json["artists"][0]["strLabel"].isNull() ? json["artists"][0]["strLabel"].toString : strip(json["artists"][0]["strLabel"].str).length == 0 ? "null" :json["artists"][0]["strLabel"].str,
383                 json["artists"][0]["idLabel"].isNull() ? json["artists"][0]["idLabel"].toString : strip(json["artists"][0]["idLabel"].str).length == 0 ? "null" :json["artists"][0]["idLabel"].str,
384                 json["artists"][0]["intFormedYear"].isNull() ? json["artists"][0]["intFormedYear"].toString : strip(json["artists"][0]["intFormedYear"].str).length == 0 ? "null" :json["artists"][0]["intFormedYear"].str,
385                 json["artists"][0]["intBornYear"].isNull() ? json["artists"][0]["intBornYear"].toString : strip(json["artists"][0]["intBornYear"].str).length == 0 ? "null" :json["artists"][0]["intBornYear"].str,
386                 json["artists"][0]["intDiedYear"].isNull() ? json["artists"][0]["intDiedYear"].toString : strip(json["artists"][0]["intDiedYear"].str).length == 0 ? "null" :json["artists"][0]["intDiedYear"].str,
387                 json["artists"][0]["strDisbanded"].isNull() ? json["artists"][0]["strDisbanded"].toString : strip(json["artists"][0]["strDisbanded"].str).length == 0 ? "null" :json["artists"][0]["strDisbanded"].str,
388                 json["artists"][0]["strStyle"].isNull() ? json["artists"][0]["strStyle"].toString : strip(json["artists"][0]["strStyle"].str).length == 0 ? "null" :json["artists"][0]["strStyle"].str,
389                 json["artists"][0]["strGenre"].isNull() ? json["artists"][0]["strGenre"].toString : strip(json["artists"][0]["strGenre"].str).length == 0 ? "null" :json["artists"][0]["strGenre"].str,
390                 json["artists"][0]["strMood"].isNull() ? json["artists"][0]["strMood"].toString : strip(json["artists"][0]["strMood"].str).length == 0 ? "null" :json["artists"][0]["strMood"].str,
391                 json["artists"][0]["strWebsite"].isNull() ? json["artists"][0]["strWebsite"].toString : strip(json["artists"][0]["strWebsite"].str).length == 0 ? "null" :json["artists"][0]["strWebsite"].str,
392                 json["artists"][0]["strFacebook"].isNull() ? json["artists"][0]["strFacebook"].toString : strip(json["artists"][0]["strFacebook"].str).length == 0 ? "null" :json["artists"][0]["strFacebook"].str,
393                 json["artists"][0]["strTwitter"].isNull() ? json["artists"][0]["strTwitter"].toString : strip(json["artists"][0]["strTwitter"].str).length == 0 ? "null" :json["artists"][0]["strTwitter"].str,
394                 json["artists"][0]["strBiographyEN"].isNull() ? json["artists"][0]["strBiographyEN"].toString : strip(json["artists"][0]["strBiographyEN"].str).length == 0 ? "null" :json["artists"][0]["strBiographyEN"].str,
395                 json["artists"][0]["strBiographyDE"].isNull() ? json["artists"][0]["strBiographyDE"].toString : strip(json["artists"][0]["strBiographyDE"].str).length == 0 ? "null" :json["artists"][0]["strBiographyDE"].str,
396                 json["artists"][0]["strBiographyFR"].isNull() ? json["artists"][0]["strBiographyFR"].toString : strip(json["artists"][0]["strBiographyFR"].str).length == 0 ? "null" :json["artists"][0]["strBiographyFR"].str,
397                 json["artists"][0]["strBiographyCN"].isNull() ? json["artists"][0]["strBiographyCN"].toString : strip(json["artists"][0]["strBiographyCN"].str).length == 0 ? "null" :json["artists"][0]["strBiographyCN"].str,
398                 json["artists"][0]["strBiographyIT"].isNull() ? json["artists"][0]["strBiographyIT"].toString : strip(json["artists"][0]["strBiographyIT"].str).length == 0 ? "null" :json["artists"][0]["strBiographyIT"].str,
399                 json["artists"][0]["strBiographyJP"].isNull() ? json["artists"][0]["strBiographyJP"].toString : strip(json["artists"][0]["strBiographyJP"].str).length == 0 ? "null" :json["artists"][0]["strBiographyJP"].str,
400                 json["artists"][0]["strBiographyRU"].isNull() ? json["artists"][0]["strBiographyRU"].toString : strip(json["artists"][0]["strBiographyRU"].str).length == 0 ? "null" :json["artists"][0]["strBiographyRU"].str,
401                 json["artists"][0]["strBiographyES"].isNull() ? json["artists"][0]["strBiographyES"].toString : strip(json["artists"][0]["strBiographyES"].str).length == 0 ? "null" :json["artists"][0]["strBiographyES"].str,
402                 json["artists"][0]["strBiographyPT"].isNull() ? json["artists"][0]["strBiographyPT"].toString : strip(json["artists"][0]["strBiographyPT"].str).length == 0 ? "null" :json["artists"][0]["strBiographyPT"].str,
403                 json["artists"][0]["strBiographySE"].isNull() ? json["artists"][0]["strBiographySE"].toString : strip(json["artists"][0]["strBiographySE"].str).length == 0 ? "null" :json["artists"][0]["strBiographySE"].str,
404                 json["artists"][0]["strBiographyNL"].isNull() ? json["artists"][0]["strBiographyNL"].toString : strip(json["artists"][0]["strBiographyNL"].str).length == 0 ? "null" :json["artists"][0]["strBiographyNL"].str,
405                 json["artists"][0]["strBiographyHU"].isNull() ? json["artists"][0]["strBiographyHU"].toString : strip(json["artists"][0]["strBiographyHU"].str).length == 0 ? "null" :json["artists"][0]["strBiographyHU"].str,
406                 json["artists"][0]["strBiographyNO"].isNull() ? json["artists"][0]["strBiographyNO"].toString : strip(json["artists"][0]["strBiographyNO"].str).length == 0 ? "null" :json["artists"][0]["strBiographyNO"].str,
407                 json["artists"][0]["strBiographyIL"].isNull() ? json["artists"][0]["strBiographyIL"].toString : strip(json["artists"][0]["strBiographyIL"].str).length == 0 ? "null" :json["artists"][0]["strBiographyIL"].str,
408                 json["artists"][0]["strBiographyPL"].isNull() ? json["artists"][0]["strBiographyPL"].toString : strip(json["artists"][0]["strBiographyPL"].str).length == 0 ? "null" :json["artists"][0]["strBiographyPL"].str,
409                 json["artists"][0]["strGender"].isNull() ? json["artists"][0]["strGender"].toString : strip(json["artists"][0]["strGender"].str).length == 0 ? "null" :json["artists"][0]["strGender"].str,
410                 json["artists"][0]["intMembers"].isNull() ? json["artists"][0]["intMembers"].toString : strip(json["artists"][0]["intMembers"].str).length == 0 ? "null" :json["artists"][0]["intMembers"].str,
411                 json["artists"][0]["strCountry"].isNull() ? json["artists"][0]["strCountry"].toString : strip(json["artists"][0]["strCountry"].str).length == 0 ? "null" :json["artists"][0]["strCountry"].str,
412                 json["artists"][0]["strCountryCode"].isNull() ? json["artists"][0]["strCountryCode"].toString : strip(json["artists"][0]["strCountryCode"].str).length == 0 ? "null" :json["artists"][0]["strCountryCode"].str,
413                 json["artists"][0]["strArtistThumb"].isNull() ? json["artists"][0]["strArtistThumb"].toString : strip(json["artists"][0]["strArtistThumb"].str).length == 0 ? "null" :json["artists"][0]["strArtistThumb"].str,
414                 json["artists"][0]["strArtistLogo"].isNull() ? json["artists"][0]["strArtistLogo"].toString : strip(json["artists"][0]["strArtistLogo"].str).length == 0 ? "null" :json["artists"][0]["strArtistLogo"].str,
415                 json["artists"][0]["strArtistCutout"].isNull() ? json["artists"][0]["strArtistCutout"].toString : strip(json["artists"][0]["strArtistCutout"].str).length == 0 ? "null" :json["artists"][0]["strArtistCutout"].str,
416                 json["artists"][0]["strArtistClearart"].isNull() ? json["artists"][0]["strArtistClearart"].toString : strip(json["artists"][0]["strArtistClearart"].str).length == 0 ? "null" :json["artists"][0]["strArtistClearart"].str,
417                 json["artists"][0]["strArtistWideThumb"].isNull() ? json["artists"][0]["strArtistWideThumb"].toString : strip(json["artists"][0]["strArtistWideThumb"].str).length == 0 ? "null" :json["artists"][0]["strArtistWideThumb"].str,
418                 json["artists"][0]["strArtistFanart"].isNull() ? json["artists"][0]["strArtistFanart"].toString : strip(json["artists"][0]["strArtistFanart"].str).length == 0 ? "null" :json["artists"][0]["strArtistFanart"].str,
419                 json["artists"][0]["strArtistFanart2"].isNull() ? json["artists"][0]["strArtistFanart2"].toString : strip(json["artists"][0]["strArtistFanart2"].str).length == 0 ? "null" :json["artists"][0]["strArtistFanart2"].str,
420                 json["artists"][0]["strArtistFanart3"].isNull() ? json["artists"][0]["strArtistFanart3"].toString : strip(json["artists"][0]["strArtistFanart3"].str).length == 0 ? "null" :json["artists"][0]["strArtistFanart3"].str,
421                 json["artists"][0]["strArtistFanart4"].isNull() ? json["artists"][0]["strArtistFanart4"].toString : strip(json["artists"][0]["strArtistFanart4"].str).length == 0 ? "null" :json["artists"][0]["strArtistFanart4"].str,
422                 json["artists"][0]["strArtistBanner"].isNull() ? json["artists"][0]["strArtistBanner"].toString : strip(json["artists"][0]["strArtistBanner"].str).length == 0 ? "null" :json["artists"][0]["strArtistBanner"].str,
423                 json["artists"][0]["strMusicBrainzID"].isNull() ? json["artists"][0]["strMusicBrainzID"].toString : strip(json["artists"][0]["strMusicBrainzID"].str).length == 0 ? "null" :json["artists"][0]["strMusicBrainzID"].str,
424                 json["artists"][0]["strISNIcode"].isNull() ? json["artists"][0]["strISNIcode"].toString : strip(json["artists"][0]["strISNIcode"].str).length == 0 ? "null" :json["artists"][0]["strISNIcode"].str,
425                 json["artists"][0]["strLastFMChart"].isNull() ? json["artists"][0]["strLastFMChart"].toString : strip(json["artists"][0]["strLastFMChart"].str).length == 0 ? "null" :json["artists"][0]["strLastFMChart"].str,
426                 json["artists"][0]["intCharted"].isNull() ? json["artists"][0]["intCharted"].toString : strip(json["artists"][0]["intCharted"].str).length == 0 ? "null" :json["artists"][0]["intCharted"].str,
427                 json["artists"][0]["strLocked"].isNull() ? json["artists"][0]["strLocked"].toString : strip(json["artists"][0]["strLocked"].str).length == 0 ? "null" :json["artists"][0]["strLocked"].str,
428             };
429             return data;
430         }
431         throw new Exception("no results found");
432     }
433     catch(CurlException ex)
434     {
435         throw new AudioDBException(ex.msg);
436     }
437     catch(JSONException ex)
438     {
439         throw new AudioDBException(format("Something went wrong while parsing json: %s", ex.msg));
440     }
441     catch(Exception ex)
442     {
443         throw new AudioDBException(ex.msg);
444     }
445 }
446 
447 /** 
448  * Params:
449  *   l
450  * Returns: individual Album info using known Album ID
451  * Throws: AudioDBException on failure
452  */
453 Album searchAlbumById(long l) {
454     try
455     {
456         auto response = getRequest(format("album.php?m=%d", l));
457         if (response.length == 0)
458         {
459             throw new Exception("no results found");
460         }
461         JSONValue json = parseJSON(response); 
462         if (json["album"].type != JSONType.null_ && json["album"].array.length != 0) {
463             Album data = {
464                 json["album"][0]["idAlbum"].isNull() ? json["album"][0]["idAlbum"].toString : strip(json["album"][0]["idAlbum"].str).length == 0 ? "null" :json["album"][0]["idAlbum"].str,
465                 json["album"][0]["idArtist"].isNull() ? json["album"][0]["idArtist"].toString : strip(json["album"][0]["idArtist"].str).length == 0 ? "null" :json["album"][0]["idArtist"].str,
466                 json["album"][0]["idLabel"].isNull() ? json["album"][0]["idLabel"].toString : strip(json["album"][0]["idLabel"].str).length == 0 ? "null" :json["album"][0]["idLabel"].str,
467                 json["album"][0]["strAlbum"].isNull() ? json["album"][0]["strAlbum"].toString : strip(json["album"][0]["strAlbum"].str).length == 0 ? "null" :json["album"][0]["strAlbum"].str,
468                 json["album"][0]["strAlbumStripped"].isNull() ? json["album"][0]["strAlbumStripped"].toString : strip(json["album"][0]["strAlbumStripped"].str).length == 0 ? "null" :json["album"][0]["strAlbumStripped"].str,
469                 json["album"][0]["strArtist"].isNull() ? json["album"][0]["strArtist"].toString : strip(json["album"][0]["strArtist"].str).length == 0 ? "null" :json["album"][0]["strArtist"].str,
470                 json["album"][0]["strArtistStripped"].isNull() ? json["album"][0]["strArtistStripped"].toString : strip(json["album"][0]["strArtistStripped"].str).length == 0 ? "null" :json["album"][0]["strArtistStripped"].str,
471                 json["album"][0]["intYearReleased"].isNull() ? json["album"][0]["intYearReleased"].toString : strip(json["album"][0]["intYearReleased"].str).length == 0 ? "null" :json["album"][0]["intYearReleased"].str,
472                 json["album"][0]["strStyle"].isNull() ? json["album"][0]["strStyle"].toString : strip(json["album"][0]["strStyle"].str).length == 0 ? "null" :json["album"][0]["strStyle"].str,
473                 json["album"][0]["strGenre"].isNull() ? json["album"][0]["strGenre"].toString : strip(json["album"][0]["strGenre"].str).length == 0 ? "null" :json["album"][0]["strGenre"].str,
474                 json["album"][0]["strLabel"].isNull() ? json["album"][0]["strLabel"].toString : strip(json["album"][0]["strLabel"].str).length == 0 ? "null" :json["album"][0]["strLabel"].str,
475                 json["album"][0]["strReleaseFormat"].isNull() ? json["album"][0]["strReleaseFormat"].toString : strip(json["album"][0]["strReleaseFormat"].str).length == 0 ? "null" :json["album"][0]["strReleaseFormat"].str,
476                 json["album"][0]["intSales"].isNull() ? json["album"][0]["intSales"].toString : strip(json["album"][0]["intSales"].str).length == 0 ? "null" :json["album"][0]["intSales"].str,
477                 json["album"][0]["strAlbumThumb"].isNull() ? json["album"][0]["strAlbumThumb"].toString : strip(json["album"][0]["strAlbumThumb"].str).length == 0 ? "null" :json["album"][0]["strAlbumThumb"].str,
478                 json["album"][0]["strAlbumThumbHQ"].isNull() ? json["album"][0]["strAlbumThumbHQ"].toString : strip(json["album"][0]["strAlbumThumbHQ"].str).length == 0 ? "null" :json["album"][0]["strAlbumThumbHQ"].str,
479                 json["album"][0]["strAlbumThumbBack"].isNull() ? json["album"][0]["strAlbumThumbBack"].toString : strip(json["album"][0]["strAlbumThumbBack"].str).length == 0 ? "null" :json["album"][0]["strAlbumThumbBack"].str,
480                 json["album"][0]["strAlbumCDart"].isNull() ? json["album"][0]["strAlbumCDart"].toString : strip(json["album"][0]["strAlbumCDart"].str).length == 0 ? "null" :json["album"][0]["strAlbumCDart"].str,
481                 json["album"][0]["strAlbumSpine"].isNull() ? json["album"][0]["strAlbumSpine"].toString : strip(json["album"][0]["strAlbumSpine"].str).length == 0 ? "null" :json["album"][0]["strAlbumSpine"].str,
482                 json["album"][0]["strAlbum3DCase"].isNull() ? json["album"][0]["strAlbum3DCase"].toString : strip(json["album"][0]["strAlbum3DCase"].str).length == 0 ? "null" :json["album"][0]["strAlbum3DCase"].str,
483                 json["album"][0]["strAlbum3DFlat"].isNull() ? json["album"][0]["strAlbum3DFlat"].toString : strip(json["album"][0]["strAlbum3DFlat"].str).length == 0 ? "null" :json["album"][0]["strAlbum3DFlat"].str,
484                 json["album"][0]["strAlbum3DFace"].isNull() ? json["album"][0]["strAlbum3DFace"].toString : strip(json["album"][0]["strAlbum3DFace"].str).length == 0 ? "null" :json["album"][0]["strAlbum3DFace"].str,
485                 json["album"][0]["strAlbum3DThumb"].isNull() ? json["album"][0]["strAlbum3DThumb"].toString : strip(json["album"][0]["strAlbum3DThumb"].str).length == 0 ? "null" :json["album"][0]["strAlbum3DThumb"].str,
486                 json["album"][0]["strDescriptionDE"].isNull() ? json["album"][0]["strDescriptionDE"].toString : strip(json["album"][0]["strDescriptionDE"].str).length == 0 ? "null" :json["album"][0]["strDescriptionDE"].str,
487                 json["album"][0]["strDescriptionFR"].isNull() ? json["album"][0]["strDescriptionFR"].toString : strip(json["album"][0]["strDescriptionFR"].str).length == 0 ? "null" :json["album"][0]["strDescriptionFR"].str,
488                 json["album"][0]["strDescriptionCN"].isNull() ? json["album"][0]["strDescriptionCN"].toString : strip(json["album"][0]["strDescriptionCN"].str).length == 0 ? "null" :json["album"][0]["strDescriptionCN"].str,
489                 json["album"][0]["strDescriptionIT"].isNull() ? json["album"][0]["strDescriptionIT"].toString : strip(json["album"][0]["strDescriptionIT"].str).length == 0 ? "null" :json["album"][0]["strDescriptionIT"].str,
490                 json["album"][0]["strDescriptionJP"].isNull() ? json["album"][0]["strDescriptionJP"].toString : strip(json["album"][0]["strDescriptionJP"].str).length == 0 ? "null" :json["album"][0]["strDescriptionJP"].str,
491                 json["album"][0]["strDescriptionRU"].isNull() ? json["album"][0]["strDescriptionRU"].toString : strip(json["album"][0]["strDescriptionRU"].str).length == 0 ? "null" :json["album"][0]["strDescriptionRU"].str,
492                 json["album"][0]["strDescriptionES"].isNull() ? json["album"][0]["strDescriptionES"].toString : strip(json["album"][0]["strDescriptionES"].str).length == 0 ? "null" :json["album"][0]["strDescriptionES"].str,
493                 json["album"][0]["strDescriptionPT"].isNull() ? json["album"][0]["strDescriptionPT"].toString : strip(json["album"][0]["strDescriptionPT"].str).length == 0 ? "null" :json["album"][0]["strDescriptionPT"].str,
494                 json["album"][0]["strDescriptionSE"].isNull() ? json["album"][0]["strDescriptionSE"].toString : strip(json["album"][0]["strDescriptionSE"].str).length == 0 ? "null" :json["album"][0]["strDescriptionSE"].str,
495                 json["album"][0]["strDescriptionNL"].isNull() ? json["album"][0]["strDescriptionNL"].toString : strip(json["album"][0]["strDescriptionNL"].str).length == 0 ? "null" :json["album"][0]["strDescriptionNL"].str,
496                 json["album"][0]["strDescriptionHU"].isNull() ? json["album"][0]["strDescriptionHU"].toString : strip(json["album"][0]["strDescriptionHU"].str).length == 0 ? "null" :json["album"][0]["strDescriptionHU"].str,
497                 json["album"][0]["strDescriptionNO"].isNull() ? json["album"][0]["strDescriptionNO"].toString : strip(json["album"][0]["strDescriptionNO"].str).length == 0 ? "null" :json["album"][0]["strDescriptionNO"].str,
498                 json["album"][0]["strDescriptionIL"].isNull() ? json["album"][0]["strDescriptionIL"].toString : strip(json["album"][0]["strDescriptionIL"].str).length == 0 ? "null" :json["album"][0]["strDescriptionIL"].str,
499                 json["album"][0]["strDescriptionPL"].isNull() ? json["album"][0]["strDescriptionPL"].toString : strip(json["album"][0]["strDescriptionPL"].str).length == 0 ? "null" :json["album"][0]["strDescriptionPL"].str,
500                 json["album"][0]["intLoved"].isNull() ? json["album"][0]["intLoved"].toString : strip(json["album"][0]["intLoved"].str).length == 0 ? "null" :json["album"][0]["intLoved"].str,
501                 json["album"][0]["intScore"].isNull() ? json["album"][0]["intScore"].toString : strip(json["album"][0]["intScore"].str).length == 0 ? "null" :json["album"][0]["intScore"].str,
502                 json["album"][0]["intScoreVotes"].isNull() ? json["album"][0]["intScoreVotes"].toString : strip(json["album"][0]["intScoreVotes"].str).length == 0 ? "null" :json["album"][0]["intScoreVotes"].str,
503                 json["album"][0]["strReview"].isNull() ? json["album"][0]["strReview"].toString : strip(json["album"][0]["strReview"].str).length == 0 ? "null" :json["album"][0]["strReview"].str,
504                 json["album"][0]["strMood"].isNull() ? json["album"][0]["strMood"].toString : strip(json["album"][0]["strMood"].str).length == 0 ? "null" :json["album"][0]["strMood"].str,
505                 json["album"][0]["strTheme"].isNull() ? json["album"][0]["strTheme"].toString : strip(json["album"][0]["strTheme"].str).length == 0 ? "null" :json["album"][0]["strTheme"].str,
506                 json["album"][0]["strSpeed"].isNull() ? json["album"][0]["strSpeed"].toString : strip(json["album"][0]["strSpeed"].str).length == 0 ? "null" :json["album"][0]["strSpeed"].str,
507                 json["album"][0]["strLocation"].isNull() ? json["album"][0]["strLocation"].toString : strip(json["album"][0]["strLocation"].str).length == 0 ? "null" :json["album"][0]["strLocation"].str,
508                 json["album"][0]["strMusicBrainzID"].isNull() ? json["album"][0]["strMusicBrainzID"].toString : strip(json["album"][0]["strMusicBrainzID"].str).length == 0 ? "null" :json["album"][0]["strMusicBrainzID"].str,
509                 json["album"][0]["strMusicBrainzArtistID"].isNull() ? json["album"][0]["strMusicBrainzArtistID"].toString : strip(json["album"][0]["strMusicBrainzArtistID"].str).length == 0 ? "null" :json["album"][0]["strMusicBrainzArtistID"].str,
510                 json["album"][0]["strAllMusicID"].isNull() ? json["album"][0]["strAllMusicID"].toString : strip(json["album"][0]["strAllMusicID"].str).length == 0 ? "null" :json["album"][0]["strAllMusicID"].str,
511                 json["album"][0]["strBBCReviewID"].isNull() ? json["album"][0]["strBBCReviewID"].toString : strip(json["album"][0]["strBBCReviewID"].str).length == 0 ? "null" :json["album"][0]["strBBCReviewID"].str,
512                 json["album"][0]["strRateYourMusicID"].isNull() ? json["album"][0]["strRateYourMusicID"].toString : strip(json["album"][0]["strRateYourMusicID"].str).length == 0 ? "null" :json["album"][0]["strRateYourMusicID"].str,
513                 json["album"][0]["strDiscogsID"].isNull() ? json["album"][0]["strDiscogsID"].toString : strip(json["album"][0]["strDiscogsID"].str).length == 0 ? "null" :json["album"][0]["strDiscogsID"].str,
514                 json["album"][0]["strWikidataID"].isNull() ? json["album"][0]["strWikidataID"].toString : strip(json["album"][0]["strWikidataID"].str).length == 0 ? "null" :json["album"][0]["strWikidataID"].str,
515                 json["album"][0]["strWikipediaID"].isNull() ? json["album"][0]["strWikipediaID"].toString : strip(json["album"][0]["strWikipediaID"].str).length == 0 ? "null" :json["album"][0]["strWikipediaID"].str,
516                 json["album"][0]["strGeniusID"].isNull() ? json["album"][0]["strGeniusID"].toString : strip(json["album"][0]["strGeniusID"].str).length == 0 ? "null" :json["album"][0]["strGeniusID"].str,
517                 json["album"][0]["strLyricWikiID"].isNull() ? json["album"][0]["strLyricWikiID"].toString : strip(json["album"][0]["strLyricWikiID"].str).length == 0 ? "null" :json["album"][0]["strLyricWikiID"].str,
518                 json["album"][0]["strMusicMozID"].isNull() ? json["album"][0]["strMusicMozID"].toString : strip(json["album"][0]["strMusicMozID"].str).length == 0 ? "null" :json["album"][0]["strMusicMozID"].str,
519                 json["album"][0]["strItunesID"].isNull() ? json["album"][0]["strItunesID"].toString : strip(json["album"][0]["strItunesID"].str).length == 0 ? "null" :json["album"][0]["strItunesID"].str,
520                 json["album"][0]["strAmazonID"].isNull() ? json["album"][0]["strAmazonID"].toString : strip(json["album"][0]["strAmazonID"].str).length == 0 ? "null" :json["album"][0]["strAmazonID"].str,
521                 json["album"][0]["strLocked"].isNull() ? json["album"][0]["strLocked"].toString : strip(json["album"][0]["strLocked"].str).length == 0 ? "null" :json["album"][0]["strLocked"].str,
522             };
523             return data;
524         }
525         throw new Exception("no results found");
526     }
527     catch(CurlException ex)
528     {
529         throw new AudioDBException(ex.msg);
530     }
531     catch(JSONException ex)
532     {
533         throw new AudioDBException(format("Something went wrong while parsing json: %s", ex.msg));
534     }
535     catch(Exception ex)
536     {
537         throw new AudioDBException(ex.msg);
538     }
539 }
540 
541 /** 
542  * Params:
543  *   l
544  * Returns: All Albums for an Artist using known Artist ID
545  * Throws: AudioDBException on failure
546  */
547 Album[] searchAlbumsByArtistId(long l) {
548     try
549     {
550         auto response = getRequest(format("album.php?i=%d", l));
551         if (response.length == 0)
552         {
553             throw new Exception("no results found");
554         }
555         JSONValue json = parseJSON(response); 
556         if (json["album"].type != JSONType.null_ && json["album"].array.length != 0) {
557             Album[] array = [];
558             foreach(ref i; json["album"].array)
559             {
560                 Album data = {
561                     i["idAlbum"].isNull() ? i["idAlbum"].toString : strip(i["idAlbum"].str).length == 0 ? "null" :i["idAlbum"].str,
562                     i["idArtist"].isNull() ? i["idArtist"].toString : strip(i["idArtist"].str).length == 0 ? "null" :i["idArtist"].str,
563                     i["idLabel"].isNull() ? i["idLabel"].toString : strip(i["idLabel"].str).length == 0 ? "null" :i["idLabel"].str,
564                     i["strAlbum"].isNull() ? i["strAlbum"].toString : strip(i["strAlbum"].str).length == 0 ? "null" :i["strAlbum"].str,
565                     i["strAlbumStripped"].isNull() ? i["strAlbumStripped"].toString : strip(i["strAlbumStripped"].str).length == 0 ? "null" :i["strAlbumStripped"].str,
566                     i["strArtist"].isNull() ? i["strArtist"].toString : strip(i["strArtist"].str).length == 0 ? "null" :i["strArtist"].str,
567                     i["strArtistStripped"].isNull() ? i["strArtistStripped"].toString : strip(i["strArtistStripped"].str).length == 0 ? "null" :i["strArtistStripped"].str,
568                     i["intYearReleased"].isNull() ? i["intYearReleased"].toString : strip(i["intYearReleased"].str).length == 0 ? "null" :i["intYearReleased"].str,
569                     i["strStyle"].isNull() ? i["strStyle"].toString : strip(i["strStyle"].str).length == 0 ? "null" :i["strStyle"].str,
570                     i["strGenre"].isNull() ? i["strGenre"].toString : strip(i["strGenre"].str).length == 0 ? "null" :i["strGenre"].str,
571                     i["strLabel"].isNull() ? i["strLabel"].toString : strip(i["strLabel"].str).length == 0 ? "null" :i["strLabel"].str,
572                     i["strReleaseFormat"].isNull() ? i["strReleaseFormat"].toString : strip(i["strReleaseFormat"].str).length == 0 ? "null" :i["strReleaseFormat"].str,
573                     i["intSales"].isNull() ? i["intSales"].toString : strip(i["intSales"].str).length == 0 ? "null" :i["intSales"].str,
574                     i["strAlbumThumb"].isNull() ? i["strAlbumThumb"].toString : strip(i["strAlbumThumb"].str).length == 0 ? "null" :i["strAlbumThumb"].str,
575                     i["strAlbumThumbHQ"].isNull() ? i["strAlbumThumbHQ"].toString : strip(i["strAlbumThumbHQ"].str).length == 0 ? "null" :i["strAlbumThumbHQ"].str,
576                     i["strAlbumThumbBack"].isNull() ? i["strAlbumThumbBack"].toString : strip(i["strAlbumThumbBack"].str).length == 0 ? "null" :i["strAlbumThumbBack"].str,
577                     i["strAlbumCDart"].isNull() ? i["strAlbumCDart"].toString : strip(i["strAlbumCDart"].str).length == 0 ? "null" :i["strAlbumCDart"].str,
578                     i["strAlbumSpine"].isNull() ? i["strAlbumSpine"].toString : strip(i["strAlbumSpine"].str).length == 0 ? "null" :i["strAlbumSpine"].str,
579                     i["strAlbum3DCase"].isNull() ? i["strAlbum3DCase"].toString : strip(i["strAlbum3DCase"].str).length == 0 ? "null" :i["strAlbum3DCase"].str,
580                     i["strAlbum3DFlat"].isNull() ? i["strAlbum3DFlat"].toString : strip(i["strAlbum3DFlat"].str).length == 0 ? "null" :i["strAlbum3DFlat"].str,
581                     i["strAlbum3DFace"].isNull() ? i["strAlbum3DFace"].toString : strip(i["strAlbum3DFace"].str).length == 0 ? "null" :i["strAlbum3DFace"].str,
582                     i["strAlbum3DThumb"].isNull() ? i["strAlbum3DThumb"].toString : strip(i["strAlbum3DThumb"].str).length == 0 ? "null" :i["strAlbum3DThumb"].str,
583                     i["strDescriptionDE"].isNull() ? i["strDescriptionDE"].toString : strip(i["strDescriptionDE"].str).length == 0 ? "null" :i["strDescriptionDE"].str,
584                     i["strDescriptionFR"].isNull() ? i["strDescriptionFR"].toString : strip(i["strDescriptionFR"].str).length == 0 ? "null" :i["strDescriptionFR"].str,
585                     i["strDescriptionCN"].isNull() ? i["strDescriptionCN"].toString : strip(i["strDescriptionCN"].str).length == 0 ? "null" :i["strDescriptionCN"].str,
586                     i["strDescriptionIT"].isNull() ? i["strDescriptionIT"].toString : strip(i["strDescriptionIT"].str).length == 0 ? "null" :i["strDescriptionIT"].str,
587                     i["strDescriptionJP"].isNull() ? i["strDescriptionJP"].toString : strip(i["strDescriptionJP"].str).length == 0 ? "null" :i["strDescriptionJP"].str,
588                     i["strDescriptionRU"].isNull() ? i["strDescriptionRU"].toString : strip(i["strDescriptionRU"].str).length == 0 ? "null" :i["strDescriptionRU"].str,
589                     i["strDescriptionES"].isNull() ? i["strDescriptionES"].toString : strip(i["strDescriptionES"].str).length == 0 ? "null" :i["strDescriptionES"].str,
590                     i["strDescriptionPT"].isNull() ? i["strDescriptionPT"].toString : strip(i["strDescriptionPT"].str).length == 0 ? "null" :i["strDescriptionPT"].str,
591                     i["strDescriptionSE"].isNull() ? i["strDescriptionSE"].toString : strip(i["strDescriptionSE"].str).length == 0 ? "null" :i["strDescriptionSE"].str,
592                     i["strDescriptionNL"].isNull() ? i["strDescriptionNL"].toString : strip(i["strDescriptionNL"].str).length == 0 ? "null" :i["strDescriptionNL"].str,
593                     i["strDescriptionHU"].isNull() ? i["strDescriptionHU"].toString : strip(i["strDescriptionHU"].str).length == 0 ? "null" :i["strDescriptionHU"].str,
594                     i["strDescriptionNO"].isNull() ? i["strDescriptionNO"].toString : strip(i["strDescriptionNO"].str).length == 0 ? "null" :i["strDescriptionNO"].str,
595                     i["strDescriptionIL"].isNull() ? i["strDescriptionIL"].toString : strip(i["strDescriptionIL"].str).length == 0 ? "null" :i["strDescriptionIL"].str,
596                     i["strDescriptionPL"].isNull() ? i["strDescriptionPL"].toString : strip(i["strDescriptionPL"].str).length == 0 ? "null" :i["strDescriptionPL"].str,
597                     i["intLoved"].isNull() ? i["intLoved"].toString : strip(i["intLoved"].str).length == 0 ? "null" :i["intLoved"].str,
598                     i["intScore"].isNull() ? i["intScore"].toString : strip(i["intScore"].str).length == 0 ? "null" :i["intScore"].str,
599                     i["intScoreVotes"].isNull() ? i["intScoreVotes"].toString : strip(i["intScoreVotes"].str).length == 0 ? "null" :i["intScoreVotes"].str,
600                     i["strReview"].isNull() ? i["strReview"].toString : strip(i["strReview"].str).length == 0 ? "null" :i["strReview"].str,
601                     i["strMood"].isNull() ? i["strMood"].toString : strip(i["strMood"].str).length == 0 ? "null" :i["strMood"].str,
602                     i["strTheme"].isNull() ? i["strTheme"].toString : strip(i["strTheme"].str).length == 0 ? "null" :i["strTheme"].str,
603                     i["strSpeed"].isNull() ? i["strSpeed"].toString : strip(i["strSpeed"].str).length == 0 ? "null" :i["strSpeed"].str,
604                     i["strLocation"].isNull() ? i["strLocation"].toString : strip(i["strLocation"].str).length == 0 ? "null" :i["strLocation"].str,
605                     i["strMusicBrainzID"].isNull() ? i["strMusicBrainzID"].toString : strip(i["strMusicBrainzID"].str).length == 0 ? "null" :i["strMusicBrainzID"].str,
606                     i["strMusicBrainzArtistID"].isNull() ? i["strMusicBrainzArtistID"].toString : strip(i["strMusicBrainzArtistID"].str).length == 0 ? "null" :i["strMusicBrainzArtistID"].str,
607                     i["strAllMusicID"].isNull() ? i["strAllMusicID"].toString : strip(i["strAllMusicID"].str).length == 0 ? "null" :i["strAllMusicID"].str,
608                     i["strBBCReviewID"].isNull() ? i["strBBCReviewID"].toString : strip(i["strBBCReviewID"].str).length == 0 ? "null" :i["strBBCReviewID"].str,
609                     i["strRateYourMusicID"].isNull() ? i["strRateYourMusicID"].toString : strip(i["strRateYourMusicID"].str).length == 0 ? "null" :i["strRateYourMusicID"].str,
610                     i["strDiscogsID"].isNull() ? i["strDiscogsID"].toString : strip(i["strDiscogsID"].str).length == 0 ? "null" :i["strDiscogsID"].str,
611                     i["strWikidataID"].isNull() ? i["strWikidataID"].toString : strip(i["strWikidataID"].str).length == 0 ? "null" :i["strWikidataID"].str,
612                     i["strWikipediaID"].isNull() ? i["strWikipediaID"].toString : strip(i["strWikipediaID"].str).length == 0 ? "null" :i["strWikipediaID"].str,
613                     i["strGeniusID"].isNull() ? i["strGeniusID"].toString : strip(i["strGeniusID"].str).length == 0 ? "null" :i["strGeniusID"].str,
614                     i["strLyricWikiID"].isNull() ? i["strLyricWikiID"].toString : strip(i["strLyricWikiID"].str).length == 0 ? "null" :i["strLyricWikiID"].str,
615                     i["strMusicMozID"].isNull() ? i["strMusicMozID"].toString : strip(i["strMusicMozID"].str).length == 0 ? "null" :i["strMusicMozID"].str,
616                     i["strItunesID"].isNull() ? i["strItunesID"].toString : strip(i["strItunesID"].str).length == 0 ? "null" :i["strItunesID"].str,
617                     i["strAmazonID"].isNull() ? i["strAmazonID"].toString : strip(i["strAmazonID"].str).length == 0 ? "null" :i["strAmazonID"].str,
618                     i["strLocked"].isNull() ? i["strLocked"].toString : strip(i["strLocked"].str).length == 0 ? "null" :i["strLocked"].str,
619                 };
620                 array ~= data;
621             }
622             return array;
623         }
624         throw new Exception("no results found");
625     }
626     catch(CurlException ex)
627     {
628         throw new AudioDBException(ex.msg);
629     }
630     catch(JSONException ex)
631     {
632         throw new AudioDBException(format("Something went wrong while parsing json: %s", ex.msg));
633     }
634     catch(Exception ex)
635     {
636         throw new AudioDBException(ex.msg);
637     }
638 }
639 
640 /** 
641  * Params:
642  *   l
643  * Returns: All Tracks for Album from known Album ID
644  * Throws: AudioDBException on failure
645  */
646 Track[] searchTracksByAlbumId(long l) {
647     try
648     {
649         auto response = getRequest(format("track.php?m=%d", l));
650         if (response.length == 0)
651         {
652             throw new Exception("no results found");
653         }
654         JSONValue json = parseJSON(response); 
655         if (json["track"].type != JSONType.null_ && json["track"].array.length != 0) {
656             Track[] array = [];
657             foreach(ref i; json["track"].array)
658             {
659                 Track data = {
660                     i["idTrack"].isNull() ? i["idTrack"].toString : strip(i["idTrack"].str).length == 0 ? "null" :i["idTrack"].str,
661                     i["idAlbum"].isNull() ? i["idAlbum"].toString : strip(i["idAlbum"].str).length == 0 ? "null" :i["idAlbum"].str,
662                     i["idArtist"].isNull() ? i["idArtist"].toString : strip(i["idArtist"].str).length == 0 ? "null" :i["idArtist"].str,
663                     i["idLyric"].isNull() ? i["idLyric"].toString : strip(i["idLyric"].str).length == 0 ? "null" :i["idLyric"].str,
664                     i["idIMVDB"].isNull() ? i["idIMVDB"].toString : strip(i["idIMVDB"].str).length == 0 ? "null" :i["idIMVDB"].str,
665                     i["strTrack"].isNull() ? i["strTrack"].toString : strip(i["strTrack"].str).length == 0 ? "null" :i["strTrack"].str,
666                     i["strAlbum"].isNull() ? i["strAlbum"].toString : strip(i["strAlbum"].str).length == 0 ? "null" :i["strAlbum"].str,
667                     i["strArtist"].isNull() ? i["strArtist"].toString : strip(i["strArtist"].str).length == 0 ? "null" :i["strArtist"].str,
668                     i["strArtistAlternate"].isNull() ? i["strArtistAlternate"].toString : strip(i["strArtistAlternate"].str).length == 0 ? "null" :i["strArtistAlternate"].str,
669                     i["intCD"].isNull() ? i["intCD"].toString : strip(i["intCD"].str).length == 0 ? "null" :i["intCD"].str,
670                     i["intDuration"].isNull() ? i["intDuration"].toString : strip(i["intDuration"].str).length == 0 ? "null" :i["intDuration"].str,
671                     i["strGenre"].isNull() ? i["strGenre"].toString : strip(i["strGenre"].str).length == 0 ? "null" :i["strGenre"].str,
672                     i["strMood"].isNull() ? i["strMood"].toString : strip(i["strMood"].str).length == 0 ? "null" :i["strMood"].str,
673                     i["strStyle"].isNull() ? i["strStyle"].toString : strip(i["strStyle"].str).length == 0 ? "null" :i["strStyle"].str,
674                     i["strTheme"].isNull() ? i["strTheme"].toString : strip(i["strTheme"].str).length == 0 ? "null" :i["strTheme"].str,
675                     i["strDescriptionEN"].isNull() ? i["strDescriptionEN"].toString : strip(i["strDescriptionEN"].str).length == 0 ? "null" :i["strDescriptionEN"].str,
676                     i["strDescriptionDE"].isNull() ? i["strDescriptionDE"].toString : strip(i["strDescriptionDE"].str).length == 0 ? "null" :i["strDescriptionDE"].str,
677                     i["strDescriptionFR"].isNull() ? i["strDescriptionFR"].toString : strip(i["strDescriptionFR"].str).length == 0 ? "null" :i["strDescriptionFR"].str,
678                     i["strDescriptionCN"].isNull() ? i["strDescriptionCN"].toString : strip(i["strDescriptionCN"].str).length == 0 ? "null" :i["strDescriptionCN"].str,
679                     i["strDescriptionIT"].isNull() ? i["strDescriptionIT"].toString : strip(i["strDescriptionIT"].str).length == 0 ? "null" :i["strDescriptionIT"].str,
680                     i["strDescriptionJP"].isNull() ? i["strDescriptionJP"].toString : strip(i["strDescriptionJP"].str).length == 0 ? "null" :i["strDescriptionJP"].str,
681                     i["strDescriptionRU"].isNull() ? i["strDescriptionRU"].toString : strip(i["strDescriptionRU"].str).length == 0 ? "null" :i["strDescriptionRU"].str,
682                     i["strDescriptionES"].isNull() ? i["strDescriptionES"].toString : strip(i["strDescriptionES"].str).length == 0 ? "null" :i["strDescriptionES"].str,
683                     i["strDescriptionPT"].isNull() ? i["strDescriptionPT"].toString : strip(i["strDescriptionPT"].str).length == 0 ? "null" :i["strDescriptionPT"].str,
684                     i["strDescriptionSE"].isNull() ? i["strDescriptionSE"].toString : strip(i["strDescriptionSE"].str).length == 0 ? "null" :i["strDescriptionSE"].str,
685                     i["strDescriptionNL"].isNull() ? i["strDescriptionNL"].toString : strip(i["strDescriptionNL"].str).length == 0 ? "null" :i["strDescriptionNL"].str,
686                     i["strDescriptionHU"].isNull() ? i["strDescriptionHU"].toString : strip(i["strDescriptionHU"].str).length == 0 ? "null" :i["strDescriptionHU"].str,
687                     i["strDescriptionNO"].isNull() ? i["strDescriptionNO"].toString : strip(i["strDescriptionNO"].str).length == 0 ? "null" :i["strDescriptionNO"].str,
688                     i["strDescriptionIL"].isNull() ? i["strDescriptionIL"].toString : strip(i["strDescriptionIL"].str).length == 0 ? "null" :i["strDescriptionIL"].str,
689                     i["strDescriptionPL"].isNull() ? i["strDescriptionPL"].toString : strip(i["strDescriptionPL"].str).length == 0 ? "null" :i["strDescriptionPL"].str,
690                     i["strTrackThumb"].isNull() ? i["strTrackThumb"].toString : strip(i["strTrackThumb"].str).length == 0 ? "null" :i["strTrackThumb"].str,
691                     i["strTrack3DCase"].isNull() ? i["strTrack3DCase"].toString : strip(i["strTrack3DCase"].str).length == 0 ? "null" :i["strTrack3DCase"].str,
692                     i["strTrackLyrics"].isNull() ? i["strTrackLyrics"].toString : strip(i["strTrackLyrics"].str).length == 0 ? "null" :i["strTrackLyrics"].str,
693                     i["strMusicVid"].isNull() ? i["strMusicVid"].toString : strip(i["strMusicVid"].str).length == 0 ? "null" :i["strMusicVid"].str,
694                     i["strMusicVidDirector"].isNull() ? i["strMusicVidDirector"].toString : strip(i["strMusicVidDirector"].str).length == 0 ? "null" :i["strMusicVidDirector"].str,
695                     i["strMusicVidCompany"].isNull() ? i["strMusicVidCompany"].toString : strip(i["strMusicVidCompany"].str).length == 0 ? "null" :i["strMusicVidCompany"].str,
696                     i["strMusicVidScreen1"].isNull() ? i["strMusicVidScreen1"].toString : strip(i["strMusicVidScreen1"].str).length == 0 ? "null" :i["strMusicVidScreen1"].str,
697                     i["strMusicVidScreen2"].isNull() ? i["strMusicVidScreen2"].toString : strip(i["strMusicVidScreen2"].str).length == 0 ? "null" :i["strMusicVidScreen2"].str,
698                     i["strMusicVidScreen3"].isNull() ? i["strMusicVidScreen3"].toString : strip(i["strMusicVidScreen3"].str).length == 0 ? "null" :i["strMusicVidScreen3"].str,
699                     i["intMusicVidViews"].isNull() ? i["intMusicVidViews"].toString : strip(i["intMusicVidViews"].str).length == 0 ? "null" :i["intMusicVidViews"].str,
700                     i["intMusicVidLikes"].isNull() ? i["intMusicVidLikes"].toString : strip(i["intMusicVidLikes"].str).length == 0 ? "null" :i["intMusicVidLikes"].str,
701                     i["intMusicVidDislikes"].isNull() ? i["intMusicVidDislikes"].toString : strip(i["intMusicVidDislikes"].str).length == 0 ? "null" :i["intMusicVidDislikes"].str,
702                     i["intMusicVidFavorites"].isNull() ? i["intMusicVidFavorites"].toString : strip(i["intMusicVidFavorites"].str).length == 0 ? "null" :i["intMusicVidFavorites"].str,
703                     i["intMusicVidComments"].isNull() ? i["intMusicVidComments"].toString : strip(i["intMusicVidComments"].str).length == 0 ? "null" :i["intMusicVidComments"].str,
704                     i["intTrackNumber"].isNull() ? i["intTrackNumber"].toString : strip(i["intTrackNumber"].str).length == 0 ? "null" :i["intTrackNumber"].str,
705                     i["intLoved"].isNull() ? i["intLoved"].toString : strip(i["intLoved"].str).length == 0 ? "null" :i["intLoved"].str,
706                     i["intScore"].isNull() ? i["intScore"].toString : strip(i["intScore"].str).length == 0 ? "null" :i["intScore"].str,
707                     i["intScoreVotes"].isNull() ? i["intScoreVotes"].toString : strip(i["intScoreVotes"].str).length == 0 ? "null" :i["intScoreVotes"].str,
708                     i["intTotalListeners"].isNull() ? i["intTotalListeners"].toString : strip(i["intTotalListeners"].str).length == 0 ? "null" :i["intTotalListeners"].str,
709                     i["intTotalPlays"].isNull() ? i["intTotalPlays"].toString : strip(i["intTotalPlays"].str).length == 0 ? "null" :i["intTotalPlays"].str,
710                     i["strMusicBrainzID"].isNull() ? i["strMusicBrainzID"].toString : strip(i["strMusicBrainzID"].str).length == 0 ? "null" :i["strMusicBrainzID"].str,
711                     i["strMusicBrainzAlbumID"].isNull() ? i["strMusicBrainzAlbumID"].toString : strip(i["strMusicBrainzAlbumID"].str).length == 0 ? "null" :i["strMusicBrainzAlbumID"].str,
712                     i["strMusicBrainzArtistID"].isNull() ? i["strMusicBrainzArtistID"].toString : strip(i["strMusicBrainzArtistID"].str).length == 0 ? "null" :i["strMusicBrainzArtistID"].str,
713                     i["strLocked"].isNull() ? i["strLocked"].toString : strip(i["strLocked"].str).length == 0 ? "null" :i["strLocked"].str,
714                 };
715                 array ~= data;
716             }
717             return array;
718         }
719         throw new Exception("no results found");
720     }
721     catch(CurlException ex)
722     {
723         throw new AudioDBException(ex.msg);
724     }
725     catch(JSONException ex)
726     {
727         throw new AudioDBException(format("Something went wrong while parsing json: %s", ex.msg));
728     }
729     catch(Exception ex)
730     {
731         throw new AudioDBException(ex.msg);
732     }
733 }
734 
735 /** 
736  * Params:
737  *   l
738  * Returns: individual track info using a known Track ID
739  * Throws: AudioDBException on failure
740  */
741 Track searchTrackById(long l) {
742     try
743     {
744         auto response = getRequest(format("track.php?h=%d", l));
745         if (response.length == 0)
746         {
747             throw new Exception("no results found");
748         }
749         JSONValue json = parseJSON(response); 
750         if (json["track"].type != JSONType.null_ && json["track"].array.length != 0) {
751             Track data = {
752                 json["track"][0]["idTrack"].isNull() ? json["track"][0]["idTrack"].toString : strip(json["track"][0]["idTrack"].str).length == 0 ? "null" :json["track"][0]["idTrack"].str,
753                 json["track"][0]["idAlbum"].isNull() ? json["track"][0]["idAlbum"].toString : strip(json["track"][0]["idAlbum"].str).length == 0 ? "null" :json["track"][0]["idAlbum"].str,
754                 json["track"][0]["idArtist"].isNull() ? json["track"][0]["idArtist"].toString : strip(json["track"][0]["idArtist"].str).length == 0 ? "null" :json["track"][0]["idArtist"].str,
755                 json["track"][0]["idLyric"].isNull() ? json["track"][0]["idLyric"].toString : strip(json["track"][0]["idLyric"].str).length == 0 ? "null" :json["track"][0]["idLyric"].str,
756                 json["track"][0]["idIMVDB"].isNull() ? json["track"][0]["idIMVDB"].toString : strip(json["track"][0]["idIMVDB"].str).length == 0 ? "null" :json["track"][0]["idIMVDB"].str,
757                 json["track"][0]["strTrack"].isNull() ? json["track"][0]["strTrack"].toString : strip(json["track"][0]["strTrack"].str).length == 0 ? "null" :json["track"][0]["strTrack"].str,
758                 json["track"][0]["strAlbum"].isNull() ? json["track"][0]["strAlbum"].toString : strip(json["track"][0]["strAlbum"].str).length == 0 ? "null" :json["track"][0]["strAlbum"].str,
759                 json["track"][0]["strArtist"].isNull() ? json["track"][0]["strArtist"].toString : strip(json["track"][0]["strArtist"].str).length == 0 ? "null" :json["track"][0]["strArtist"].str,
760                 json["track"][0]["strArtistAlternate"].isNull() ? json["track"][0]["strArtistAlternate"].toString : strip(json["track"][0]["strArtistAlternate"].str).length == 0 ? "null" :json["track"][0]["strArtistAlternate"].str,
761                 json["track"][0]["intCD"].isNull() ? json["track"][0]["intCD"].toString : strip(json["track"][0]["intCD"].str).length == 0 ? "null" :json["track"][0]["intCD"].str,
762                 json["track"][0]["intDuration"].isNull() ? json["track"][0]["intDuration"].toString : strip(json["track"][0]["intDuration"].str).length == 0 ? "null" :json["track"][0]["intDuration"].str,
763                 json["track"][0]["strGenre"].isNull() ? json["track"][0]["strGenre"].toString : strip(json["track"][0]["strGenre"].str).length == 0 ? "null" :json["track"][0]["strGenre"].str,
764                 json["track"][0]["strMood"].isNull() ? json["track"][0]["strMood"].toString : strip(json["track"][0]["strMood"].str).length == 0 ? "null" :json["track"][0]["strMood"].str,
765                 json["track"][0]["strStyle"].isNull() ? json["track"][0]["strStyle"].toString : strip(json["track"][0]["strStyle"].str).length == 0 ? "null" :json["track"][0]["strStyle"].str,
766                 json["track"][0]["strTheme"].isNull() ? json["track"][0]["strTheme"].toString : strip(json["track"][0]["strTheme"].str).length == 0 ? "null" :json["track"][0]["strTheme"].str,
767                 json["track"][0]["strDescriptionEN"].isNull() ? json["track"][0]["strDescriptionEN"].toString : strip(json["track"][0]["strDescriptionEN"].str).length == 0 ? "null" :json["track"][0]["strDescriptionEN"].str,
768                 json["track"][0]["strDescriptionDE"].isNull() ? json["track"][0]["strDescriptionDE"].toString : strip(json["track"][0]["strDescriptionDE"].str).length == 0 ? "null" :json["track"][0]["strDescriptionDE"].str,
769                 json["track"][0]["strDescriptionFR"].isNull() ? json["track"][0]["strDescriptionFR"].toString : strip(json["track"][0]["strDescriptionFR"].str).length == 0 ? "null" :json["track"][0]["strDescriptionFR"].str,
770                 json["track"][0]["strDescriptionCN"].isNull() ? json["track"][0]["strDescriptionCN"].toString : strip(json["track"][0]["strDescriptionCN"].str).length == 0 ? "null" :json["track"][0]["strDescriptionCN"].str,
771                 json["track"][0]["strDescriptionIT"].isNull() ? json["track"][0]["strDescriptionIT"].toString : strip(json["track"][0]["strDescriptionIT"].str).length == 0 ? "null" :json["track"][0]["strDescriptionIT"].str,
772                 json["track"][0]["strDescriptionJP"].isNull() ? json["track"][0]["strDescriptionJP"].toString : strip(json["track"][0]["strDescriptionJP"].str).length == 0 ? "null" :json["track"][0]["strDescriptionJP"].str,
773                 json["track"][0]["strDescriptionRU"].isNull() ? json["track"][0]["strDescriptionRU"].toString : strip(json["track"][0]["strDescriptionRU"].str).length == 0 ? "null" :json["track"][0]["strDescriptionRU"].str,
774                 json["track"][0]["strDescriptionES"].isNull() ? json["track"][0]["strDescriptionES"].toString : strip(json["track"][0]["strDescriptionES"].str).length == 0 ? "null" :json["track"][0]["strDescriptionES"].str,
775                 json["track"][0]["strDescriptionPT"].isNull() ? json["track"][0]["strDescriptionPT"].toString : strip(json["track"][0]["strDescriptionPT"].str).length == 0 ? "null" :json["track"][0]["strDescriptionPT"].str,
776                 json["track"][0]["strDescriptionSE"].isNull() ? json["track"][0]["strDescriptionSE"].toString : strip(json["track"][0]["strDescriptionSE"].str).length == 0 ? "null" :json["track"][0]["strDescriptionSE"].str,
777                 json["track"][0]["strDescriptionNL"].isNull() ? json["track"][0]["strDescriptionNL"].toString : strip(json["track"][0]["strDescriptionNL"].str).length == 0 ? "null" :json["track"][0]["strDescriptionNL"].str,
778                 json["track"][0]["strDescriptionHU"].isNull() ? json["track"][0]["strDescriptionHU"].toString : strip(json["track"][0]["strDescriptionHU"].str).length == 0 ? "null" :json["track"][0]["strDescriptionHU"].str,
779                 json["track"][0]["strDescriptionNO"].isNull() ? json["track"][0]["strDescriptionNO"].toString : strip(json["track"][0]["strDescriptionNO"].str).length == 0 ? "null" :json["track"][0]["strDescriptionNO"].str,
780                 json["track"][0]["strDescriptionIL"].isNull() ? json["track"][0]["strDescriptionIL"].toString : strip(json["track"][0]["strDescriptionIL"].str).length == 0 ? "null" :json["track"][0]["strDescriptionIL"].str,
781                 json["track"][0]["strDescriptionPL"].isNull() ? json["track"][0]["strDescriptionPL"].toString : strip(json["track"][0]["strDescriptionPL"].str).length == 0 ? "null" :json["track"][0]["strDescriptionPL"].str,
782                 json["track"][0]["strTrackThumb"].isNull() ? json["track"][0]["strTrackThumb"].toString : strip(json["track"][0]["strTrackThumb"].str).length == 0 ? "null" :json["track"][0]["strTrackThumb"].str,
783                 json["track"][0]["strTrack3DCase"].isNull() ? json["track"][0]["strTrack3DCase"].toString : strip(json["track"][0]["strTrack3DCase"].str).length == 0 ? "null" :json["track"][0]["strTrack3DCase"].str,
784                 json["track"][0]["strTrackLyrics"].isNull() ? json["track"][0]["strTrackLyrics"].toString : strip(json["track"][0]["strTrackLyrics"].str).length == 0 ? "null" :json["track"][0]["strTrackLyrics"].str,
785                 json["track"][0]["strMusicVid"].isNull() ? json["track"][0]["strMusicVid"].toString : strip(json["track"][0]["strMusicVid"].str).length == 0 ? "null" :json["track"][0]["strMusicVid"].str,
786                 json["track"][0]["strMusicVidDirector"].isNull() ? json["track"][0]["strMusicVidDirector"].toString : strip(json["track"][0]["strMusicVidDirector"].str).length == 0 ? "null" :json["track"][0]["strMusicVidDirector"].str,
787                 json["track"][0]["strMusicVidCompany"].isNull() ? json["track"][0]["strMusicVidCompany"].toString : strip(json["track"][0]["strMusicVidCompany"].str).length == 0 ? "null" :json["track"][0]["strMusicVidCompany"].str,
788                 json["track"][0]["strMusicVidScreen1"].isNull() ? json["track"][0]["strMusicVidScreen1"].toString : strip(json["track"][0]["strMusicVidScreen1"].str).length == 0 ? "null" :json["track"][0]["strMusicVidScreen1"].str,
789                 json["track"][0]["strMusicVidScreen2"].isNull() ? json["track"][0]["strMusicVidScreen2"].toString : strip(json["track"][0]["strMusicVidScreen2"].str).length == 0 ? "null" :json["track"][0]["strMusicVidScreen2"].str,
790                 json["track"][0]["strMusicVidScreen3"].isNull() ? json["track"][0]["strMusicVidScreen3"].toString : strip(json["track"][0]["strMusicVidScreen3"].str).length == 0 ? "null" :json["track"][0]["strMusicVidScreen3"].str,
791                 json["track"][0]["intMusicVidViews"].isNull() ? json["track"][0]["intMusicVidViews"].toString : strip(json["track"][0]["intMusicVidViews"].str).length == 0 ? "null" :json["track"][0]["intMusicVidViews"].str,
792                 json["track"][0]["intMusicVidLikes"].isNull() ? json["track"][0]["intMusicVidLikes"].toString : strip(json["track"][0]["intMusicVidLikes"].str).length == 0 ? "null" :json["track"][0]["intMusicVidLikes"].str,
793                 json["track"][0]["intMusicVidDislikes"].isNull() ? json["track"][0]["intMusicVidDislikes"].toString : strip(json["track"][0]["intMusicVidDislikes"].str).length == 0 ? "null" :json["track"][0]["intMusicVidDislikes"].str,
794                 json["track"][0]["intMusicVidFavorites"].isNull() ? json["track"][0]["intMusicVidFavorites"].toString : strip(json["track"][0]["intMusicVidFavorites"].str).length == 0 ? "null" :json["track"][0]["intMusicVidFavorites"].str,
795                 json["track"][0]["intMusicVidComments"].isNull() ? json["track"][0]["intMusicVidComments"].toString : strip(json["track"][0]["intMusicVidComments"].str).length == 0 ? "null" :json["track"][0]["intMusicVidComments"].str,
796                 json["track"][0]["intTrackNumber"].isNull() ? json["track"][0]["intTrackNumber"].toString : strip(json["track"][0]["intTrackNumber"].str).length == 0 ? "null" :json["track"][0]["intTrackNumber"].str,
797                 json["track"][0]["intLoved"].isNull() ? json["track"][0]["intLoved"].toString : strip(json["track"][0]["intLoved"].str).length == 0 ? "null" :json["track"][0]["intLoved"].str,
798                 json["track"][0]["intScore"].isNull() ? json["track"][0]["intScore"].toString : strip(json["track"][0]["intScore"].str).length == 0 ? "null" :json["track"][0]["intScore"].str,
799                 json["track"][0]["intScoreVotes"].isNull() ? json["track"][0]["intScoreVotes"].toString : strip(json["track"][0]["intScoreVotes"].str).length == 0 ? "null" :json["track"][0]["intScoreVotes"].str,
800                 json["track"][0]["intTotalListeners"].isNull() ? json["track"][0]["intTotalListeners"].toString : strip(json["track"][0]["intTotalListeners"].str).length == 0 ? "null" :json["track"][0]["intTotalListeners"].str,
801                 json["track"][0]["intTotalPlays"].isNull() ? json["track"][0]["intTotalPlays"].toString : strip(json["track"][0]["intTotalPlays"].str).length == 0 ? "null" :json["track"][0]["intTotalPlays"].str,
802                 json["track"][0]["strMusicBrainzID"].isNull() ? json["track"][0]["strMusicBrainzID"].toString : strip(json["track"][0]["strMusicBrainzID"].str).length == 0 ? "null" :json["track"][0]["strMusicBrainzID"].str,
803                 json["track"][0]["strMusicBrainzAlbumID"].isNull() ? json["track"][0]["strMusicBrainzAlbumID"].toString : strip(json["track"][0]["strMusicBrainzAlbumID"].str).length == 0 ? "null" :json["track"][0]["strMusicBrainzAlbumID"].str,
804                 json["track"][0]["strMusicBrainzArtistID"].isNull() ? json["track"][0]["strMusicBrainzArtistID"].toString : strip(json["track"][0]["strMusicBrainzArtistID"].str).length == 0 ? "null" :json["track"][0]["strMusicBrainzArtistID"].str,
805                 json["track"][0]["strLocked"].isNull() ? json["track"][0]["strLocked"].toString : strip(json["track"][0]["strLocked"].str).length == 0 ? "null" :json["track"][0]["strLocked"].str,
806             };
807             return data;
808         }
809         throw new Exception("no results found");
810     }
811     catch(CurlException ex)
812     {
813         throw new AudioDBException(ex.msg);
814     }
815     catch(JSONException ex)
816     {
817         throw new AudioDBException(format("Something went wrong while parsing json: %s", ex.msg));
818     }
819     catch(Exception ex)
820     {
821         throw new AudioDBException(ex.msg);
822     }
823 }
824 
825 /** 
826  * Params:
827  *   l
828  * Returns: all the Music videos for a known Artist ID
829  * Throws: AudioDBException on failure
830  */
831 MusicVideo[] searchMusicVideosByArtistId(long l) {
832     try
833     {
834         auto response = getRequest(format("mvid.php?i=%d", l));
835         if (response.length == 0)
836         {
837             throw new Exception("no results found");
838         }
839         JSONValue json = parseJSON(response); 
840         if (json["mvids"].type != JSONType.null_ && json["mvids"].array.length != 0) {
841             MusicVideo[] array = [];
842             foreach(ref i; json["mvids"].array)
843             {
844                 MusicVideo data = {
845                     i["idArtist"].isNull() ? i["idArtist"].toString : strip(i["idArtist"].str).length == 0 ? "null" : i["idArtist"].str,
846                     i["idAlbum"].isNull() ? i["idAlbum"].toString : strip(i["idAlbum"].str).length == 0 ? "null" : i["idAlbum"].str,
847                     i["idTrack"].isNull() ? i["idTrack"].toString : strip(i["idTrack"].str).length == 0 ? "null" : i["idTrack"].str,
848                     i["strTrack"].isNull() ? i["strTrack"].toString : strip(i["strTrack"].str).length == 0 ? "null" : i["strTrack"].str,
849                     i["strTrackThumb"].isNull() ? i["strTrackThumb"].toString : strip(i["strTrackThumb"].str).length == 0 ? "null" : i["strTrackThumb"].str,
850                     i["strMusicVid"].isNull() ? i["strMusicVid"].toString : strip(i["strMusicVid"].str).length == 0 ? "null" : i["strMusicVid"].str,
851                     i["strDescriptionEN"].isNull() ? i["strDescriptionEN"].toString : strip(i["strDescriptionEN"].str).length == 0 ? "null" : i["strDescriptionEN"].str,
852                 };
853                 array ~= data;
854             }
855             return array;
856         }
857         throw new Exception("no results found");
858     }
859     catch(CurlException ex)
860     {
861         throw new AudioDBException(ex.msg);
862     }
863     catch(JSONException ex)
864     {
865         throw new AudioDBException(format("Something went wrong while parsing json: %s", ex.msg));
866     }
867     catch(Exception ex)
868     {
869         throw new AudioDBException(ex.msg);
870     }
871 }