Merge branch 'develop'

This commit is contained in:
Remy
2011-08-08 20:29:29 -07:00
11 changed files with 137 additions and 105 deletions

View File

@@ -138,8 +138,8 @@ div#main { margin: 0; padding: 80px 0 0 0; }
.table_wrapper_right{ padding: 25px; background-color: #ffffff; width: 40%; min-height: 100px; margin-top: 25px; margin-left: auto; margin-right: 30px; -moz-border-radius: 20px; border-radius: 20px; }
.configtable { font-size: 14px; line-height:18px; }
.configtable td { width: 350px; padding: 10px; vertical-align: middle; }
.configtable tr { vertical-align: text-top; }
.configtable td { width: 350px; padding: 10px; }
.configtable td#middle { vertical-align: middle; }
table#artist_table { background-color: white; width: 100%; padding: 20px; }

View File

@@ -9,11 +9,11 @@
<ul id="subhead_menu">
%if album['Status'] == 'Skipped':
<li><a href="queueAlbum?AlbumID=${album['AlbumID']}&ArtistID=${album['ArtistID']}&new=False">Mark Album as Wanted</a></li>
%elif album['Status'] == 'Snatched' or 'Downloaded':
%elif album['Status'] == 'Wanted':
<li><a href="unqueueAlbum?AlbumID=${album['AlbumID']}&ArtistID=${album['ArtistID']}&new=False">Mark Album as Skipped</a></li>
%else:
<li><a href="queueAlbum?AlbumID=${album['AlbumID']}&ArtistID=${album['ArtistID']}&new=False">Retry Download</a></li>
<li><a href="queueAlbum?AlbumID=${album['AlbumID']}&ArtistID=${album['ArtistID']}&new=True">Try New Version</a></li>
%else:
<li><a href="unqueueAlbum?AlbumID=${album['AlbumID']}&ArtistID=${album['ArtistID']}&new=False">Mark Album as Skipped</a></li>
%endif
</ul>
</div>

View File

@@ -109,7 +109,7 @@
<a name="providers"><h1><u>Search Providers</u></h1></a>
<table class="configtable" summary="Search Providers">
<tr>
<td>
<td id="middle">
<h3>NZBMatrix: <input type="checkbox" name="nzbmatrix" value="1" ${config['use_nzbmatrix']} /></h3>
</td>
@@ -125,61 +125,55 @@
</tr>
<tr>
<td>
<td id="middle">
<h3>Newznab: <input type="checkbox" name="newznab" value="1" ${config['use_newznab']} /></h3>
</td>
<td>
<h3>Newznab Host:</h3>
<h3>Newznab Host: </h3>
<input type="text" name="newznab_host" value="${config['newznab_host']}" size="30" maxlength="40"><br>
<i class="smalltext">i.e. http://nzb.su</i>
</td>
<td>
<h3>
Newznab API:</h3>
<h3>Newznab API: </h3>
<input type="text" name="newznab_apikey" value="${config['newznab_api']}" size="36" maxlength="40">
</td>
</tr>
<tr>
<td>
<h3>NZBs.org:<input type="checkbox" name="nzbsorg" value="1" ${config['use_nzbsorg']} /></h3>
<td id="middle">
<h3>NZBs.org: <input type="checkbox" name="nzbsorg" value="1" ${config['use_nzbsorg']} /></h3>
</td>
<td>
<h3>NZBs.org UID:</h3>
<h3>NZBs.org UID: </h3>
<input type="text" name="nzbsorg_uid" value="${config['nzbsorg_uid']}" size="30" maxlength="40">
</td>
<td>
<h3>NZBs.org Hash:</h3>
<h3>NZBs.org Hash: </h3>
<input type="text" name="nzbsorg_hash" value="${config['nzbsorg_hash']}" size="36" maxlength="40">
</td>
</tr>
<tr>
<td>
<h3>Newzbin:<input type="checkbox" name="newzbin" value="1" ${config['use_newzbin']} /></h3>
<td id="middle">
<h3>Newzbin: <input type="checkbox" name="newzbin" value="1" ${config['use_newzbin']} /></h3>
</td>
<td>
<h3>Newzbin UID:</h3>
<h3>Newzbin UID: </h3>
<input type="text" name="newzbin_uid" value="${config['newzbin_uid']}" size="30" maxlength="40">
</td>
<td>
<br>
<h3>Newzbin Password:</h3>
<h3>Newzbin Password: </h3>
<input type="text" name="newzbin_password" value="${config['newzbin_pass']}" size="36" maxlength="40">
</td>
</tr>
@@ -192,21 +186,21 @@
<tr>
<td>
<h2>Album Quality:</h2><br>
<input type="radio" name="preferred_quality" value="0" ${config['pref_qual_0']} />Highest Quality excluding Lossless<br>
<input type="radio" name="preferred_quality" value="1" ${config['pref_qual_1']} />Highest Quality including Lossless<br>
<input type="radio" name="preferred_quality" value="3" ${config['pref_qual_3']} />Lossless Only<br>
<input type="radio" name="preferred_quality" value="2" ${config['pref_qual_2']} />Preferred Bitrate:
<input type="radio" name="preferred_quality" value="0" ${config['pref_qual_0']} /> Highest Quality excluding Lossless<br>
<input type="radio" name="preferred_quality" value="1" ${config['pref_qual_1']} /> Highest Quality including Lossless<br>
<input type="radio" name="preferred_quality" value="3" ${config['pref_qual_3']} /> Lossless Only<br>
<input type="radio" name="preferred_quality" value="2" ${config['pref_qual_2']} /> Preferred Bitrate:
<input type="text" name="preferred_bitrate" value="${config['pref_bitrate']}" size="5" maxlength="5" />kbps <br>
<i class="smalltext2"><input type="checkbox" name="detect_bitrate" value="1" ${config['detect_bitrate']} />Auto-Detect Preferred Bitrate </i>
</td>
<td>
<h2>Post-Processing:</h2>
<input type="checkbox" name="move_files" value="1" ${config['move_files']} />Move downloads to Destination Folder<br />
<input type="checkbox" name="rename_files" value="1" ${config['rename_files']} />Rename files<br>
<input type="checkbox" name="correct_metadata" value="1" ${config['correct_metadata']} />Correct metadata<br>
<input type="checkbox" name="cleanup_files" value="1" ${config['cleanup_files']} />Delete leftover files (.m3u, .nfo, .sfv, .nzb, etc.)<br>
<input type="checkbox" name="add_album_art" value="1" ${config['add_album_art']}>Add album art as 'folder.jpg' to album folder<br>
<input type="checkbox" name="embed_album_art" value="1" ${config['embed_album_art']}>Embed album art in each file
<input type="checkbox" name="move_files" value="1" ${config['move_files']} /> Move downloads to Destination Folder<br />
<input type="checkbox" name="rename_files" value="1" ${config['rename_files']} /> Rename files<br>
<input type="checkbox" name="correct_metadata" value="1" ${config['correct_metadata']} /> Correct metadata<br>
<input type="checkbox" name="cleanup_files" value="1" ${config['cleanup_files']} /> Delete leftover files (.m3u, .nfo, .sfv, .nzb, etc.)<br>
<input type="checkbox" name="add_album_art" value="1" ${config['add_album_art']}> Add album art as 'folder.jpg' to album folder<br>
<input type="checkbox" name="embed_album_art" value="1" ${config['embed_album_art']}> Embed album art in each file
</td>
</tr>
@@ -242,7 +236,7 @@
<br>
<h3><input type="checkbox" name="include_extras" value="1" ${config['include_extras']} />Automatically Include Extras When Adding an Artist</h3><br />
<i class="smalltext">Extras includes: EPs, Compilations, Live Albums, Remix Albums and Singles</i>
<br><br><br>
<br><br>
<h3>Log Directory:</h3><input type="text" name="log_dir" value="${config['log_dir']}" size="50">
</td>
</tr>
@@ -253,4 +247,3 @@
(Web Interface changes require a restart to take effect)</h3>
</form>
</%def>
<%inherit file="base.html" />

View File

@@ -57,6 +57,7 @@
"bStateSave": true,
"iDisplayLength": 100,
"sPaginationType": "full_numbers",
"aaSorting": []
});
});

