00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 import simplejson as json
00027
00028 import os
00029 import hashlib
00030 import time
00031
00032
00033 from urllib2 import urlopen, URLError
00034 from urllib import urlencode as _urlencode
00035
00036
00037 import functions
00038
00039
00040 functions.translation_gettext()
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 class Query(object):
00090 def __init__(self, query=None, caching_time=None, raise_event=None, ignore_cache=None):
00091 self.query = query
00092 self.caching_time = caching_time
00093 self.raise_event = raise_event
00094 self.ignore_cache = ignore_cache
00095
00096 def send(self):
00097 pass
00098
00099
00100
00101
00102 class Jamendo:
00103
00104 def __init__(self, parent):
00105 self.__parent = parent
00106 self.__home = functions.preparedirs()
00107
00108 self.cachedir = os.path.join(self.__home, "cache")
00109
00110 self.cache_counter = 0
00111
00112 self.jamendo_counter = 0
00113
00114 self.__last_query = None
00115
00116 self.__ignore_cache = None
00117
00118 self.__parent.Events.add_event("jamendo-query")
00119
00120
00121
00122
00123
00124
00125
00126 try:
00127 self.json = json.JSONDecoder(strict=False)
00128 except:
00129 self.json = json.JSONDecoder()
00130
00131
00132
00133
00134
00135
00136
00137
00138 def get_album_image(self, album_id, size=100):
00139 image = "http://api.jamendo.com/get2/image/album/redirect/?id=%i&imagesize=%i" % (int(album_id), int(size))
00140 md5hash = hashlib.md5(image).hexdigest()
00141 fh = os.path.join(self.main.home, "images", md5hash)
00142 if not os.path.exists(fh):
00143 try:
00144 urllib.urlretrieve(image, fh)
00145 return fh
00146 except IOError:
00147 print ("Could not load image")
00148 return None
00149 else:
00150 return fh
00151
00152
00153
00154
00155
00156 def set_ignore_cache(self, value):
00157 self.__ignore_cache = value
00158
00159
00160
00161 def get_ignore_cache(self):
00162 return self.__ignore_cache
00163
00164
00165
00166
00167 def check(self, query):
00168 if query is None:
00169 return False
00170 if isinstance(query, list) and query == []:
00171 return False
00172 if isinstance(query, int) and query < 0:
00173 return False
00174 if isinstance(query, str) and query == "":
00175 return False
00176 return True
00177
00178
00179
00180
00181
00182
00183
00184 def json_decode(self, string):
00185 try:
00186
00187
00188
00189 return self.json.decode(string)
00190 except Exception, inst:
00191 desc = "An error occured while parsing Jamendos server-response\n"
00192 desc += "Most probably this is a json issue coming up with new\n"
00193 desc += "versions of debian.\n"
00194 desc += "<b>Get the newest version of pyjama to deal with it!</b>"
00195 self.__parent.Events.raise_event("error", inst, desc)
00196 return None
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 def get(self, field, unit, params, format="json"):
00208 print ("Requesting database on jamendo.com")
00209 query = "http://api.jamendo.com/get2/" + field + "/" + unit + "/" + format + "/" + params
00210 if self.__parent.debug:
00211 print query
00212 source = urlopen(query)
00213 print ("Requesting database - done")
00214 return self.json_decode(source.read())
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 def cache(self, query, CACHING_TIME = None):
00226 if CACHING_TIME == None or CACHING_TIME == self.__parent.settings.get_value("JAMENDO", "CACHING_TIME_LONG"):
00227 CACHING_TIME = self.__parent.settings.get_value("JAMENDO", "CACHING_TIME_LONG")
00228 subdir = "long"
00229 else:
00230 subdir = "short"
00231 if self.__ignore_cache is True:
00232 print "Ignoring Cache"
00233 CACHING_TIME = 0
00234 md5hash = hashlib.md5(query).hexdigest()
00235 datei = os.path.join(self.cachedir, subdir, md5hash)
00236 if os.path.exists(datei):
00237 file_time = os.stat(datei).st_mtime
00238 if file_time + CACHING_TIME > time.time():
00239 datei = open(datei,'r')
00240 content = datei.read()
00241 datei.close()
00242 remaining = CACHING_TIME - (time.time() - file_time)
00243 m = 60
00244 h = 60*m
00245 d = h*24
00246
00247 days = remaining // d
00248 hours = (remaining - d*days) // h
00249 mins = ((remaining - d*days) - h*hours) // m
00250 secs = (((remaining - d*days) - h*hours) - m*mins)
00251 if self.__parent.verbose:
00252 print ("This Query was loaded from Cache. New Data will be loaded from Jamendo in %i days, %i hourse, %i minutes and %i seconds.") % (days, hours, mins, secs)
00253 if CACHING_TIME == self.__parent.settings.get_value("JAMENDO", "CACHING_TIME_LONG"):
00254 print ("Don't mind this might be to long. This specific data- set won't change!")
00255
00256 self.__parent.window.sbStatus.set_text("Info", _("From Cache. Reload in %iD, %i:%i:%i") % (days, hours, mins, secs))
00257 self.cache_counter += 1
00258 return content
00259 print ("Cache too old, Loading Data from Jamendo")
00260 self.__parent.window.sbStatus.set_text("Info", _("Refreshing Cache"))
00261 return False
00262 print ("No Data cached, yet. Caching Query now")
00263 self.__parent.window.sbStatus.set_text("Info", _("Cached from Jamendo"))
00264 self.jamendo_counter += 1
00265 return False
00266
00267 def __write2cache(self, query, result, caching_time = None):
00268 if caching_time == None or caching_time == self.__parent.settings.get_value("JAMENDO", "CACHING_TIME_LONG"):
00269 subdir = "long"
00270 else:
00271 subdir = "short"
00272 if self.__parent.debug:
00273 print subdir
00274 md5hash = hashlib.md5(query).hexdigest()
00275 datei = os.path.join(self.cachedir, subdir, md5hash)
00276 fh = file(datei,'w')
00277 fh.write(result)
00278 fh.close()
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289 def query(self, query, caching_time = None, raise_query_event=True):
00290 if raise_query_event:
00291 self.__parent.Events.raise_event("jamendo-query", "start")
00292 query = "http://api.jamendo.com/get2/" + query
00293 ret = self.cache(query, caching_time)
00294 if ret != False:
00295 if raise_query_event:
00296 self.__parent.Events.raise_event("jamendo-query", "end")
00297 return self.json_decode(ret)
00298 if self.__last_query == None:
00299 self.__last_query = time.time()
00300 elif self.__last_query + 1 > time.time():
00301 print "To fast"
00302 print (query)
00303 if raise_query_event:
00304 self.__parent.Events.raise_event("jamendo-query", "end")
00305 return None
00306 else:
00307 self.__last_query = time.time()
00308 if self.__parent.verbose:
00309 print ("Requesting database on jamendo.com")
00310 if self.__parent.debug:
00311 print query
00312 try:
00313 source = urlopen(query)
00314 except URLError, inst:
00315 desc = "Could not query Data from jamendo. Perhaps Jamendo is maintening the servers or your connection is broken."
00316 self.__parent.Events.raise_event("error", inst, desc)
00317 print ("couldn't load from jamendo")
00318 if raise_query_event:
00319 self.__parent.Events.raise_event("jamendo-query", "end")
00320 return -1
00321 ret = source.read()
00322 self.__write2cache(query, ret, caching_time)
00323 if self.__parent.verbose:
00324 print ("Requesting database - done, wrote cache")
00325 if raise_query_event:
00326 self.__parent.Events.raise_event("jamendo-query", "end")
00327 return self.json_decode(ret)
00328
00329
00330
00331 def last_query_hack(self):
00332 self.__last_query=0
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343 def queryold(self, query, caching_time = None, raise_query_event=True):
00344 if raise_query_event:
00345 self.__parent.Events.raise_event("jamendo-query", "start")
00346 query = "http://www.jamendo.com/get/" + query
00347 ret = self.cache(query, caching_time)
00348 if ret != False:
00349 if raise_query_event:
00350 self.__parent.Events.raise_event("jamendo-query", "end")
00351 return self.json_decode(ret)
00352 if self.__last_query == None:
00353 self.__last_query = time.time()
00354 elif self.__last_query + 1 > time.time():
00355 print ("To fast")
00356 print (query)
00357 if raise_query_event:
00358 self.__parent.Events.raise_event("jamendo-query", "end")
00359 return None
00360 else:
00361 self.__last_query = time.time()
00362 print ("Requesting database on jamendo.com")
00363 if self.__parent.debug:
00364 print query
00365 try:
00366 source = urlopen(query)
00367 except URLError, inst:
00368 desc = "Could not query Data from jamendo. Perhaps Jamendo is maintening the servers or your connection is broken."
00369 self.__parent.Events.raise_event("error", inst, desc)
00370 print ("couldn't load from jamendo")
00371 if raise_query_event:
00372 self.__parent.Events.raise_event("jamendo-query", "end")
00373 return -1
00374 ret = source.read()
00375 self.__write2cache(query, ret, caching_time)
00376 print ("Requesting database - done, wrote cache")
00377 if raise_query_event:
00378 self.__parent.Events.raise_event("jamendo-query", "end")
00379 return self.json_decode(ret)
00380
00381
00382
00383
00384 def get_similar_albums(self, album_id, num=5):
00385 if self.__parent.debug:
00386 print ("jamendo: getting similar albums")
00387 if num <= 0: return None
00388 ret = self.query("id/album/jsonpretty/album_album2_soundslike/?album2_id=%i&n=%i" % (album_id, num) )
00389 return ret
00390
00391
00392
00393
00394
00395
00396
00397 def top(self, num = 10, order = "tag", page=1, tag="all"):
00398 if self.__parent.debug:
00399 print ("jamendo: getting top albums")
00400 if tag == "all":
00401 if self.__parent.verbose:
00402 print ("Getting top %i ordered by '%s'") % (num, order)
00403 ret = self.query("artist_name+artist_idstr+artist_id+album_name+album_id+album_image+album_genre/album/json/?order=%s_desc&n=%i&pn=%s" % (order, num, page), self.__parent.settings.get_value("JAMENDO", "CACHING_TIME_SHORT"))
00404 else:
00405 if self.__parent.verbose:
00406 print ("Getting %i albums tagged '%s' ordered by '%s'") % (num, tag, order)
00407 ret = self.query("artist_name+artist_idstr+artist_id+album_name+album_id+album_image+album_genre/album/json/?tag_idstr=%s&n=%i&pn=%s&order=%s_desc" % (tag, num, page, order), self.__parent.settings.get_value("JAMENDO", "CACHING_TIME_SHORT"))
00408 return ret
00409
00410
00411
00412
00413 def stream(self, id):
00414 if self.__parent.debug:
00415 print ("jamendo: getting stream")
00416 if self.__parent.verbose:
00417 print ("Getting stream informations")
00418 ret = self.query("stream/track/json/?id=%i&streamencoding=ogg2" % id, self.__parent.settings.get_value("JAMENDO", "CACHING_TIME_LONG"))
00419 if ret == None:
00420 return None
00421 return ret[0]
00422
00423
00424
00425
00426
00427
00428 def trackinfos(self, id):
00429 if self.__parent.debug:
00430 print ("jamendo: getting track infos")
00431 if self.__parent.verbose:
00432 print ("Getting track informations")
00433 ret = self.queryold("track/id/track/data/json/%s?ali=full&ari=full+object+stream&tri=full&item_o=track_no_asc&showhidden=1&streamencoding=ogg2&shownotmod=1" % str(id), self.__parent.settings.get_value("JAMENDO", "CACHING_TIME_LONG"))
00434 return ret
00435
00436
00437
00438
00439
00440
00441
00442
00443 def albuminfos_altundmaechtig(self, id):
00444 if self.__parent.debug:
00445 print ("jamendo: getting a lot of album infos")
00446 strQuery = "track/id/album/data/json/ID?ali=full&ari=full+object&tri=full&item_o=track_no_asc&showhidden=1&shownotmod=1"
00447 strQuery = strQuery.replace("ID", str(id))
00448 ret = self.queryold(strQuery, self.__parent.settings.get_value("JAMENDO", "CACHING_TIME_LONG"))
00449 return ret
00450
00451
00452
00453
00454
00455
00456 def albuminfos(self, id):
00457 if self.__parent.debug:
00458 print ("jamendo: getting album infos")
00459 if self.__parent.verbose:
00460 print ("Getting album informations")
00461 strQuery = "album/id/album/data/prettyjson/ID?ali=full&ari=full+object&item_o=track_no_asc&showhidden=1&shownotmod=1"
00462 strQuery = strQuery.replace("ID", str(id))
00463 ret = self.queryold(strQuery, self.__parent.settings.get_value("JAMENDO", "CACHING_TIME_LONG"))
00464 if ret == None:
00465 return None
00466 return ret[0]
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478 def albumtracks(self, id):
00479 if self.__parent.debug:
00480 print ("jamendo: getting album's tracks")
00481 ret = self.get("track_id+track_name+track_stream+track_duration+album_name", "track", "album_track/?album_id=" + str(id)+"&streamencoding=ogg2")
00482 return ret
00483
00484
00485
00486
00487
00488
00489 def artistalbums(self, idstr):
00490 if self.__parent.debug:
00491 print ("jamendo: getting artist's albums")
00492 ret = self.get("album_id+album_name+album_playlist", "artist", "?idstr=" + idstr + "&ali=full")
00493 print ret
00494 return ret
00495
00496
00497
00498
00499
00500
00501 def artistlist(self):
00502 if self.__parent.debug:
00503 print ("jamendo: getting artist list")
00504 ret = self.get("id+idstr+name", "artist", "?artist_hasalbums&n=50")
00505 return ret