mirror of
https://github.com/rembo10/headphones.git
synced 2026-01-08 22:28:11 -05:00
Merge remote-tracking branch 'satreix/pep-e121,122' into develop
This commit is contained in:
4
.pep8
4
.pep8
@@ -1,9 +1,7 @@
|
||||
[pep8]
|
||||
# E121 continuation line under-indented for hanging indent
|
||||
# E122 continuation line missing indentation or outdented
|
||||
# E126 continuation line over-indented for hanging indent
|
||||
# E127 continuation line over-indented for visual indent
|
||||
# E128 continuation line under-indented for visual indent
|
||||
# E501 line too long (312 > 160 characters)
|
||||
ignore = E121,E122,E123,E126,E127,E128,E501
|
||||
ignore = E123,E126,E127,E128,E501
|
||||
max-line-length = 160
|
||||
|
||||
@@ -80,9 +80,8 @@ def artistlist_to_mbids(artistlist, forced=False):
|
||||
bl_artist = myDB.action('SELECT * FROM blacklist WHERE ArtistID=?',
|
||||
[artistid]).fetchone()
|
||||
if bl_artist or artistid in blacklisted_special_artists:
|
||||
logger.info(
|
||||
"Artist ID for '%s' is either blacklisted or Various Artists. To add artist, you must do it manually (Artist ID: %s)" % (
|
||||
artist, artistid))
|
||||
logger.info("Artist ID for '%s' is either blacklisted or Various Artists. To add artist, you must "
|
||||
"do it manually (Artist ID: %s)" % (artist, artistid))
|
||||
continue
|
||||
|
||||
# Add to database if it doesn't exist
|
||||
@@ -225,9 +224,8 @@ def addArtisttoDB(artistid, extrasonly=False, forcefull=False, type="artist"):
|
||||
myDB.action("DELETE FROM tracks WHERE AlbumID=?", [items['AlbumID']])
|
||||
myDB.action("DELETE FROM alltracks WHERE AlbumID=?", [items['AlbumID']])
|
||||
myDB.action('DELETE from releases WHERE ReleaseGroupID=?', [items['AlbumID']])
|
||||
logger.info(
|
||||
"[%s] Removing all references to release group %s to reflect MusicBrainz refresh" % (
|
||||
artist['artist_name'], items['AlbumID']))
|
||||
logger.info("[%s] Removing all references to release group %s to reflect MusicBrainz refresh" % (
|
||||
artist['artist_name'], items['AlbumID']))
|
||||
if not extrasonly:
|
||||
force_repackage = 1
|
||||
else:
|
||||
@@ -259,14 +257,12 @@ def addArtisttoDB(artistid, extrasonly=False, forcefull=False, type="artist"):
|
||||
new_release_group = True
|
||||
|
||||
if new_release_group:
|
||||
logger.info("[%s] Now adding: %s (New Release Group)" % (
|
||||
artist['artist_name'], rg['title']))
|
||||
logger.info("[%s] Now adding: %s (New Release Group)" % (artist['artist_name'], rg['title']))
|
||||
new_releases = mb.get_new_releases(rgid, includeExtras)
|
||||
|
||||
else:
|
||||
if check_release_date is None or check_release_date == u"None":
|
||||
logger.info("[%s] Now updating: %s (No Release Date)" % (
|
||||
artist['artist_name'], rg['title']))
|
||||
logger.info("[%s] Now updating: %s (No Release Date)" % (artist['artist_name'], rg['title']))
|
||||
new_releases = mb.get_new_releases(rgid, includeExtras, True)
|
||||
else:
|
||||
if len(check_release_date) == 10:
|
||||
@@ -349,11 +345,11 @@ def addArtisttoDB(artistid, extrasonly=False, forcefull=False, type="artist"):
|
||||
try:
|
||||
hybridrelease = getHybridRelease(fullreleaselist)
|
||||
logger.info('[%s] Packaging %s releases into hybrid title' % (
|
||||
artist['artist_name'], rg['title']))
|
||||
artist['artist_name'], rg['title']))
|
||||
except Exception as e:
|
||||
errors = True
|
||||
logger.warn('[%s] Unable to get hybrid release information for %s: %s' % (
|
||||
artist['artist_name'], rg['title'], e))
|
||||
artist['artist_name'], rg['title'], e))
|
||||
continue
|
||||
|
||||
# Use the ReleaseGroupID as the ReleaseID for the hybrid release to differentiate it
|
||||
@@ -374,8 +370,7 @@ def addArtisttoDB(artistid, extrasonly=False, forcefull=False, type="artist"):
|
||||
|
||||
for track in hybridrelease['Tracks']:
|
||||
|
||||
cleanname = helpers.clean_name(
|
||||
artist['artist_name'] + ' ' + rg['title'] + ' ' + track['title'])
|
||||
cleanname = helpers.clean_name(artist['artist_name'] + ' ' + rg['title'] + ' ' + track['title'])
|
||||
|
||||
controlValueDict = {"TrackID": track['id'],
|
||||
"ReleaseID": rg['id']}
|
||||
@@ -503,7 +498,7 @@ def addArtisttoDB(artistid, extrasonly=False, forcefull=False, type="artist"):
|
||||
|
||||
if rg_exists:
|
||||
if rg_exists['Status'] == 'Skipped' and (
|
||||
(have_track_count / float(total_track_count)) >= (
|
||||
(have_track_count / float(total_track_count)) >= (
|
||||
headphones.CONFIG.ALBUM_COMPLETION_PCT / 100.0)):
|
||||
myDB.action('UPDATE albums SET Status=? WHERE AlbumID=?',
|
||||
['Downloaded', rg['id']])
|
||||
@@ -527,7 +522,7 @@ def addArtisttoDB(artistid, extrasonly=False, forcefull=False, type="artist"):
|
||||
else:
|
||||
if skip_log == 0:
|
||||
logger.info(u"[%s] No new releases, so no changes made to %s" % (
|
||||
artist['artist_name'], rg['title']))
|
||||
artist['artist_name'], rg['title']))
|
||||
|
||||
time.sleep(3)
|
||||
finalize_update(artistid, artist['artist_name'], errors)
|
||||
@@ -541,7 +536,7 @@ def addArtisttoDB(artistid, extrasonly=False, forcefull=False, type="artist"):
|
||||
if errors:
|
||||
logger.info(
|
||||
"[%s] Finished updating artist: %s but with errors, so not marking it as updated in the database" % (
|
||||
artist['artist_name'], artist['artist_name']))
|
||||
artist['artist_name'], artist['artist_name']))
|
||||
else:
|
||||
myDB.action('DELETE FROM newartists WHERE ArtistName = ?', [artist['artist_name']])
|
||||
logger.info(u"Updating complete for: %s" % artist['artist_name'])
|
||||
|
||||
@@ -353,8 +353,8 @@ def libraryScan(dir=None, append=False, ArtistID=None, ArtistName=None,
|
||||
len(myDB.select(
|
||||
'SELECT TrackTitle from tracks WHERE ArtistName like ? AND Location IS NOT NULL',
|
||||
[artist])) + len(myDB.select(
|
||||
'SELECT TrackTitle from have WHERE ArtistName like ? AND Matched = "Failed"',
|
||||
[artist]))
|
||||
'SELECT TrackTitle from have WHERE ArtistName like ? AND Matched = "Failed"',
|
||||
[artist]))
|
||||
)
|
||||
# Note: some people complain about having "artist have tracks" > # of tracks total in artist official releases
|
||||
# (can fix by getting rid of second len statement)
|
||||
@@ -382,8 +382,8 @@ def libraryScan(dir=None, append=False, ArtistID=None, ArtistName=None,
|
||||
havetracks = len(
|
||||
myDB.select('SELECT TrackTitle from tracks WHERE ArtistID=? AND Location IS NOT NULL',
|
||||
[ArtistID])) + len(myDB.select(
|
||||
'SELECT TrackTitle from have WHERE ArtistName like ? AND Matched = "Failed"',
|
||||
[ArtistName]))
|
||||
'SELECT TrackTitle from have WHERE ArtistName like ? AND Matched = "Failed"',
|
||||
[ArtistName]))
|
||||
myDB.action('UPDATE artists SET HaveTracks=? WHERE ArtistID=?', [havetracks, ArtistID])
|
||||
|
||||
if not append:
|
||||
|
||||
@@ -287,7 +287,7 @@ def getArtist(artistid, extrasonly=False):
|
||||
except musicbrainzngs.WebServiceError as e:
|
||||
logger.warn(
|
||||
'Attempt to retrieve artist information from MusicBrainz failed for artistid: %s (%s)' % (
|
||||
artistid, str(e)))
|
||||
artistid, str(e)))
|
||||
mb_lock.snooze(5)
|
||||
except Exception as e:
|
||||
pass
|
||||
@@ -354,7 +354,7 @@ def getArtist(artistid, extrasonly=False):
|
||||
except musicbrainzngs.WebServiceError as e:
|
||||
logger.warn(
|
||||
'Attempt to retrieve artist information from MusicBrainz failed for artistid: %s (%s)' % (
|
||||
artistid, str(e)))
|
||||
artistid, str(e)))
|
||||
mb_lock.snooze(5)
|
||||
|
||||
for rg in mb_extras_list:
|
||||
@@ -384,9 +384,9 @@ def getSeries(seriesid):
|
||||
except musicbrainzngs.WebServiceError as e:
|
||||
logger.warn(
|
||||
'Attempt to retrieve series information from MusicBrainz failed for seriesid: %s (%s)' % (
|
||||
seriesid, str(e)))
|
||||
seriesid, str(e)))
|
||||
mb_lock.snooze(5)
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if not series:
|
||||
@@ -425,7 +425,7 @@ def getReleaseGroup(rgid):
|
||||
except musicbrainzngs.WebServiceError as e:
|
||||
logger.warn(
|
||||
'Attempt to retrieve information from MusicBrainz for release group "%s" failed (%s)' % (
|
||||
rgid, str(e)))
|
||||
rgid, str(e)))
|
||||
mb_lock.snooze(5)
|
||||
|
||||
if not releaseGroup:
|
||||
@@ -453,7 +453,7 @@ def getRelease(releaseid, include_artist_info=True):
|
||||
except musicbrainzngs.WebServiceError as e:
|
||||
logger.warn(
|
||||
'Attempt to retrieve information from MusicBrainz for release "%s" failed (%s)' % (
|
||||
releaseid, str(e)))
|
||||
releaseid, str(e)))
|
||||
mb_lock.snooze(5)
|
||||
|
||||
if not results:
|
||||
@@ -528,7 +528,7 @@ def get_new_releases(rgid, includeExtras=False, forcefull=False):
|
||||
except musicbrainzngs.WebServiceError as e:
|
||||
logger.warn(
|
||||
'Attempt to retrieve information from MusicBrainz for release group "%s" failed (%s)' % (
|
||||
rgid, str(e)))
|
||||
rgid, str(e)))
|
||||
mb_lock.snooze(5)
|
||||
return False
|
||||
|
||||
@@ -675,14 +675,14 @@ def get_new_releases(rgid, includeExtras=False, forcefull=False):
|
||||
num_new_releases = num_new_releases + 1
|
||||
if album_checker:
|
||||
logger.info('[%s] Existing release %s (%s) updated' % (
|
||||
release['ArtistName'], release['AlbumTitle'], rel_id_check))
|
||||
release['ArtistName'], release['AlbumTitle'], rel_id_check))
|
||||
else:
|
||||
logger.info('[%s] New release %s (%s) added' % (
|
||||
release['ArtistName'], release['AlbumTitle'], rel_id_check))
|
||||
release['ArtistName'], release['AlbumTitle'], rel_id_check))
|
||||
if force_repackage1 == 1:
|
||||
num_new_releases = -1
|
||||
logger.info('[%s] Forcing repackage of %s, since dB releases have been removed' % (
|
||||
release['ArtistName'], release_title))
|
||||
release['ArtistName'], release_title))
|
||||
else:
|
||||
num_new_releases = num_new_releases
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ class GROWL(object):
|
||||
# Split host and port
|
||||
if self.host == "":
|
||||
host, port = "localhost", 23053
|
||||
|
||||
if ":" in self.host:
|
||||
host, port = self.host.split(':', 1)
|
||||
port = int(port)
|
||||
@@ -245,9 +246,8 @@ class XBMC(object):
|
||||
for host in hosts:
|
||||
logger.info('Sending notification command to XMBC @ ' + host)
|
||||
try:
|
||||
version = \
|
||||
self._sendjson(host, 'Application.GetProperties', {'properties': ['version']})[
|
||||
'version']['major']
|
||||
version = self._sendjson(host, 'Application.GetProperties',
|
||||
{'properties': ['version']})['version']['major']
|
||||
|
||||
if version < 12: # Eden
|
||||
notification = header + "," + message + "," + time + "," + albumartpath
|
||||
@@ -383,9 +383,8 @@ class Plex(object):
|
||||
for host in hosts:
|
||||
logger.info('Sending notification command to Plex client @ ' + host)
|
||||
try:
|
||||
version = \
|
||||
self._sendjson(host, 'Application.GetProperties', {'properties': ['version']})[
|
||||
'version']['major']
|
||||
version = self._sendjson(host, 'Application.GetProperties',
|
||||
{'properties': ['version']})['version']['major']
|
||||
|
||||
if version < 12: # Eden
|
||||
notification = header + "," + message + "," + time + "," + albumartpath
|
||||
|
||||
@@ -53,7 +53,7 @@ def sendNZB(nzb):
|
||||
logger.debug(u"Successfully connected to NZBget")
|
||||
else:
|
||||
logger.info(u"Successfully connected to NZBget, but unable to send a message" % (
|
||||
nzb.name + ".nzb"))
|
||||
nzb.name + ".nzb"))
|
||||
|
||||
except httplib.socket.error:
|
||||
logger.error(
|
||||
|
||||
@@ -57,11 +57,7 @@ class PathRenderTest(TestCase):
|
||||
pattern = Pattern(u"{$Disc.}$Track - $Artist - $Title{ [$Year]")
|
||||
self.assertEqual(set([Warnings.UNCLOSED_OPTIONAL]), pattern.warnings)
|
||||
pattern = Pattern(u"{$Disc.}$Track - $Artist - $Title{ [$Year]'}")
|
||||
self.assertEqual(set([
|
||||
Warnings.UNCLOSED_ESCAPE,
|
||||
Warnings.UNCLOSED_OPTIONAL
|
||||
]),
|
||||
pattern.warnings)
|
||||
self.assertEqual(set([Warnings.UNCLOSED_ESCAPE, Warnings.UNCLOSED_OPTIONAL]), pattern.warnings)
|
||||
|
||||
def test_replacement(self):
|
||||
"""pathrender: _Replacement variable substitution"""
|
||||
|
||||
@@ -348,9 +348,8 @@ def doPostProcessing(albumid, albumpath, release, tracks, downloaded_track_list,
|
||||
f = MediaFile(downloaded_track)
|
||||
builder.add_media_file(f)
|
||||
except (FileTypeError, UnreadableFileError):
|
||||
logger.error("Track file is not a valid media file: %s. Not "
|
||||
"continuing.", downloaded_track.decode(
|
||||
headphones.SYS_ENCODING, "replace"))
|
||||
logger.error("Track file is not a valid media file: %s. Not continuing.",
|
||||
downloaded_track.decode(headphones.SYS_ENCODING, "replace"))
|
||||
return
|
||||
except IOError:
|
||||
logger.error("Unable to find media file: %s. Not continuing.")
|
||||
@@ -455,7 +454,7 @@ def doPostProcessing(albumid, albumpath, release, tracks, downloaded_track_list,
|
||||
hash = seed_snatched['FolderName']
|
||||
torrent_removed = False
|
||||
logger.info(u'%s - %s. Checking if torrent has finished seeding and can be removed' % (
|
||||
release['ArtistName'], release['AlbumTitle']))
|
||||
release['ArtistName'], release['AlbumTitle']))
|
||||
if headphones.CONFIG.TORRENT_DOWNLOADER == 1:
|
||||
torrent_removed = transmission.removeTorrent(hash, True)
|
||||
elif headphones.CONFIG.TORRENT_DOWNLOADER == 3: # Deluge
|
||||
@@ -603,7 +602,7 @@ def embedAlbumArt(artwork, downloaded_track_list):
|
||||
f.save()
|
||||
except Exception as e:
|
||||
logger.error(u'Error embedding album art to: %s. Error: %s' % (
|
||||
downloaded_track.decode(headphones.SYS_ENCODING, 'replace'), str(e)))
|
||||
downloaded_track.decode(headphones.SYS_ENCODING, 'replace'), str(e)))
|
||||
continue
|
||||
|
||||
|
||||
@@ -647,7 +646,7 @@ def cleanupFiles(albumpath):
|
||||
os.remove(os.path.join(r, files))
|
||||
except Exception as e:
|
||||
logger.error(u'Could not remove file: %s. Error: %s' % (
|
||||
files.decode(headphones.SYS_ENCODING, 'replace'), e))
|
||||
files.decode(headphones.SYS_ENCODING, 'replace'), e))
|
||||
|
||||
|
||||
def renameNFO(albumpath):
|
||||
@@ -657,14 +656,14 @@ def renameNFO(albumpath):
|
||||
for file in f:
|
||||
if file.lower().endswith('.nfo'):
|
||||
logger.debug('Renaming: "%s" to "%s"' % (
|
||||
file.decode(headphones.SYS_ENCODING, 'replace'),
|
||||
file.decode(headphones.SYS_ENCODING, 'replace') + '-orig'))
|
||||
file.decode(headphones.SYS_ENCODING, 'replace'),
|
||||
file.decode(headphones.SYS_ENCODING, 'replace') + '-orig'))
|
||||
try:
|
||||
new_file_name = os.path.join(r, file)[:-3] + 'orig.nfo'
|
||||
os.rename(os.path.join(r, file), new_file_name)
|
||||
except Exception as e:
|
||||
logger.error(u'Could not rename file: %s. Error: %s' % (
|
||||
os.path.join(r, file).decode(headphones.SYS_ENCODING, 'replace'), e))
|
||||
os.path.join(r, file).decode(headphones.SYS_ENCODING, 'replace'), e))
|
||||
|
||||
|
||||
def moveFiles(albumpath, release, metadata_dict):
|
||||
@@ -736,7 +735,7 @@ def moveFiles(albumpath, release, metadata_dict):
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
"Error deleting existing folder: %s. Creating duplicate folder. Error: %s" % (
|
||||
lossless_destination_path.decode(headphones.SYS_ENCODING, 'replace'), e))
|
||||
lossless_destination_path.decode(headphones.SYS_ENCODING, 'replace'), e))
|
||||
create_duplicate_folder = True
|
||||
|
||||
if not headphones.CONFIG.REPLACE_EXISTING_FOLDERS or create_duplicate_folder:
|
||||
@@ -759,7 +758,7 @@ def moveFiles(albumpath, release, metadata_dict):
|
||||
os.makedirs(lossless_destination_path)
|
||||
except Exception as e:
|
||||
logger.error('Could not create lossless folder for %s. (Error: %s)' % (
|
||||
release['AlbumTitle'], e))
|
||||
release['AlbumTitle'], e))
|
||||
if not make_lossy_folder:
|
||||
return [albumpath]
|
||||
|
||||
@@ -774,7 +773,7 @@ def moveFiles(albumpath, release, metadata_dict):
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
"Error deleting existing folder: %s. Creating duplicate folder. Error: %s" % (
|
||||
lossy_destination_path.decode(headphones.SYS_ENCODING, 'replace'), e))
|
||||
lossy_destination_path.decode(headphones.SYS_ENCODING, 'replace'), e))
|
||||
create_duplicate_folder = True
|
||||
|
||||
if not headphones.CONFIG.REPLACE_EXISTING_FOLDERS or create_duplicate_folder:
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
import urllib
|
||||
import time
|
||||
from urlparse import urlparse
|
||||
|
||||
import re
|
||||
|
||||
import requests as requests
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
import headphones
|
||||
from headphones import logger
|
||||
|
||||
@@ -69,7 +70,6 @@ class Rutracker(object):
|
||||
"""
|
||||
Return the search url
|
||||
"""
|
||||
|
||||
# Build search url
|
||||
searchterm = ''
|
||||
if artist != 'Various Artists':
|
||||
@@ -91,22 +91,17 @@ class Rutracker(object):
|
||||
|
||||
# sort by size, descending.
|
||||
sort = '&o=7&s=2'
|
||||
|
||||
searchurl = "%s?nm=%s%s%s" % (self.search_referer, urllib.quote(searchterm), format, sort)
|
||||
|
||||
logger.info("Searching rutracker using term: %s", searchterm)
|
||||
|
||||
return searchurl
|
||||
|
||||
def search(self, searchurl):
|
||||
"""
|
||||
Parse the search results and return valid torrent list
|
||||
"""
|
||||
|
||||
try:
|
||||
headers = {'Referer': self.search_referer}
|
||||
r = self.session.get(url=searchurl, headers=headers, timeout=self.timeout)
|
||||
|
||||
soup = BeautifulSoup(r.content, 'html5lib')
|
||||
|
||||
# Debug
|
||||
@@ -155,9 +150,8 @@ class Rutracker(object):
|
||||
topicurl = 'http://rutracker.org/forum/viewtopic.php?t=' + torrent_id
|
||||
rulist.append((title, size, topicurl, 'rutracker.org', 'torrent', True))
|
||||
else:
|
||||
logger.info(
|
||||
"%s is larger than the maxsize or has too little seeders for this category, skipping. (Size: %i bytes, Seeders: %i)" % (
|
||||
title, size, int(seeds)))
|
||||
logger.info("%s is larger than the maxsize or has too little seeders for this category, "
|
||||
"skipping. (Size: %i bytes, Seeders: %i)" % (title, size, int(seeds)))
|
||||
|
||||
if not rulist:
|
||||
logger.info("No valid results found from rutracker")
|
||||
@@ -172,7 +166,6 @@ class Rutracker(object):
|
||||
"""
|
||||
return the .torrent data
|
||||
"""
|
||||
|
||||
torrent_id = dict([part.split('=') for part in urlparse(url)[4].split('&')])['t']
|
||||
downloadurl = 'http://dl.rutracker.org/forum/dl.php?t=' + torrent_id
|
||||
cookie = {'bb_dl': torrent_id}
|
||||
@@ -187,7 +180,6 @@ class Rutracker(object):
|
||||
|
||||
# TODO get this working in utorrent.py
|
||||
def utorrent_add_file(self, data):
|
||||
|
||||
host = headphones.CONFIG.UTORRENT_HOST
|
||||
if not host.startswith('http'):
|
||||
host = 'http://' + host
|
||||
@@ -197,10 +189,8 @@ class Rutracker(object):
|
||||
host = host[:-4]
|
||||
|
||||
base_url = host
|
||||
|
||||
url = base_url + '/gui/'
|
||||
self.session.auth = (
|
||||
headphones.CONFIG.UTORRENT_USERNAME, headphones.CONFIG.UTORRENT_PASSWORD)
|
||||
self.session.auth = (headphones.CONFIG.UTORRENT_USERNAME, headphones.CONFIG.UTORRENT_PASSWORD)
|
||||
|
||||
try:
|
||||
r = self.session.get(url + 'token.html')
|
||||
|
||||
@@ -208,7 +208,7 @@ def searchforalbum(albumid=None, new=False, losslessOnly=False,
|
||||
|
||||
if release_date > datetime.datetime.today():
|
||||
logger.info("Skipping: %s. Waiting for release date of: %s" % (
|
||||
album['AlbumTitle'], album['ReleaseDate']))
|
||||
album['AlbumTitle'], album['ReleaseDate']))
|
||||
continue
|
||||
|
||||
new = True
|
||||
@@ -217,7 +217,7 @@ def searchforalbum(albumid=None, new=False, losslessOnly=False,
|
||||
losslessOnly = True
|
||||
|
||||
logger.info('Searching for "%s - %s" since it is marked as wanted' % (
|
||||
album['ArtistName'], album['AlbumTitle']))
|
||||
album['ArtistName'], album['AlbumTitle']))
|
||||
do_sorted_search(album, new, losslessOnly)
|
||||
|
||||
elif albumid and choose_specific_download:
|
||||
@@ -229,24 +229,36 @@ def searchforalbum(albumid=None, new=False, losslessOnly=False,
|
||||
else:
|
||||
album = myDB.action('SELECT * from albums WHERE AlbumID=?', [albumid]).fetchone()
|
||||
logger.info('Searching for "%s - %s" since it was marked as wanted' % (
|
||||
album['ArtistName'], album['AlbumTitle']))
|
||||
album['ArtistName'], album['AlbumTitle']))
|
||||
do_sorted_search(album, new, losslessOnly)
|
||||
|
||||
logger.info('Search for wanted albums complete')
|
||||
|
||||
|
||||
def do_sorted_search(album, new, losslessOnly, choose_specific_download=False):
|
||||
NZB_PROVIDERS = (
|
||||
headphones.CONFIG.HEADPHONES_INDEXER or headphones.CONFIG.NEWZNAB or headphones.CONFIG.NZBSORG or headphones.CONFIG.OMGWTFNZBS)
|
||||
NZB_DOWNLOADERS = (
|
||||
headphones.CONFIG.SAB_HOST or headphones.CONFIG.BLACKHOLE_DIR or headphones.CONFIG.NZBGET_HOST)
|
||||
TORRENT_PROVIDERS = (
|
||||
headphones.CONFIG.TORZNAB or headphones.CONFIG.KAT or headphones.CONFIG.PIRATEBAY or headphones.CONFIG.OLDPIRATEBAY or headphones.CONFIG.MININOVA or headphones.CONFIG.WAFFLES or headphones.CONFIG.RUTRACKER or headphones.CONFIG.WHATCD or headphones.CONFIG.STRIKE)
|
||||
NZB_PROVIDERS = (headphones.CONFIG.HEADPHONES_INDEXER or
|
||||
headphones.CONFIG.NEWZNAB or
|
||||
headphones.CONFIG.NZBSORG or
|
||||
headphones.CONFIG.OMGWTFNZBS)
|
||||
|
||||
NZB_DOWNLOADERS = (headphones.CONFIG.SAB_HOST or
|
||||
headphones.CONFIG.BLACKHOLE_DIR or
|
||||
headphones.CONFIG.NZBGET_HOST)
|
||||
|
||||
TORRENT_PROVIDERS = (headphones.CONFIG.TORZNAB or
|
||||
headphones.CONFIG.KAT or
|
||||
headphones.CONFIG.PIRATEBAY or
|
||||
headphones.CONFIG.OLDPIRATEBAY or
|
||||
headphones.CONFIG.MININOVA or
|
||||
headphones.CONFIG.WAFFLES or
|
||||
headphones.CONFIG.RUTRACKER or
|
||||
headphones.CONFIG.WHATCD or
|
||||
headphones.CONFIG.STRIKE)
|
||||
|
||||
results = []
|
||||
myDB = db.DBConnection()
|
||||
albumlength = \
|
||||
myDB.select('SELECT sum(TrackDuration) from tracks WHERE AlbumID=?', [album['AlbumID']])[0][0]
|
||||
albumlength = myDB.select('SELECT sum(TrackDuration) from tracks WHERE AlbumID=?',
|
||||
[album['AlbumID']])[0][0]
|
||||
|
||||
if headphones.CONFIG.PREFER_TORRENTS == 0 and not choose_specific_download:
|
||||
|
||||
@@ -407,7 +419,7 @@ def sort_search_results(resultlist, album, new, albumlength):
|
||||
|
||||
if not targetsize:
|
||||
logger.info('No track information for %s - %s. Defaulting to highest quality' % (
|
||||
album['ArtistName'], album['AlbumTitle']))
|
||||
album['ArtistName'], album['AlbumTitle']))
|
||||
finallist = sorted(resultlist, key=lambda title: (title[5], int(title[1])),
|
||||
reverse=True)
|
||||
|
||||
@@ -790,9 +802,9 @@ def send_to_downloader(data, bestqual, album):
|
||||
return
|
||||
else:
|
||||
folder_name = '%s - %s [%s]' % (
|
||||
helpers.latinToAscii(album['ArtistName']).encode('UTF-8').replace('/', '_'),
|
||||
helpers.latinToAscii(album['AlbumTitle']).encode('UTF-8').replace('/', '_'),
|
||||
get_year_from_release_date(album['ReleaseDate']))
|
||||
helpers.latinToAscii(album['ArtistName']).encode('UTF-8').replace('/', '_'),
|
||||
helpers.latinToAscii(album['AlbumTitle']).encode('UTF-8').replace('/', '_'),
|
||||
get_year_from_release_date(album['ReleaseDate']))
|
||||
|
||||
# Blackhole
|
||||
if headphones.CONFIG.TORRENT_DOWNLOADER == 0:
|
||||
@@ -1463,7 +1475,7 @@ def searchTorrent(album, new=False, losslessOnly=False, albumlength=None,
|
||||
except Exception as e:
|
||||
gazelle = None
|
||||
logger.error(u"What.cd credentials incorrect or site is down. Error: %s %s" % (
|
||||
e.__class__.__name__, str(e)))
|
||||
e.__class__.__name__, str(e)))
|
||||
|
||||
if gazelle and gazelle.logged_in():
|
||||
logger.info(u"Searching %s..." % provider)
|
||||
@@ -1588,9 +1600,8 @@ def searchTorrent(album, new=False, losslessOnly=False, albumlength=None,
|
||||
logger.info('Found %s. Size: %s' % (title, formatted_size))
|
||||
else:
|
||||
match = False
|
||||
logger.info(
|
||||
'%s is larger than the maxsize or has too little seeders for this category, skipping. (Size: %i bytes, Seeders: %i)' % (
|
||||
title, size, int(seeds)))
|
||||
logger.info('%s is larger than the maxsize or has too little seeders for this category, '
|
||||
'skipping. (Size: %i bytes, Seeders: %i)' % (title, size, int(seeds)))
|
||||
|
||||
resultlist.append((title, size, url, provider, "torrent", match))
|
||||
except Exception as e:
|
||||
@@ -1644,9 +1655,8 @@ def searchTorrent(album, new=False, losslessOnly=False, albumlength=None,
|
||||
logger.info('Found %s. Size: %s' % (title, formatted_size))
|
||||
else:
|
||||
match = False
|
||||
logger.info(
|
||||
'%s is larger than the maxsize or has too little seeders for this category, skipping. (Size: %i bytes, Seeders: %i)' % (
|
||||
title, size, int(seeds)))
|
||||
logger.info('%s is larger than the maxsize or has too little seeders for this category, '
|
||||
'skipping. (Size: %i bytes, Seeders: %i)' % (title, size, int(seeds)))
|
||||
|
||||
resultlist.append((title, size, url, provider, "torrent", match))
|
||||
except Exception as e:
|
||||
@@ -1746,9 +1756,9 @@ def searchTorrent(album, new=False, losslessOnly=False, albumlength=None,
|
||||
logger.info('Found %s. Size: %s' % (title, helpers.bytes_to_mb(size)))
|
||||
else:
|
||||
match = False
|
||||
logger.info(
|
||||
'%s is larger than the maxsize, the wrong format or has too little seeders for this category, skipping. (Size: %i bytes, Seeders: %i, Format: %s)' % (
|
||||
title, size, int(seeds), rightformat))
|
||||
logger.info('%s is larger than the maxsize, the wrong format or has too little seeders'
|
||||
' for this category, skipping. (Size: %i bytes, Seeders: %i, Format: %s)' % (
|
||||
title, size, int(seeds), rightformat))
|
||||
|
||||
resultlist.append((title, size, url, provider, 'torrent', match))
|
||||
except Exception as e:
|
||||
@@ -1757,8 +1767,7 @@ def searchTorrent(album, new=False, losslessOnly=False, albumlength=None,
|
||||
# attempt to verify that this isn't a substring result
|
||||
# when looking for "Foo - Foo" we don't want "Foobar"
|
||||
# this should be less of an issue when it isn't a self-titled album so we'll only check vs artist
|
||||
results = [result for result in resultlist if
|
||||
verifyresult(result[0], artistterm, term, losslessOnly)]
|
||||
results = [result for result in resultlist if verifyresult(result[0], artistterm, term, losslessOnly)]
|
||||
|
||||
# Additional filtering for size etc
|
||||
if results and not choose_specific_download:
|
||||
@@ -1806,7 +1815,7 @@ def preprocess(resultlist):
|
||||
headers = {'User-Agent': USER_AGENT}
|
||||
|
||||
if result[3] == 'headphones':
|
||||
return request.request_content(url=result[2], headers=headers, auth=(
|
||||
headphones.CONFIG.HPUSER, headphones.CONFIG.HPPASS)), result
|
||||
return request.request_content(url=result[2], headers=headers,
|
||||
auth=(headphones.CONFIG.HPUSER, headphones.CONFIG.HPPASS)), result
|
||||
else:
|
||||
return request.request_content(url=result[2], headers=headers), result
|
||||
|
||||
@@ -124,7 +124,7 @@ def checkGithub():
|
||||
# Get the latest version available from github
|
||||
logger.info('Retrieving latest version information from GitHub')
|
||||
url = 'https://api.github.com/repos/%s/headphones/commits/%s' % (
|
||||
headphones.CONFIG.GIT_USER, headphones.CONFIG.GIT_BRANCH)
|
||||
headphones.CONFIG.GIT_USER, headphones.CONFIG.GIT_BRANCH)
|
||||
version = request.request_json(url, timeout=20, validator=lambda x: type(x) == dict)
|
||||
|
||||
if version is None:
|
||||
@@ -147,7 +147,7 @@ def checkGithub():
|
||||
|
||||
logger.info('Comparing currently installed version with latest GitHub version')
|
||||
url = 'https://api.github.com/repos/%s/headphones/compare/%s...%s' % (
|
||||
headphones.CONFIG.GIT_USER, headphones.LATEST_VERSION, headphones.CURRENT_VERSION)
|
||||
headphones.CONFIG.GIT_USER, headphones.LATEST_VERSION, headphones.CURRENT_VERSION)
|
||||
commits = request.request_json(url, timeout=20, whitelist_status_code=404,
|
||||
validator=lambda x: type(x) == dict)
|
||||
|
||||
@@ -192,7 +192,7 @@ def update():
|
||||
|
||||
else:
|
||||
tar_download_url = 'https://github.com/%s/headphones/tarball/%s' % (
|
||||
headphones.CONFIG.GIT_USER, headphones.CONFIG.GIT_BRANCH)
|
||||
headphones.CONFIG.GIT_USER, headphones.CONFIG.GIT_BRANCH)
|
||||
update_dir = os.path.join(headphones.PROG_DIR, 'update')
|
||||
version_path = os.path.join(headphones.PROG_DIR, 'version.txt')
|
||||
|
||||
|
||||
@@ -281,8 +281,7 @@ class WebInterface(object):
|
||||
def scanArtist(self, ArtistID):
|
||||
|
||||
myDB = db.DBConnection()
|
||||
artist_name = \
|
||||
myDB.select('SELECT DISTINCT ArtistName FROM artists WHERE ArtistID=?', [ArtistID])[0][0]
|
||||
artist_name = myDB.select('SELECT DISTINCT ArtistName FROM artists WHERE ArtistID=?', [ArtistID])[0][0]
|
||||
|
||||
logger.info(u"Scanning artist: %s", artist_name)
|
||||
|
||||
@@ -292,8 +291,7 @@ class WebInterface(object):
|
||||
acceptable_formats = ["$artist", "$sortartist", "$first/$artist", "$first/$sortartist"]
|
||||
|
||||
if not folder_format.lower() in acceptable_formats:
|
||||
logger.info(
|
||||
"Can't determine the artist folder from the configured folder_format. Not scanning")
|
||||
logger.info("Can't determine the artist folder from the configured folder_format. Not scanning")
|
||||
return
|
||||
|
||||
# Format the folder to match the settings
|
||||
@@ -388,8 +386,7 @@ class WebInterface(object):
|
||||
if ArtistID:
|
||||
ArtistIDT = ArtistID
|
||||
else:
|
||||
ArtistIDT = \
|
||||
myDB.action('SELECT ArtistID FROM albums WHERE AlbumID=?', [mbid]).fetchone()[0]
|
||||
ArtistIDT = myDB.action('SELECT ArtistID FROM albums WHERE AlbumID=?', [mbid]).fetchone()[0]
|
||||
myDB.action(
|
||||
'UPDATE artists SET TotalTracks=(SELECT COUNT(*) FROM tracks WHERE ArtistID = ? AND AlbumTitle IN (SELECT AlbumTitle FROM albums WHERE Status != "Ignored")) WHERE ArtistID = ?',
|
||||
[ArtistIDT, ArtistIDT])
|
||||
@@ -661,8 +658,7 @@ class WebInterface(object):
|
||||
# This was throwing errors and I don't know why, but it seems to be working fine.
|
||||
# else:
|
||||
# logger.info("There was an error modifying Artist %s. This should not have happened" % existing_artist)
|
||||
logger.info("Manual matching yielded %s new matches for Artist: %s" % (
|
||||
update_count, new_artist))
|
||||
logger.info("Manual matching yielded %s new matches for Artist: %s" % (update_count, new_artist))
|
||||
if update_count > 0:
|
||||
librarysync.update_album_status()
|
||||
else:
|
||||
@@ -714,13 +710,13 @@ class WebInterface(object):
|
||||
# else:
|
||||
# logger.info("There was an error modifying Artist %s / Album %s with clean name %s" % (existing_artist, existing_album, existing_clean_string))
|
||||
logger.info("Manual matching yielded %s new matches for Artist: %s / Album: %s" % (
|
||||
update_count, new_artist, new_album))
|
||||
update_count, new_artist, new_album))
|
||||
if update_count > 0:
|
||||
librarysync.update_album_status(album_id)
|
||||
else:
|
||||
logger.info(
|
||||
"Artist %s / Album %s already named appropriately; nothing to modify" % (
|
||||
existing_artist, existing_album))
|
||||
existing_artist, existing_album))
|
||||
|
||||
@cherrypy.expose
|
||||
def manageManual(self):
|
||||
@@ -992,14 +988,14 @@ class WebInterface(object):
|
||||
totalcount = len(filtered)
|
||||
else:
|
||||
query = 'SELECT * from artists WHERE ArtistSortName LIKE "%' + sSearch + '%" OR LatestAlbum LIKE "%' + sSearch + '%"' + 'ORDER BY %s COLLATE NOCASE %s' % (
|
||||
sortcolumn, sSortDir_0)
|
||||
sortcolumn, sSortDir_0)
|
||||
filtered = myDB.select(query)
|
||||
totalcount = myDB.select('SELECT COUNT(*) from artists')[0][0]
|
||||
|
||||
if sortbyhavepercent:
|
||||
filtered.sort(key=lambda x: (
|
||||
float(x['HaveTracks']) / x['TotalTracks'] if x['TotalTracks'] > 0 else 0.0,
|
||||
x['HaveTracks'] if x['HaveTracks'] else 0.0), reverse=sSortDir_0 == "asc")
|
||||
float(x['HaveTracks']) / x['TotalTracks'] if x['TotalTracks'] > 0 else 0.0,
|
||||
x['HaveTracks'] if x['HaveTracks'] else 0.0), reverse=sSortDir_0 == "asc")
|
||||
|
||||
# can't figure out how to change the datatables default sorting order when its using an ajax datasource so ill
|
||||
# just reverse it here and the first click on the "Latest Album" header will sort by descending release date
|
||||
|
||||
Reference in New Issue
Block a user