View File

@@ -99,6 +99,7 @@ NEWZBIN_PASSWORD = None
LASTFM_USERNAME = None
MEDIA_FORMATS = ["mp3", "flac", "aac", "ogg", "ape", "m4a"]
def CheckSection(sec):
""" Check if INI section exists, if not create it """

View File

@@ -24,7 +24,7 @@ def scanMusic(dir=None):
for r,d,f in os.walk(dir):
for files in f:
if any(files.endswith(x) for x in (".mp3", ".flac", ".aac", ".ogg", ".ape", ".m4a")):
if any(files.endswith('.' + x) for x in headphones.MEDIA_FORMATS):
results.append(os.path.join(r, files))
logger.info(u'%i music files found. Reading metadata....' % len(results))
@@ -96,7 +96,7 @@ def is_exists(artistid):
artistlist = myDB.select('SELECT ArtistID, ArtistName from artists WHERE ArtistID=?', [artistid])
if any(artistid in x for x in artistlist):
logger.info(artistlist[0][1] + u" is already in the database. Updating 'have tracks', but not artist information")
logger.debug(artistlist[0][1] + u" is already in the database. Updating 'have tracks', but not artist information")
return True
else:
return False
@@ -215,7 +215,7 @@ def addArtisttoDB(artistid, extrasonly=False):
myDB.upsert("albums", newValueDict, controlValueDict)
lastfm.getAlbumDescription(rg['id'], release_dict['releaselist'])
lastfm.getAlbumDescription(rg['id'], artist['artist_name'], rg['title'])
# I changed the albumid from releaseid -> rgid, so might need to delete albums that have a releaseid
for release in release_dict['releaselist']:

