Release v0.5.5

This commit is contained in:
rembo10
2015-05-04 19:43:37 -07:00
11 changed files with 246 additions and 26 deletions
+19
View File
@@ -1,5 +1,24 @@
# Changelog # Changelog
## v0.5.5
Released 04 May 2015
Highlights:
* Added: force ID3v2.3 during post processing (#2121)
* Added: MusicBrainz authentication (#2125)
* Added: Email notifications (addresses #1045)
* Fixed: Kickass url updated to kickass.to (#2119)
* Fixed: Piratebay returning 0 bytes for all files
* Fixed: Albums stopped automatically refreshing when adding an artist
* Fixed: Min/max sizes for target bitrate
* Fixed: Don't filter any results if looking for a specific download
* Fixed: Sort by size in the specific download table
* Fixed: Deal with beets recommendation.none correctly
* Improved: Close dialog window automatically when choosing a specific download
* Improved: Move some repetitive log messages to debug level
The full list of commits can be found [here](https://github.com/rembo10/headphones/compare/v0.5.4...v0.5.5).
## v0.5.4 ## v0.5.4
Released 05 February 2015 Released 05 February 2015
+15
View File
@@ -337,6 +337,21 @@
}); });
} }
jQuery.extend( jQuery.fn.dataTableExt.oSort, {
"title-numeric-pre": function ( a ) {
var x = a.match(/title="*(-?[0-9\.]+)/)[1];
return parseFloat( x );
},
"title-numeric-asc": function ( a, b ) {
return ((a < b) ? -1 : ((a > b) ? 1 : 0));
},
"title-numeric-desc": function ( a, b ) {
return ((a < b) ? 1 : ((a > b) ? -1 : 0));
}
} );
$(document).ready(function() { $(document).ready(function() {
getAlbumInfo(); getAlbumInfo();
initThisPage(); initThisPage();
+88
View File
@@ -786,6 +786,10 @@
Embed lyrics Embed lyrics
<input type="checkbox" name="embed_lyrics" value="1" ${config['embed_lyrics']}> <input type="checkbox" name="embed_lyrics" value="1" ${config['embed_lyrics']}>
</label> </label>
<label title="Use ID3v2.3 instead of ID3v2.4">
Tag using ID3v2.3
<input type="checkbox" name="idtag" value="1" ${config['idtag']}>
</label>
</div> </div>
<div class="row"> <div class="row">
<label> <label>
@@ -1104,6 +1108,39 @@
</div> </div>
</fieldset> </fieldset>
<fieldset>
<h3>Email</h3>
<div class="row checkbox">
<input type="checkbox" name="email_enabled" id="email" value="1" ${config['email_enabled']} /><label>Enable Email Notifications</label>
</div>
<div id="email_options">
<div class="row">
<label>From</label><input type="text" name="email_from" value="${config['email_from']}" size="254">
</div>
<div class="row">
<label>To</label><input type="text" name="email_to" value="${config['email_to']}" size="254">
</div>
<div class="row">
<label>SMTP Server</label><input type="text" name="email_smtp_server" value="${config['email_smtp_server']}" size="254">
</div>
<div class="row">
<label>SMTP User</label><input type="text" name="email_smtp_user" value="${config['email_smtp_user']}" size="254">
</div>
<div class="row">
<label>SMTP Password</label><input type="password" name="email_smtp_password" value="${config['email_smtp_password']}" size="50">
</div>
<div class="row checkbox">
<input type="text" class="override-float" name="email_smtp_port" value="${config['email_smtp_port']}" size="4"><label>SMTP Port</label>
</div>
<div class="row checkbox">
<input type="checkbox" name="email_tls" value="1" ${config['email_tls']} /><label>TLS</label>
</div>
<div class="row checkbox">
<input type="checkbox" name="email_onsnatch" value="1" ${config['email_onsnatch']} /><label>Notify on snatch?</label>
</div>
</div>
</fieldset>
<fieldset> <fieldset>
</td> </td>
</tr> </tr>
@@ -1416,6 +1453,17 @@
<div class="row"> <div class="row">
<label>Port</label><input type="text" name="customport" value="${config['customport']}" size="8"> <label>Port</label><input type="text" name="customport" value="${config['customport']}" size="8">
</div> </div>
<div class="row checkbox">
<input type="checkbox" name="customauth" id="customauth" value="1" ${config['customauth']} /><label>Requires Authentication</label>
</div>
<div id="customauth_options">
<div class="row">
<label>Username</label><input type="text" class="customuser" name="customuser" value="${config['customuser']}" size="20">
</div>
<div class="row">
<label>Password</label><input type="password" class="custompass" name="custompass" value="${config['custompass']}" size="15"><br>
</div>
</div>
<div class="row"> <div class="row">
<label>Sleep Interval</label><input type="text" name="customsleep" value="${config['customsleep']}" size="4"> <label>Sleep Interval</label><input type="text" name="customsleep" value="${config['customsleep']}" size="4">
</div> </div>
@@ -1526,6 +1574,25 @@
$('#api_key').val(data); $('#api_key').val(data);
}); });
}); });
if ($("#customauth").is(":checked"))
{
$("#customauth_options").show();
}
else
{
$("#customauth_options").hide();
}
$("#customauth").click(function(){
if ($("#customauth").is(":checked"))
{
$("#customauth_options").slideDown();
}
else
{
$("#customauth_options").slideUp();
}
});
if ($("#enable_https").is(":checked")) if ($("#enable_https").is(":checked"))
{ {
$("#https_options").show(); $("#https_options").show();
@@ -1866,6 +1933,26 @@
} }
}); });
if ($("#email").is(":checked"))
{
$("#email_options").show();
}
else
{
$("#email_options").hide();
}
$("#email").click(function(){
if ($("#email").is(":checked"))
{
$("#email_options").slideDown();
}
else
{
$("#email_options").slideUp();
}
});
if ($("#songkick").is(":checked")) if ($("#songkick").is(":checked"))
{ {
$("#songkickoptions").show(); $("#songkickoptions").show();
@@ -2074,6 +2161,7 @@
initConfigCheckbox("#use_whatcd"); initConfigCheckbox("#use_whatcd");
initConfigCheckbox("#api_enabled"); initConfigCheckbox("#api_enabled");
initConfigCheckbox("#enable_https"); initConfigCheckbox("#enable_https");
initConfigCheckbox("#customauth");
$('#twitterStep1').click(function () { $('#twitterStep1').click(function () {
+13
View File
@@ -44,9 +44,12 @@ _CONFIG_DEFINITIONS = {
'CUE_SPLIT': (int, 'General', 1), 'CUE_SPLIT': (int, 'General', 1),
'CUE_SPLIT_FLAC_PATH': (str, 'General', ''), 'CUE_SPLIT_FLAC_PATH': (str, 'General', ''),
'CUE_SPLIT_SHNTOOL_PATH': (str, 'General', ''), 'CUE_SPLIT_SHNTOOL_PATH': (str, 'General', ''),
'CUSTOMAUTH': (int, 'General', 0),
'CUSTOMHOST': (str, 'General', 'localhost'), 'CUSTOMHOST': (str, 'General', 'localhost'),
'CUSTOMPASS': (str, 'General', ''),
'CUSTOMPORT': (int, 'General', 5000), 'CUSTOMPORT': (int, 'General', 5000),
'CUSTOMSLEEP': (int, 'General', 1), 'CUSTOMSLEEP': (int, 'General', 1),
'CUSTOMUSER': (str, 'General', ''),
'DELETE_LOSSLESS_FILES': (int, 'General', 1), 'DELETE_LOSSLESS_FILES': (int, 'General', 1),
'DESTINATION_DIR': (str, 'General', ''), 'DESTINATION_DIR': (str, 'General', ''),
'DETECT_BITRATE': (int, 'General', 0), 'DETECT_BITRATE': (int, 'General', 0),
@@ -54,6 +57,15 @@ _CONFIG_DEFINITIONS = {
'DOWNLOAD_SCAN_INTERVAL': (int, 'General', 5), 'DOWNLOAD_SCAN_INTERVAL': (int, 'General', 5),
'DOWNLOAD_TORRENT_DIR': (str, 'General', ''), 'DOWNLOAD_TORRENT_DIR': (str, 'General', ''),
'DO_NOT_OVERRIDE_GIT_BRANCH': (int, 'General', 0), 'DO_NOT_OVERRIDE_GIT_BRANCH': (int, 'General', 0),
'EMAIL_ENABLED': (int, 'Email', 0),
'EMAIL_FROM': (str, 'Email', ''),
'EMAIL_TO': (str, 'Email', ''),
'EMAIL_SMTP_SERVER': (str, 'Email', ''),
'EMAIL_SMTP_USER': (str, 'Email', ''),
'EMAIL_SMTP_PASSWORD': (str, 'Email', ''),
'EMAIL_SMTP_PORT': (int, 'Email', 25),
'EMAIL_TLS': (int, 'Email', 0),
'EMAIL_ONSNATCH': (int, 'Email', 0),
'EMBED_ALBUM_ART': (int, 'General', 0), 'EMBED_ALBUM_ART': (int, 'General', 0),
'EMBED_LYRICS': (int, 'General', 0), 'EMBED_LYRICS': (int, 'General', 0),
'ENABLE_HTTPS': (int, 'General', 0), 'ENABLE_HTTPS': (int, 'General', 0),
@@ -92,6 +104,7 @@ _CONFIG_DEFINITIONS = {
'HTTP_PROXY': (int, 'General', 0), 'HTTP_PROXY': (int, 'General', 0),
'HTTP_ROOT': (str, 'General', '/'), 'HTTP_ROOT': (str, 'General', '/'),
'HTTP_USERNAME': (str, 'General', ''), 'HTTP_USERNAME': (str, 'General', ''),
'IDTAG': (int, 'Beets', 0),
'IGNORED_WORDS': (str, 'General', ''), 'IGNORED_WORDS': (str, 'General', ''),
'IGNORED_FOLDERS': (list, 'Advanced', []), 'IGNORED_FOLDERS': (list, 'Advanced', []),
'IGNORED_FILES': (list, 'Advanced', []), 'IGNORED_FILES': (list, 'Advanced', []),
+3 -3
View File
@@ -173,15 +173,15 @@ def piratesize(size):
factor = float(split[0]) factor = float(split[0])
unit = split[1].upper() unit = split[1].upper()
if unit == 'MiB': if unit == 'MIB':
size = factor * 1048576 size = factor * 1048576
elif unit == 'MB': elif unit == 'MB':
size = factor * 1000000 size = factor * 1000000
elif unit == 'GiB': elif unit == 'GIB':
size = factor * 1073741824 size = factor * 1073741824
elif unit == 'GB': elif unit == 'GB':
size = factor * 1000000000 size = factor * 1000000000
elif unit == 'KiB': elif unit == 'KIB':
size = factor * 1024 size = factor * 1024
elif unit == 'KB': elif unit == 'KB':
size = factor * 1000 size = factor * 1000
+9 -3
View File
@@ -47,6 +47,8 @@ def startmb():
elif headphones.CONFIG.MIRROR == "custom": elif headphones.CONFIG.MIRROR == "custom":
mbhost = headphones.CONFIG.CUSTOMHOST mbhost = headphones.CONFIG.CUSTOMHOST
mbport = int(headphones.CONFIG.CUSTOMPORT) mbport = int(headphones.CONFIG.CUSTOMPORT)
mbuser = headphones.CONFIG.CUSTOMUSER
mbpass = headphones.CONFIG.CUSTOMPASS
sleepytime = int(headphones.CONFIG.CUSTOMSLEEP) sleepytime = int(headphones.CONFIG.CUSTOMSLEEP)
elif headphones.CONFIG.MIRROR == "headphones": elif headphones.CONFIG.MIRROR == "headphones":
mbhost = "144.76.94.239" mbhost = "144.76.94.239"
@@ -69,12 +71,16 @@ def startmb():
mb_lock.minimum_delta = sleepytime mb_lock.minimum_delta = sleepytime
# Add headphones credentials # Add headphones credentials
if headphones.CONFIG.MIRROR == "headphones": if headphones.CONFIG.MIRROR == "headphones" or headphones.CONFIG.CUSTOMAUTH:
if not mbuser and mbpass: if not mbuser or not mbpass:
logger.warn("No username or password set for VIP server") logger.warn("No username or password set for MusicBrainz server")
else: else:
musicbrainzngs.hpauth(mbuser, mbpass) musicbrainzngs.hpauth(mbuser, mbpass)
# Let us know if we disable custom authentication
if not headphones.CONFIG.CUSTOMAUTH and headphones.CONFIG.MIRROR == "custom":
musicbrainzngs.disable_hpauth()
logger.debug('Using the following server values: MBHost: %s, MBPort: %i, Sleep Interval: %i', mbhost, mbport, sleepytime) logger.debug('Using the following server values: MBHost: %s, MBPort: %i, Sleep Interval: %i', mbhost, mbport, sleepytime)
return True return True
+33
View File
@@ -34,6 +34,11 @@ import json
import oauth2 as oauth import oauth2 as oauth
import pythontwitter as twitter import pythontwitter as twitter
from email.mime.text import MIMEText
import smtplib
import email.utils
class GROWL(object): class GROWL(object):
""" """
Growl notifications, for OS X. Growl notifications, for OS X.
@@ -827,3 +832,31 @@ class SubSonicNotifier(object):
# Invoke request # Invoke request
request.request_response(self.host + "musicFolderSettings.view?scanNow", request.request_response(self.host + "musicFolderSettings.view?scanNow",
auth=(self.username, self.password)) auth=(self.username, self.password))
class Email(object):
def notify(self, subject, message):
message = MIMEText(message, 'plain', "utf-8")
message['Subject'] = subject
message['From'] = email.utils.formataddr(('Headphones', headphones.CONFIG.EMAIL_FROM))
message['To'] = headphones.CONFIG.EMAIL_TO
try:
mailserver = smtplib.SMTP(headphones.CONFIG.EMAIL_SMTP_SERVER, headphones.CONFIG.EMAIL_SMTP_PORT)
if (headphones.CONFIG.EMAIL_TLS):
mailserver.starttls()
mailserver.ehlo()
if headphones.CONFIG.EMAIL_SMTP_USER:
mailserver.login(headphones.CONFIG.EMAIL_SMTP_USER, headphones.CONFIG.EMAIL_SMTP_PASSWORD)
mailserver.sendmail(headphones.CONFIG.EMAIL_FROM, headphones.CONFIG.EMAIL_TO, message.as_string())
mailserver.quit()
return True
except Exception, e:
logger.warn('Error sending Email: %s' % e)
return False
+20 -3
View File
@@ -23,6 +23,7 @@ import itertools
import headphones import headphones
from beets import autotag from beets import autotag
from beets import config as beetsconfig
from beets.mediafile import MediaFile, FileTypeError, UnreadableFileError from beets.mediafile import MediaFile, FileTypeError, UnreadableFileError
from beetsplug import lyrics as beetslyrics from beetsplug import lyrics as beetslyrics
@@ -34,7 +35,7 @@ postprocessor_lock = threading.Lock()
def checkFolder(): def checkFolder():
logger.info("Checking download folder for completed downloads (only snatched ones).") logger.debug("Checking download folder for completed downloads (only snatched ones).")
with postprocessor_lock: with postprocessor_lock:
myDB = db.DBConnection() myDB = db.DBConnection()
@@ -56,7 +57,7 @@ def checkFolder():
else: else:
logger.info("No folder name found for " + album['Title']) logger.info("No folder name found for " + album['Title'])
logger.info("Checking download folder finished.") logger.debug("Checking download folder finished.")
def verify(albumid, albumpath, Kind=None, forced=False): def verify(albumid, albumpath, Kind=None, forced=False):
@@ -513,6 +514,12 @@ def doPostProcessing(albumid, albumpath, release, tracks, downloaded_track_list,
mpc = notifiers.MPC() mpc = notifiers.MPC()
mpc.notify() mpc.notify()
if headphones.CONFIG.EMAIL_ENABLED:
logger.info(u"Sending Email notification")
email = notifiers.Email()
subject = release['ArtistName'] + ' - ' + release['AlbumTitle']
email.notify(subject, "Download and Postprocessing completed")
def embedAlbumArt(artwork, downloaded_track_list): def embedAlbumArt(artwork, downloaded_track_list):
logger.info('Embedding album art') logger.info('Embedding album art')
@@ -858,7 +865,7 @@ def correctMetadata(albumid, release, downloaded_track_list):
except Exception as e: except Exception as e:
logger.error('Error getting recommendation: %s. Not writing metadata', e) logger.error('Error getting recommendation: %s. Not writing metadata', e)
return return
if str(rec) == 'recommendation.none': if str(rec) == 'Recommendation.none':
logger.warn('No accurate album match found for %s, %s - not writing metadata', release['ArtistName'], release['AlbumTitle']) logger.warn('No accurate album match found for %s, %s - not writing metadata', release['ArtistName'], release['AlbumTitle'])
return return
@@ -874,6 +881,14 @@ def correctMetadata(albumid, release, downloaded_track_list):
autotag.apply_metadata(info, mapping) autotag.apply_metadata(info, mapping)
# Set ID3 tag version
if headphones.CONFIG.IDTAG:
beetsconfig['id3v23'] = True
logger.debug("Using ID3v2.3")
else:
beetsconfig['id3v23'] = False
logger.debug("Using ID3v2.4")
for item in items: for item in items:
try: try:
item.write() item.write()
@@ -1053,6 +1068,8 @@ def renameUnprocessedFolder(path, tag):
def forcePostProcess(dir=None, expand_subfolders=True, album_dir=None): def forcePostProcess(dir=None, expand_subfolders=True, album_dir=None):
logger.info('Force checking download folder for completed downloads')
ignored = 0 ignored = 0
if album_dir: if album_dir:
+16 -12
View File
@@ -225,7 +225,7 @@ def do_sorted_search(album, new, losslessOnly, choose_specific_download=False):
myDB = db.DBConnection() 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: if headphones.CONFIG.PREFER_TORRENTS == 0 and not choose_specific_download:
if NZB_PROVIDERS and NZB_DOWNLOADERS: if NZB_PROVIDERS and NZB_DOWNLOADERS:
results = searchNZB(album, new, losslessOnly, albumlength) results = searchNZB(album, new, losslessOnly, albumlength)
@@ -233,7 +233,7 @@ def do_sorted_search(album, new, losslessOnly, choose_specific_download=False):
if not results and TORRENT_PROVIDERS: if not results and TORRENT_PROVIDERS:
results = searchTorrent(album, new, losslessOnly, albumlength) results = searchTorrent(album, new, losslessOnly, albumlength)
elif headphones.CONFIG.PREFER_TORRENTS == 1: elif headphones.CONFIG.PREFER_TORRENTS == 1 and not choose_specific_download:
if TORRENT_PROVIDERS: if TORRENT_PROVIDERS:
results = searchTorrent(album, new, losslessOnly, albumlength) results = searchTorrent(album, new, losslessOnly, albumlength)
@@ -247,10 +247,10 @@ def do_sorted_search(album, new, losslessOnly, choose_specific_download=False):
torrent_results = None torrent_results = None
if NZB_PROVIDERS and NZB_DOWNLOADERS: if NZB_PROVIDERS and NZB_DOWNLOADERS:
nzb_results = searchNZB(album, new, losslessOnly, albumlength) nzb_results = searchNZB(album, new, losslessOnly, albumlength, choose_specific_download)
if TORRENT_PROVIDERS: if TORRENT_PROVIDERS:
torrent_results = searchTorrent(album, new, losslessOnly, albumlength) torrent_results = searchTorrent(album, new, losslessOnly, albumlength, choose_specific_download)
if not nzb_results: if not nzb_results:
nzb_results = [] nzb_results = []
@@ -306,9 +306,9 @@ def more_filtering(results, album, albumlength, new):
targetsize = albumlength / 1000 * int(headphones.CONFIG.PREFERRED_BITRATE) * 128 targetsize = albumlength / 1000 * int(headphones.CONFIG.PREFERRED_BITRATE) * 128
logger.info('Target size: %s' % helpers.bytes_to_mb(targetsize)) logger.info('Target size: %s' % helpers.bytes_to_mb(targetsize))
if headphones.CONFIG.PREFERRED_BITRATE_LOW_BUFFER: if headphones.CONFIG.PREFERRED_BITRATE_LOW_BUFFER:
low_size_limit = targetsize - (targetsize * int(headphones.CONFIG.PREFERRED_BITRATE_LOW_BUFFER) / 100) low_size_limit = targetsize * int(headphones.CONFIG.PREFERRED_BITRATE_LOW_BUFFER) / 100
if headphones.CONFIG.PREFERRED_BITRATE_HIGH_BUFFER: if headphones.CONFIG.PREFERRED_BITRATE_HIGH_BUFFER:
high_size_limit = targetsize + (targetsize * int(headphones.CONFIG.PREFERRED_BITRATE_HIGH_BUFFER) / 100) high_size_limit = targetsize * int(headphones.CONFIG.PREFERRED_BITRATE_HIGH_BUFFER) / 100
if headphones.CONFIG.PREFERRED_BITRATE_ALLOW_LOSSLESS: if headphones.CONFIG.PREFERRED_BITRATE_ALLOW_LOSSLESS:
allow_lossless = True allow_lossless = True
@@ -429,7 +429,7 @@ def get_year_from_release_date(release_date):
return year return year
def searchNZB(album, new=False, losslessOnly=False, albumlength=None): def searchNZB(album, new=False, losslessOnly=False, albumlength=None, choose_specific_download=False):
reldate = album['ReleaseDate'] reldate = album['ReleaseDate']
year = get_year_from_release_date(reldate) year = get_year_from_release_date(reldate)
@@ -691,7 +691,7 @@ def searchNZB(album, new=False, losslessOnly=False, albumlength=None):
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 # Additional filtering for size etc
if results: if results and not choose_specific_download:
results = more_filtering(results, album, albumlength, new) results = more_filtering(results, album, albumlength, new)
return results return results
@@ -946,7 +946,11 @@ def send_to_downloader(data, bestqual, album):
b2msg = 'From ' + provider + '<br></br>' + name b2msg = 'From ' + provider + '<br></br>' + name
boxcar = notifiers.BOXCAR() boxcar = notifiers.BOXCAR()
boxcar.notify('Headphones snatched: ' + title, b2msg, rgid) boxcar.notify('Headphones snatched: ' + title, b2msg, rgid)
if headphones.CONFIG.EMAIL_ENABLED and headphones.CONFIG.EMAIL_ONSNATCH:
logger.info(u"Sending Email notification")
email = notifiers.Email()
message = 'Snatched from ' + provider + '. ' + name
email.notify(title, message)
def verifyresult(title, artistterm, term, lossless): def verifyresult(title, artistterm, term, lossless):
@@ -1014,7 +1018,7 @@ def verifyresult(title, artistterm, term, lossless):
return True return True
def searchTorrent(album, new=False, losslessOnly=False, albumlength=None): def searchTorrent(album, new=False, losslessOnly=False, albumlength=None, choose_specific_download=False):
global gazelle # persistent what.cd api object to reduce number of login attempts global gazelle # persistent what.cd api object to reduce number of login attempts
# rutracker login # rutracker login
@@ -1092,7 +1096,7 @@ def searchTorrent(album, new=False, losslessOnly=False, albumlength=None):
if headphones.CONFIG.KAT_PROXY_URL: if headphones.CONFIG.KAT_PROXY_URL:
providerurl = fix_url(set_proxy(headphones.CONFIG.KAT_PROXY_URL)) providerurl = fix_url(set_proxy(headphones.CONFIG.KAT_PROXY_URL))
else: else:
providerurl = fix_url("https://kickass.so") providerurl = fix_url("https://kickass.to")
# Build URL # Build URL
providerurl = providerurl + "/usearch/" + ka_term providerurl = providerurl + "/usearch/" + ka_term
@@ -1521,7 +1525,7 @@ def searchTorrent(album, new=False, losslessOnly=False, albumlength=None):
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 # Additional filtering for size etc
if results: if results and not choose_specific_download:
results = more_filtering(results, album, albumlength, new) results = more_filtering(results, album, albumlength, new)
return results return results
+19 -2
View File
@@ -374,6 +374,9 @@ class WebInterface(object):
myDB = db.DBConnection() myDB = db.DBConnection()
album = myDB.action('SELECT * from albums WHERE AlbumID=?', [AlbumID]).fetchone() album = myDB.action('SELECT * from albums WHERE AlbumID=?', [AlbumID]).fetchone()
searcher.send_to_downloader(data, bestqual, album) searcher.send_to_downloader(data, bestqual, album)
return json.dumps({'result':'success'})
else:
return json.dumps({'result':'failure'})
@cherrypy.expose @cherrypy.expose
def unqueueAlbum(self, AlbumID, ArtistID): def unqueueAlbum(self, AlbumID, ArtistID):
@@ -877,6 +880,7 @@ class WebInterface(object):
cherrypy.response.headers['Content-type'] = 'application/json' cherrypy.response.headers['Content-type'] = 'application/json'
return json_albums return json_albums
@cherrypy.expose
def getArtistjson(self, ArtistID, **kwargs): def getArtistjson(self, ArtistID, **kwargs):
myDB = db.DBConnection() myDB = db.DBConnection()
artist = myDB.action('SELECT * FROM artists WHERE ArtistID=?', [ArtistID]).fetchone() artist = myDB.action('SELECT * FROM artists WHERE ArtistID=?', [ArtistID]).fetchone()
@@ -1142,6 +1146,9 @@ class WebInterface(object):
"customhost": headphones.CONFIG.CUSTOMHOST, "customhost": headphones.CONFIG.CUSTOMHOST,
"customport": headphones.CONFIG.CUSTOMPORT, "customport": headphones.CONFIG.CUSTOMPORT,
"customsleep": headphones.CONFIG.CUSTOMSLEEP, "customsleep": headphones.CONFIG.CUSTOMSLEEP,
"customauth": checked(headphones.CONFIG.CUSTOMAUTH),
"customuser": headphones.CONFIG.CUSTOMUSER,
"custompass": headphones.CONFIG.CUSTOMPASS,
"hpuser": headphones.CONFIG.HPUSER, "hpuser": headphones.CONFIG.HPUSER,
"hppass": headphones.CONFIG.HPPASS, "hppass": headphones.CONFIG.HPPASS,
"songkick_enabled": checked(headphones.CONFIG.SONGKICK_ENABLED), "songkick_enabled": checked(headphones.CONFIG.SONGKICK_ENABLED),
@@ -1151,7 +1158,17 @@ class WebInterface(object):
"cache_sizemb": headphones.CONFIG.CACHE_SIZEMB, "cache_sizemb": headphones.CONFIG.CACHE_SIZEMB,
"file_permissions": headphones.CONFIG.FILE_PERMISSIONS, "file_permissions": headphones.CONFIG.FILE_PERMISSIONS,
"folder_permissions": headphones.CONFIG.FOLDER_PERMISSIONS, "folder_permissions": headphones.CONFIG.FOLDER_PERMISSIONS,
"mpc_enabled": checked(headphones.CONFIG.MPC_ENABLED) "mpc_enabled": checked(headphones.CONFIG.MPC_ENABLED),
"email_enabled": checked(headphones.CONFIG.EMAIL_ENABLED),
"email_from": headphones.CONFIG.EMAIL_FROM,
"email_to": headphones.CONFIG.EMAIL_TO,
"email_smtp_server": headphones.CONFIG.EMAIL_SMTP_SERVER,
"email_smtp_user": headphones.CONFIG.EMAIL_SMTP_USER,
"email_smtp_password": headphones.CONFIG.EMAIL_SMTP_PASSWORD,
"email_smtp_port": int(headphones.CONFIG.EMAIL_SMTP_PORT),
"email_tls": checked(headphones.CONFIG.EMAIL_TLS),
"email_onsnatch": checked(headphones.CONFIG.EMAIL_ONSNATCH),
"idtag": checked(headphones.CONFIG.IDTAG)
} }
# Need to convert EXTRAS to a dictionary we can pass to the config: # Need to convert EXTRAS to a dictionary we can pass to the config:
@@ -1196,7 +1213,7 @@ class WebInterface(object):
"nma_enabled", "nma_onsnatch", "pushalot_enabled", "pushalot_onsnatch", "synoindex_enabled", "pushover_enabled", "nma_enabled", "nma_onsnatch", "pushalot_enabled", "pushalot_onsnatch", "synoindex_enabled", "pushover_enabled",
"pushover_onsnatch", "pushbullet_enabled", "pushbullet_onsnatch", "subsonic_enabled", "twitter_enabled", "twitter_onsnatch", "pushover_onsnatch", "pushbullet_enabled", "pushbullet_onsnatch", "subsonic_enabled", "twitter_enabled", "twitter_onsnatch",
"osx_notify_enabled", "osx_notify_onsnatch", "boxcar_enabled", "boxcar_onsnatch", "songkick_enabled", "songkick_filter_enabled", "osx_notify_enabled", "osx_notify_onsnatch", "boxcar_enabled", "boxcar_onsnatch", "songkick_enabled", "songkick_filter_enabled",
"mpc_enabled" "mpc_enabled", "email_enabled", "email_tls", "email_onsnatch", "customauth", "idtag"
] ]
for checked_config in checked_configs: for checked_config in checked_configs:
if checked_config not in kwargs: if checked_config not in kwargs:
+10 -2
View File
@@ -271,6 +271,7 @@ user = password = ""
hostname = "musicbrainz.org" hostname = "musicbrainz.org"
_client = "" _client = ""
_useragent = "" _useragent = ""
mb_auth = False
def auth(u, p): def auth(u, p):
"""Set the username and password to be used in subsequent queries to """Set the username and password to be used in subsequent queries to
@@ -284,9 +285,16 @@ def hpauth(u, p):
"""Set the username and password to be used in subsequent queries to """Set the username and password to be used in subsequent queries to
the MusicBrainz XML API that require authentication. the MusicBrainz XML API that require authentication.
""" """
global hpuser, hppassword global hpuser, hppassword, mb_auth
hpuser = u hpuser = u
hppassword = p hppassword = p
mb_auth = True
def disable_hpauth():
"""Disable the authentication for MusicBrainz XML API
"""
global mb_auth
mb_auth = False
def set_useragent(app, version, contact=None): def set_useragent(app, version, contact=None):
"""Set the User-Agent to be used for requests to the MusicBrainz webservice. """Set the User-Agent to be used for requests to the MusicBrainz webservice.
@@ -635,7 +643,7 @@ def _mb_request(path, method='GET', auth_required=False, client_required=False,
req.add_header('User-Agent', _useragent) req.add_header('User-Agent', _useragent)
# Add headphones credentials # Add headphones credentials
if hostname == '144.76.94.239:8181': if mb_auth:
base64string = base64.encodestring('%s:%s' % (hpuser, hppassword)).replace('\n', '') base64string = base64.encodestring('%s:%s' % (hpuser, hppassword)).replace('\n', '')
req.add_header("Authorization", "Basic %s" % base64string) req.add_header("Authorization", "Basic %s" % base64string)