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)
예제 #5
0
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)
예제 #6
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)
예제 #7
0
    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)
예제 #8
0
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
예제 #9
0
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
예제 #10
0
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)
예제 #11
0
def coverdata(mbid):
    url = "http://coverartarchive.org/release/{}/".format(mbid)
    data = retrieve_url(url)
    if data is not None:
        return json.loads(data.text)
예제 #12
0
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