View File

@@ -91,7 +91,52 @@ def getArtists():
for artistid in artistlist:
importer.addArtisttoDB(artistid)
def getAlbumDescription(rgid, releaselist):
def getAlbumDescription(rgid, artist, album):
myDB = db.DBConnection()
result = myDB.select('SELECT Summary from descriptions WHERE ReleaseGroupID=?', [rgid])
if result:
return
params = { "method": 'album.getInfo',
"api_key": api_key,
"artist": artist.encode('utf-8'),
"album": album.encode('utf-8')
}
searchURL = 'http://ws.audioscrobbler.com/2.0/?' + urllib.urlencode(params)
data = urllib.urlopen(searchURL).read()
if data == '<?xml version="1.0" encoding="utf-8"?><lfm status="failed"><error code="6">Album not found</error></lfm>':
return
try:
d = minidom.parseString(data)
albuminfo = d.getElementsByTagName("album")
for item in albuminfo:
summarynode = item.getElementsByTagName("summary")[0].childNodes
contentnode = item.getElementsByTagName("content")[0].childNodes
for node in summarynode:
summary = node.data
for node in contentnode:
content = node.data
controlValueDict = {'ReleaseGroupID': rgid}
newValueDict = {'Summary': summary,
'Content': content}
myDB.upsert("descriptions", newValueDict, controlValueDict)
except:
return
def getAlbumDescriptionOld(rgid, releaselist):
"""
This was a dumb way to do it - going to just use artist & album name but keeping this here
because I may use it to fetch and cache album art
"""
myDB = db.DBConnection()
result = myDB.select('SELECT Summary from descriptions WHERE ReleaseGroupID=?', [rgid])

View File

@@ -306,7 +306,7 @@ def getReleaseGroup(rgid):
releaselist.append(release_dict)
average_tracks = sum(x['trackscount'] for x in releaselist) / len(releaselist)
average_tracks = sum(x['trackscount'] for x in releaselist) / float(len(releaselist))
for item in releaselist:
item['trackscount_delta'] = abs(average_tracks - item['trackscount'])

View File

