Przeglądaj źródła

init jonnieZG/YCast

Thomas Hanika 3 lat temu
rodzic
commit
53d88a4e36
7 zmienionych plików z 40 dodań i 26 usunięć
  1. 1 0
      .gitignore
  2. 1 1
      setup.py
  3. 11 0
      ycast/generic.py
  4. 3 15
      ycast/my_stations.py
  5. 21 7
      ycast/radiobrowser.py
  6. 1 1
      ycast/server.py
  7. 2 2
      ycast/station_icons.py

+ 1 - 0
.gitignore

@@ -2,5 +2,6 @@ build
 dist
 *.egg-info
 .idea
+.vscode
 *.iml
 *.pyc

+ 1 - 1
setup.py

@@ -40,6 +40,6 @@ setup(
         'onkyo',
         'denon'
     ],
-    install_requires=['requests', 'flask', 'PyYAML', 'Pillow'],
+    install_requires=['requests', 'flask', 'PyYAML', 'Pillow', 'oyaml'],
     packages=find_packages(exclude=['contrib', 'docs', 'tests'])
 )

+ 11 - 0
ycast/generic.py

@@ -1,5 +1,6 @@
 import logging
 import os
+import hashlib
 
 USER_AGENT = 'YCast'
 VAR_PATH = os.path.expanduser("~") + '/.ycast'
@@ -50,3 +51,13 @@ def get_cache_path(cache_name):
         logging.error("Could not create cache folders (%s) because of access permissions", cache_path)
         return None
     return cache_path
+
+def get_checksum(feed, charlimit=12):
+    hash_feed = feed.encode()
+    hash_object = hashlib.md5(hash_feed)
+    digest = hash_object.digest()
+    xor_fold = bytearray(digest[:8])
+    for i, b in enumerate(digest[8:]):
+        xor_fold[i] ^= b
+    digest_xor_fold = ''.join(format(x, '02x') for x in bytes(xor_fold))
+    return digest_xor_fold[:charlimit]

+ 3 - 15
ycast/my_stations.py

@@ -1,7 +1,5 @@
 import logging
-import hashlib
-
-import yaml
+import oyaml as yaml
 
 import ycast.vtuner as vtuner
 import ycast.generic as generic
@@ -63,6 +61,7 @@ def get_stations_yaml():
         return my_recently_station
     return my_stations
 
+
 def get_category_directories():
     my_stations_yaml = get_stations_yaml()
     categories = []
@@ -83,17 +82,6 @@ def get_stations_by_category(category):
             station_icon = None
             if len(url_list) > 1:
                 station_icon = url_list[1]
-            station_id = str(get_checksum(station_name + station_url)).upper()
+            station_id = str(generic.get_checksum(station_name + station_url)).upper()
             stations.append(Station(station_id, station_name, station_url, category, station_icon))
     return stations
-
-
-def get_checksum(feed, charlimit=12):
-    hash_feed = feed.encode()
-    hash_object = hashlib.md5(hash_feed)
-    digest = hash_object.digest()
-    xor_fold = bytearray(digest[:8])
-    for i, b in enumerate(digest[8:]):
-        xor_fold[i] ^= b
-    digest_xor_fold = ''.join(format(x, '02x') for x in bytes(xor_fold))
-    return digest_xor_fold[:charlimit]

+ 21 - 7
ycast/radiobrowser.py

@@ -13,6 +13,7 @@ DEFAULT_STATION_LIMIT = 200
 SHOW_BROKEN_STATIONS = False
 ID_PREFIX = "RB"
 
+id_registry = {}
 
 def get_json_attr(json, attr):
     try:
@@ -23,7 +24,7 @@ def get_json_attr(json, attr):
 
 class Station:
     def __init__(self, station_json):
-        self.id = generic.generate_stationid_with_prefix(get_json_attr(station_json, 'stationuuid'), ID_PREFIX)
+        self.id = get_json_attr(station_json, 'stationuuid')
         self.name = get_json_attr(station_json, 'name')
         self.url = get_json_attr(station_json, 'url')
         self.icon = get_json_attr(station_json, 'favicon')
@@ -35,12 +36,14 @@ class Station:
         self.bitrate = get_json_attr(station_json, 'bitrate')
 
     def to_vtuner(self):
