+class CoverFetcher(threading.Thread):
+ def __init__(self):
+ threading.Thread.__init__(self)
+ self.setDaemon(True)
+ self.cond = threading.Condition()
+ self.work = []
+
+ def _retrieve(self, url, fname):
+ BROKEN = 'http://imgjam.com/radios/default/default.100.png'
+ if url == BROKEN:
+ return None
+ f = open(fname, 'wb')
+ c = pycurl.Curl()
+ c.setopt(pycurl.FOLLOWLOCATION, 1)
+ c.setopt(pycurl.URL, str(url))
+ c.setopt(pycurl.WRITEFUNCTION, f.write)
+ try:
+ c.perform()
+ except:
+ fname = None
+ finally:
+ c.close()
+ f.close()
+ log.debug("Coverfetch: %s -> %s", url, fname)
+ return fname
+
+ def _fetch_cover(self, albumid, size):
+ try:
+ coverdir = _COVERDIR if _COVERDIR else '/tmp'
+ to = os.path.join(coverdir, '%d-%d.jpg'%(albumid, size))
+ if not os.path.isfile(to):
+ url = _GET2+'image/album/redirect/?id=%d&imagesize=%d'%(albumid, size)
+ to = self._retrieve(url, to)
+ return to
+ except Exception, e:
+ return None
+
+ def _fetch_image(self, url):
+ try:
+ h = hashlib.md5(url).hexdigest()
+ coverdir = _COVERDIR if _COVERDIR else '/tmp'
+ to = os.path.join(coverdir, h+'.jpg')
+ if not os.path.isfile(to):
+ to = self._retrieve(url, to)
+ return to
+ except Exception, e:
+ return None
+
+ def request_cover(self, albumid, size, cb):
+ self.cond.acquire()
+ self.work.insert(0, (albumid, size, cb))
+ self.cond.notify()
+ self.cond.release()
+
+ def request_images(self, urls, cb):
+ """cb([(url, image)])"""
+ self.cond.acquire()
+ self.work = [('image', url, cb) for url in urls] + self.work
+ self.cond.notify()
+ self.cond.release()
+
+ def run(self):
+ while True:
+ work = []
+ self.cond.acquire()
+ while True:
+ work = self.work
+ if work:
+ self.work = []
+ break
+ self.cond.wait()
+ self.cond.release()
+
+ multi = len(work) > 1
+ for job in work:
+ if job[0] == 'image':
+ self.process_image(job[1], job[2])
+ else:
+ self.process_cover(*job)
+
+ def process_cover(self, albumid, size, cb):
+ cover = self._fetch_cover(albumid, size)
+ if cover:
+ cb(albumid, size, cover)
+
+ def process_image(self, url, cb):
+ image = self._fetch_image(url)
+ if image:
+ cb([(url, image)])
+