@@ -113,7 +113,7 @@ def verify(albumid, albumpath):
downloaded_track_list = []
for r,d,f in os.walk(albumpath):
for files in f:
if any(files.endswith(x) for x in (".mp3", ".flac", ".aac", ".ogg", ".ape", ".m4a")):
if any(files.endswith('.' + x) for x in headphones.MEDIA_FORMATS):
downloaded_track_list.append(os.path.join(r, files))
# test #1: metadata - usually works
@@ -240,7 +240,7 @@ def cleanupFiles(albumpath):
logger.info('Cleaning up files')
for r,d,f in os.walk(albumpath):
for files in f:
if not any(files.endswith(x) for x in (".mp3", ".flac", ".aac", ".ogg", ".ape", ".m4a")):
if not any(files.endswith('.' + x) for x in headphones.MEDIA_FORMATS):
logger.debug('Removing: %s' % files)
try:
os.remove(os.path.join(r, files))
@@ -393,7 +393,7 @@ def updateHave(albumpath):
for r,d,f in os.walk(albumpath):
for files in f:
if any(files.endswith(x) for x in (".mp3", ".flac", ".aac", ".ogg", ".ape")):
if any(files.endswith('.' + x) for x in headphones.MEDIA_FORMATS):
results.append(os.path.join(r, files))
if results:

View File

@@ -67,10 +67,6 @@ def sendNZB(nzb):
url = "http://" + headphones.SAB_HOST + "/" + "api?" + urllib.urlencode(params)
logger.info(u"Sending NZB to SABnzbd")
logger.info(u"URL: " + url)
try:
if nzb.resultType == "nzb":

View File