-        return vtuner.Station(self.id, self.name, ', '.join(self.tags), self.url, self.icon,
+        tid = generic.get_checksum(self.id)
+        id_registry[tid] = self.id
+        return vtuner.Station(generic.generate_stationid_with_prefix(tid, ID_PREFIX), self.name, ', '.join(self.tags), self.url, self.icon,
                               self.tags[0], self.countrycode, self.codec, self.bitrate, None)
 
     def get_playable_url(self):
         try:
-            playable_url_json = request('url/' + generic.get_stationid_without_prefix(self.id))[0]
+            playable_url_json = request('url/' + str(self.id))[0]
             self.url = playable_url_json['url']
         except (IndexError, KeyError):
             logging.error("Could not retrieve first playlist item for station with id '%s'", self.id)
@@ -61,14 +64,18 @@ def request(url):
 
 
 def get_station_by_id(uid):
-    station_json = request('stations/byuuid/' + str(uid))
-    if station_json and len(station_json):
-        return Station(station_json[0])
-    else:
+    try:
+        station_json = request('stations/byuuid/' + str(id_registry[uid]))
+        if station_json and len(station_json):
+            return Station(station_json[0])
+        else:
+            return None
+    except KeyError:
         return None
 
 
 def search(name, limit=DEFAULT_STATION_LIMIT):
+    id_registry.clear()
     stations = []
     stations_json = request('stations/search?order=name&reverse=false&limit=' + str(limit) + '&name=' + str(name))
     for station_json in stations_json:
@@ -78,6 +85,7 @@ def search(name, limit=DEFAULT_STATION_LIMIT):
 
 
 def get_country_directories():
+    id_registry.clear()
     country_directories = []
     apicall = 'countries'
     if not SHOW_BROKEN_STATIONS:
@@ -92,6 +100,7 @@ def get_country_directories():
 
 
 def get_language_directories():
+    id_registry.clear()
     language_directories = []
     apicall = 'languages'
     if not SHOW_BROKEN_STATIONS:
@@ -107,6 +116,7 @@ def get_language_directories():
 
 
 def get_genre_directories():
+    id_registry.clear()
     genre_directories = []
     apicall = 'tags'
     if not SHOW_BROKEN_STATIONS:
@@ -122,6 +132,7 @@ def get_genre_directories():
 
 
 def get_stations_by_country(country):
+    id_registry.clear()
     stations = []
     stations_json = request('stations/search?order=name&reverse=false&countryExact=true&country=' + str(country))
     for station_json in stations_json:
@@ -131,6 +142,7 @@ def get_stations_by_country(country):
 
 
 def get_stations_by_language(language):
+    id_registry.clear()
     stations = []
     stations_json = request('stations/search?order=name&reverse=false&languageExact=true&language=' + str(language))
     for station_json in stations_json:
@@ -140,6 +152,7 @@ def get_stations_by_language(language):
 
 
 def get_stations_by_genre(genre):
+    id_registry.clear()
     stations = []
     stations_json = request('stations/search?order=name&reverse=false&tagExact=true&tag=' + str(genre))
     for station_json in stations_json:
@@ -149,6 +162,7 @@ def get_stations_by_genre(genre):
 
 
 def get_stations_by_votes(limit=DEFAULT_STATION_LIMIT):
+    id_registry.clear()
     stations = []
     stations_json = request('stations?order=votes&reverse=true&limit=' + str(limit))
     for station_json in stations_json:

+ 1 - 1
ycast/server.py

@@ -305,7 +305,7 @@ def get_station_icon():
         abort(404)
     station_icon = station_icons.get_icon(station)
     if not station_icon:
-        logging.error("Could not get station icon for station with id '%s'", stationid)
+        logging.warning("Could not get station icon for station with id '%s'", stationid)
         abort(404)
     response = make_response(station_icon)
     response.headers.set('Content-Type', 'image/jpeg')

+ 2 - 2
ycast/station_icons.py

@@ -23,10 +23,10 @@ def get_icon(station):
         try:
             response = requests.get(station.icon, headers=headers)
         except requests.exceptions.ConnectionError as err:
-            logging.error("Connection to station icon URL failed (%s)", err)
+            logging.debug("Connection to station icon URL failed (%s)", err)
             return None
         if response.status_code != 200:
-            logging.error("Could not get station icon data from %s (HTML status %s)", station.icon, response.status_code)
+            logging.debug("Could not get station icon data from %s (HTML status %s)", station.icon, response.status_code)
             return None
         try:
             image = Image.open(io.BytesIO(response.content))