diff --git a/data/interfaces/default/config.html b/data/interfaces/default/config.html index 3859d4a7..28888cae 100644 --- a/data/interfaces/default/config.html +++ b/data/interfaces/default/config.html @@ -720,8 +720,8 @@
- - e.g. http://localhost:9117/torznab/iptorrents + + e.g. http://localhost:9117/api/v2.0/indexers/demonoid/results/torznab/
@@ -744,7 +744,7 @@
- +
diff --git a/headphones/__init__.py b/headphones/__init__.py index 2bd3bf9c..c6acc763 100644 --- a/headphones/__init__.py +++ b/headphones/__init__.py @@ -87,7 +87,7 @@ LATEST_VERSION = None COMMITS_BEHIND = None LOSSY_MEDIA_FORMATS = ["mp3", "aac", "ogg", "ape", "m4a", "asf", "wma", "opus"] -LOSSLESS_MEDIA_FORMATS = ["flac", "aiff"] +LOSSLESS_MEDIA_FORMATS = ["flac", "aiff", "aif"] MEDIA_FORMATS = LOSSY_MEDIA_FORMATS + LOSSLESS_MEDIA_FORMATS MIRRORLIST = ["musicbrainz.org", "headphones", "custom"] diff --git a/headphones/deluge.py b/headphones/deluge.py index 78647b0c..5eb27849 100644 --- a/headphones/deluge.py +++ b/headphones/deluge.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + # This file is part of Headphones. # # Headphones is free software: you can redistribute it and/or modify @@ -168,7 +170,10 @@ def addTorrent(link, data=None, name=None): # remove '.torrent' suffix if name[-len('.torrent'):] == '.torrent': name = name[:-len('.torrent')] - logger.debug('Deluge: Sending Deluge torrent with name %s and content [%s...]' % (name, str(torrentfile)[:40])) + try: + logger.debug('Deluge: Sending Deluge torrent with name %s and content [%s...]' % (name, str(torrentfile)[:40])) + except UnicodeDecodeError: + logger.debug('Deluge: Sending Deluge torrent with name %s and content [%s...]' % (name.decode('utf-8'), str(torrentfile)[:40])) result = {'type': 'torrent', 'name': name, 'content': torrentfile} @@ -379,7 +384,8 @@ def _get_auth(): return None delugeweb_hosts = json.loads(response.text)['result'] - if len(delugeweb_hosts) == 0: + # Check if delugeweb_hosts is None before checking its length + if not delugeweb_hosts or len(delugeweb_hosts) == 0: logger.error('Deluge: WebUI does not contain daemons') return None @@ -465,7 +471,8 @@ def _add_torrent_file(result): try: # content is torrent file contents that needs to be encoded to base64 post_data = json.dumps({"method": "core.add_torrent_file", - "params": [result['name'] + '.torrent', b64encode(result['content'].encode('utf8')), {}], + "params": [result['name'] + '.torrent', + b64encode(result['content'].encode('utf8')), {}], "id": 2}) response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth, verify=deluge_verify_cert, headers=headers) @@ -478,7 +485,8 @@ def _add_torrent_file(result): # this time let's try leaving the encoding as is logger.debug('Deluge: There was a decoding issue, let\'s try again') post_data = json.dumps({"method": "core.add_torrent_file", - "params": [result['name'] + '.torrent', b64encode(result['content']), {}], + "params": [result['name'].decode('utf8') + '.torrent', + b64encode(result['content']), {}], "id": 22}) response = requests.post(delugeweb_url, data=post_data.encode('utf-8'), cookies=delugeweb_auth, verify=deluge_verify_cert, headers=headers) diff --git a/headphones/helpers.py b/headphones/helpers.py index 05f6108b..acc64fd3 100644 --- a/headphones/helpers.py +++ b/headphones/helpers.py @@ -223,8 +223,7 @@ def replace_illegal_chars(string, type="file"): if type == "file": string = re.sub('[\?"*:|<>/]', '_', string) if type == "folder": - string = re.sub('[:\?<>"|]', '_', string) - + string = re.sub('[:\?<>"|*]', '_', string) return string diff --git a/headphones/lastfm.py b/headphones/lastfm.py index 8f906d5f..db3e1aec 100644 --- a/headphones/lastfm.py +++ b/headphones/lastfm.py @@ -149,7 +149,10 @@ def getTagTopArtists(tag, limit=50): logger.debug("Fetched %d artists from Last.FM", len(artists)) for artist in artists: - artist_mbid = artist["mbid"] + try: + artist_mbid = artist["mbid"] + except KeyError: + continue if not any(artist_mbid in x for x in results): artistlist.append(artist_mbid) diff --git a/headphones/searcher.py b/headphones/searcher.py index 0dc81b54..2fc5e78d 100644 --- a/headphones/searcher.py +++ b/headphones/searcher.py @@ -43,7 +43,8 @@ from bencode import bencode, bdecode TORRENT_TO_MAGNET_SERVICES = [ # 'https://zoink.it/torrent/%s.torrent', # 'http://torrage.com/torrent/%s.torrent', - 'https://torcache.net/torrent/%s.torrent', + # 'https://torcache.net/torrent/%s.torrent', + 'http://itorrents.org/torrent/%s.torrent', ] # Persistent Apollo.rip API object @@ -878,12 +879,11 @@ def send_to_downloader(data, bestqual, album): services = TORRENT_TO_MAGNET_SERVICES[:] random.shuffle(services) headers = {'User-Agent': USER_AGENT} - headers['Referer'] = 'https://torcache.net/' for service in services: data = request.request_content(service % torrent_hash, headers=headers) - if data and "torcache" in data: + if data: if not torrent_to_file(download_path, data): return # Extract folder name from torrent @@ -1305,8 +1305,12 @@ def searchTorrent(album, new=False, losslessOnly=False, albumlength=None, provider = torznab_host[0] + # Format Jackett provider + if "api/v2.0/indexers" in torznab_host[0]: + provider = "Jackett_" + provider.split("/indexers/", 1)[1].split('/', 1)[0] + # Request results - logger.info('Parsing results from %s using search term: %s' % (torznab_host[0], term)) + logger.info('Parsing results from %s using search term: %s' % (provider, term)) headers = {'User-Agent': USER_AGENT} params = { @@ -1318,14 +1322,14 @@ def searchTorrent(album, new=False, losslessOnly=False, albumlength=None, } data = request.request_feed( - url=torznab_host[0] + '/api?', + url=torznab_host[0], params=params, headers=headers ) # Process feed if data: if not len(data.entries): - logger.info(u"No results found from %s for %s", torznab_host[0], term) + logger.info(u"No results found from %s for %s", provider, term) else: for item in data.entries: try: diff --git a/headphones/webserve.py b/headphones/webserve.py index 6d95712a..9d703a5c 100644 --- a/headphones/webserve.py +++ b/headphones/webserve.py @@ -348,14 +348,18 @@ class WebInterface(object): dirs = set(dirs) - for dir in dirs: - artistfolder = os.path.join(dir, folder) - if not os.path.isdir(artistfolder.encode(headphones.SYS_ENCODING)): - logger.debug("Cannot find directory: " + artistfolder) - continue - threading.Thread(target=librarysync.libraryScan, - kwargs={"dir": artistfolder, "artistScan": True, "ArtistID": ArtistID, - "ArtistName": artist_name}).start() + try: + for dir in dirs: + artistfolder = os.path.join(dir, folder) + if not os.path.isdir(artistfolder.encode(headphones.SYS_ENCODING)): + logger.debug("Cannot find directory: " + artistfolder) + continue + threading.Thread(target=librarysync.libraryScan, + kwargs={"dir": artistfolder, "artistScan": True, "ArtistID": ArtistID, + "ArtistName": artist_name}).start() + except Exception as e: + logger.error('Unable to complete the scan: %s' % e) + raise cherrypy.HTTPRedirect("artistPage?ArtistID=%s" % ArtistID) @cherrypy.expose