@@ -398,74 +398,32 @@ def searchNZB(albumid=None, new=False):
else:
bestqual = nzblist[0]
logger.info(u'Found best result: <a href="%s">%s</a> - %s' % (bestqual[2], bestqual[0], helpers.bytes_to_mb(bestqual[1])))
if bestqual[3] == "newzbin":
#logger.info("Found a newzbin result")
reportid = bestqual[2]
params = urllib.urlencode({"username": headphones.NEWZBIN_UID, "password": headphones.NEWZBIN_PASSWORD, "reportid": reportid})
url = providerurl + "/api/dnzb/"
urllib._urlopener = NewzbinDownloader()
data = urllib.urlopen(url, data=params).read()
nzb = classes.NZBDataSearchResult()
nzb.extraInfo.append(data)
nzb_folder_name = '%s - %s [%s]' % (helpers.latinToAscii(albums[0]).encode('UTF-8').replace('/', '_'), helpers.latinToAscii(albums[1]).encode('UTF-8').replace('/', '_'), year)
nzb.name = nzb_folder_name
logger.info(u"Sending FILE to SABNZBD: " + nzb.name)
sab.sendNZB(nzb)
myDB.action('UPDATE albums SET status = "Snatched" WHERE AlbumID=?', [albums[2]])
myDB.action('INSERT INTO snatched VALUES( ?, ?, ?, ?, DATETIME("NOW", "localtime"), ?, ?)', [albums[2], bestqual[0], bestqual[1], bestqual[2], "Snatched", nzb_folder_name])
else:
downloadurl = bestqual[2]
nzb_folder_name = '%s - %s [%s]' % (helpers.latinToAscii(albums[0]).encode('UTF-8').replace('/', '_'), helpers.latinToAscii(albums[1]).encode('UTF-8').replace('/', '_'), year)
logger.info(u"Pre-processing result")
(data, bestqual) = preprocess(nzblist)
if data and bestqual:
nzb_folder_name = '%s - %s [%s]' % (helpers.latinToAscii(albums[0]).encode('UTF-8').replace('/', '_'), helpers.latinToAscii(albums[1]).encode('UTF-8').replace('/', '_'), year)
if headphones.SAB_HOST and not headphones.BLACKHOLE:
linkparams = {}
linkparams["mode"] = "addurl"
if headphones.SAB_APIKEY:
linkparams["apikey"] = headphones.SAB_APIKEY
if headphones.SAB_USERNAME:
linkparams["ma_username"] = headphones.SAB_USERNAME
if headphones.SAB_PASSWORD:
linkparams["ma_password"] = headphones.SAB_PASSWORD
if headphones.SAB_CATEGORY:
linkparams["cat"] = headphones.SAB_CATEGORY
linkparams["name"] = downloadurl
linkparams["nzbname"] = nzb_folder_name
saburl = 'http://' + headphones.SAB_HOST + '/sabnzbd/api?' + urllib.urlencode(linkparams)
logger.info(u'Sending link to SABNZBD: <a href="%s">SabNZBD link</a>' % saburl)
try:
urllib.urlopen(saburl)
except:
logger.error(u"Unable to send link. Are you sure the host address is correct?")
break
myDB.action('UPDATE albums SET status = "Snatched" WHERE AlbumID=?', [albums[2]])
myDB.action('INSERT INTO snatched VALUES( ?, ?, ?, ?, DATETIME("NOW", "localtime"), ?, ?)', [albums[2], bestqual[0], bestqual[1], bestqual[2], "Snatched", nzb_folder_name])
nzb = classes.NZBDataSearchResult()
nzb.extraInfo.append(data)
nzb.name = nzb_folder_name
sab.sendNZB(nzb)
elif headphones.BLACKHOLE:
nzb_name = nzb_folder_name + '.nzb'
download_path = os.path.join(headphones.BLACKHOLE_DIR, nzb_name)
try:
urllib.urlretrieve(downloadurl, download_path)
f = open(download_path, 'w')
f.write(data)
f.close()
except Exception, e:
logger.error('Couldn\'t retrieve NZB: %s' % e)
logger.error('Couldn\'t write NZB file: %s' % e)
break
myDB.action('UPDATE albums SET status = "Snatched" WHERE AlbumID=?', [albums[2]])
myDB.action('INSERT INTO snatched VALUES( ?, ?, ?, ?, DATETIME("NOW", "localtime"), ?, ?)', [albums[2], bestqual[0], bestqual[1], bestqual[2], "Snatched", nzb_folder_name])
myDB.action('UPDATE albums SET status = "Snatched" WHERE AlbumID=?', [albums[2]])
myDB.action('INSERT INTO snatched VALUES( ?, ?, ?, ?, DATETIME("NOW", "localtime"), ?, ?)', [albums[2], bestqual[0], bestqual[1], bestqual[2], "Snatched", nzb_folder_name])
def verifyresult(title, term):
@@ -482,3 +440,41 @@ def verifyresult(title, term):
return False
else:
return True
def getresultNZB(result):
if result[3] == 'Newzbin':
params = urllib.urlencode({"username": headphones.NEWZBIN_UID, "password": headphones.NEWZBIN_PASSWORD, "reportid": result[2]})
url = "https://www.newzbin.com" + "/api/dnzb/"
urllib._urlopener = NewzbinDownloader()
try:
nzb = urllib.urlopen(url, data=params).read()
except urllib2.URLError, e:
logger.warn('Error fetching nzb from url: ' + url + ' %s' % e)
else:
try:
nzb = urllib2.urlopen(result[2], timeout=20).read()
except:
logger.warn('Error fetching nzb from url: ' + result[2] + ' %s' % e)
return nzb
def preprocess(resultlist):
for result in resultlist:
nzb = getresultNZB(result)
if nzb:
try:
d = minidom.parseString(nzb)
node = d.documentElement
nzbfiles = d.getElementsByTagName("file")
for nzbfile in nzbfiles:
if nzbfile.getAttribute("date") < (time.time() - int(headphones.USENET_RETENTION) * 86400):
logger.error('NZB contains a file out of your retention. Skipping.')
continue
#TODO: Do we want rar checking in here to try to keep unknowns out?
#or at least the option to do so?
except ExpatError:
logger.error('Unable to parse the best result NZB. Skipping.')
continue
return nzb, result
else:
logger.error("Couldn't retrieve the best nzb. Skipping.")
return (False, False)