def test_cache(self): retrieve_url(GOOGLE) self.assertTrue(is_cached(GOOGLE)) self.assertFalse(is_negative_cached(GOOGLE)) retrieve_url(NOT_EXISTING) self.assertFalse(is_cached(NOT_EXISTING)) self.assertTrue(is_negative_cached(NOT_EXISTING))
def test_ssl(self): self.assertIsNotNone(retrieve_url(GOOGLE)) self.assertIsNotNone(retrieve_url(BAD_CERT, verify=False)) clear_cache() self.assertIsNone(retrieve_url(BAD_CERT)) clear_cache() self.assertIsNone(retrieve_url(BAD_CERT, verify=True))
def test_retrieve(self): res1 = retrieve_url(GOOGLE) self.assertIsNotNone(res1) self.assertTrue("html" in res1.text) res2 = retrieve_url(GOOGLE) self.assertEqual(res1, res2) res = retrieve_url(NOT_EXISTING) self.assertIsNone(res)
def test_timeout(self): clear_cache() t1 = datetime.now() self.assertIsNone(retrieve_url(TIMEOUT, timeout=5)) t2 = datetime.now() # This should take about 5 seconds self.assertLess((t2 - t1).total_seconds(), 7) self.assertLess(4, (t2 - t1).total_seconds()) clear_cache() t1 = datetime.now() self.assertIsNone(retrieve_url(TIMEOUT, timeout=1)) t2 = datetime.now() self.assertLess((t2 - t1).total_seconds(), 3)
def hifiberry_cover(song_mbid, album_mbid, artist_mbid, player="unknown"): logging.debug("trying to find coverart for %s from hifiberry", song_mbid) try: url = "{}/cover/{}/{}/{}/{}".format(BASE_URL, song_mbid, album_mbid, artist_mbid, player) cover_data = retrieve_url(url) if cover_data is None: return (None, 0, 0) else: cover_data = cover_data.text if cover_data is not None and len(cover_data) > 0: try: (cover_url, width, height) = cover_data.split("|") except: cover_url = None width = 0 height = 0 if cover_url == "": cover_url = None if cover_url is None: logging.info("no cover found on hifiberry musicdb") return (cover_url, int(width), int(height)) else: logging.info("did not receive cover data from %s", url) return (None, 0, 0) except Exception as e: logging.warn("can't load cover for %s: %s", song_mbid, e) logging.exception(e) return (None, 0, 0)
def get_fanart_cover(artistmbid, albummbid, allow_artist_picture=False): url = "http://webservice.fanart.tv/v3/music/{}?api_key={}".format( artistmbid, APIKEY) try: json_text = retrieve_url(url).text if json_text is None: logging.debug("artist does not exit on fanart.tv") return data = json.loads(json_text) # Try to find the album cover first try: coverurl = data["albums"][albummbid]["albumcover"]["url"] logging.debug("found album cover on fanart.tv") return coverurl except KeyError: logging.debug("found no album cover on fanart.tv") # If this doesn't exist, use artist cover if allow_artist_picture: try: imageurl = data["artistthumb"][1]["url"] logging.debug("found artist picture on fanart.tv") return imageurl except KeyError: logging.debug("found no artist picture on fanart.tv") except Exception as e: logging.debug("couldn't retrieve data from fanart.tv (%s)", e)
def run(self): import socket import sys res = [] for dst in self.my_broadcasts(): st = "upnp:rootdevice" if len(sys.argv) > 2: st = sys.argv[2] msg = [ 'M-SEARCH * HTTP/1.1', 'Host:239.255.255.250:1900', 'ST:%s' % (st, ), 'Man:"ssdp:discover"', 'MX:1', '' ] urls = set() s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) s.settimeout(5) try: s.sendto('\r\n'.join(msg).encode("utf-8"), (dst, 1900)) except Exception as e: logging.warning("Exception %s when sending to %s", e, dst) continue while True: try: data, _addr = s.recvfrom(32 * 1024) for line in data.decode("utf-8").splitlines(): if line.startswith("LOCATION:"): (_loc, url) = line.split(":", 1) urls.add(url.strip()) except socket.timeout: break for url in urls: desc = retrieve_url(url, timeout=2) if desc is None: continue if "<deviceType>urn:schemas-upnp-org:device:LaMetric:1</deviceType>" in desc.text: o = urlparse(url) ip = o.hostname logging.info("found LaMetric at " + ip) res.append(ip) self.lametric.set_ips(res)
def albumInfo(artist_name, album_name, albummbid=None): if albummbid is not None: url = album_mbid_template.format(quote(albummbid)) else: url = album_template.format(quote(artist_name), quote(album_name)) albumdata = None data = retrieve_url(url) if data is not None: albumdata = json.loads(data.text) if albummbid is not None and (albumdata is None or "error" in albumdata): logging.debug("album not found via mbid, retrying with name/title") albumdata = albumInfo(artist_name, album_name, None) return albumdata
def trackInfo(artist, title, mbid, userparam): if mbid is not None: url = track_mbid_template.format(mbid, userparam) else: url = track_template.format(quote(artist), quote(title), userparam) trackdata = None data = retrieve_url(url) if data is not None: trackdata = json.loads(data.text) if mbid is not None and (trackdata is None or "error" in trackdata): logging.debug("track not found via mbid, retrying with name/title") trackdata = trackInfo(artist, title, None, userparam) return trackdata
def artistInfo(artist_name): url = artist_template.format(quote(artist_name)) data = retrieve_url(url) if data is not None: return json.loads(data.text)
def coverdata(mbid): url = "http://coverartarchive.org/release/{}/".format(mbid) data = retrieve_url(url) if data is not None: return json.loads(data.text)
def guess_stream_order(stream, field1, field2, use_cloud=True): MIN_STAT_RATIO = 0.1 MIN_STATS=10 if stream.startswith("http"): caching_supported = True else: caching_supported = False logging.warn("not a web radio stream, won't use caching") stats = stream_stats.get(stream,{"ta": 0, "at": 0, "order": ORDER_UNKNOWN, "cloud": ORDER_UNKNOWN}) at = stats["at"] ta = stats["ta"] cloud = stats["cloud"] if stats["order"] != ORDER_UNKNOWN: return stats["order"] if stats["cloud"] != ORDER_UNKNOWN: return stats["cloud"] # Check hifiberry cloud if order is known for this stream if caching_supported: try: cacheinfo = retrieve_url(cloud_url(CACHE_PATH), params = { 'stream' : stream }) if cacheinfo is not None: cloud = int(cacheinfo.content) else: cloud = ORDER_UNKNOWN except Exception as e: logging.exception(e) if cloud in [ ORDER_ARTIST_TITLE, ORDER_TITLE_ARTIST]: order = cloud stream_order = cloud else: stream_order = ORDER_UNKNOWN order = guess_order(field1, field2) if order == ORDER_ARTIST_TITLE: at += 1 elif order == ORDER_TITLE_ARTIST: ta += 1 logging.debug("at/ta: %s/%s",at,ta) if stream_order == ORDER_UNKNOWN and at+ta > MIN_STATS: if float(at)*MIN_STAT_RATIO > ta: stream_order = ORDER_ARTIST_TITLE elif float(ta)*MIN_STAT_RATIO > at: stream_order = ORDER_TITLE_ARTIST else: stream_order = ORDER_UNKNOWN logging.info("guess stream %s is using %s encoding (%s/%s)", stream, verbose[stream_order], at, ta) if use_cloud and caching_supported and stream_order != ORDER_UNKNOWN: post_data(cloud_url(CACHE_PATH), { "stream": stream, "order": stream_order}) else: stream_order = ORDER_UNKNOWN stream_stats[stream]={"order": stream_order, "ta": ta, "at": at, "cloud": cloud} return order