@@ -199,18 +200,54 @@ m<%inherit file="base.html"/>
-
-
+
+
+ <%
+ newznab_number = 2
+ %>
+ %for newznab in sorted(config['extra_newznabs'], key=itemgetter(0)):
+ <%
+ if newznab[2]:
+ newznab_enabled = "checked"
+ else:
+ newznab_enabled = ""
+ %>
+
+ <%
+ newznab_number += 1
+ %>
+ %endfor
+
+
+
@@ -233,11 +270,11 @@ m<%inherit file="base.html"/>
@@ -776,6 +813,24 @@ m<%inherit file="base.html"/>
$("#mirror").change(handleNewSelection);
handleNewSelection.apply($("#mirror"));
+
+ $(".remove").click(function() {
+ $(this).parent().parent().remove();
+ });
+
+ $("#add_newznab").click(function() {
+ var intIdPrev = $("#newznab_providers > div").size();
+ var intId = intIdPrev + 1;
+ var formfields = $("");
+ $("#newznab" + intIdPrev).after(formfields);
+ });
+
$(function() {
$( "#tabs" ).tabs();
});
@@ -789,7 +844,7 @@ m<%inherit file="base.html"/>
initConfigCheckbox("#useapi");
}
$(document).ready(function() {
- initThisPage();
+ initThisPage();
});
diff --git a/headphones/__init__.py b/headphones/__init__.py
index a6ab5255..f8eacc1a 100644
--- a/headphones/__init__.py
+++ b/headphones/__init__.py
@@ -121,6 +121,8 @@ NZBMATRIX_APIKEY = None
NEWZNAB = False
NEWZNAB_HOST = None
NEWZNAB_APIKEY = None
+NEWZNAB_ENABLED = False
+EXTRA_NEWZNABS = []
NZBSORG = False
NZBSORG_UID = None
@@ -240,7 +242,7 @@ def initialize():
ADD_ALBUM_ART, EMBED_ALBUM_ART, EMBED_LYRICS, DOWNLOAD_DIR, BLACKHOLE, BLACKHOLE_DIR, USENET_RETENTION, SEARCH_INTERVAL, \
TORRENTBLACKHOLE_DIR, NUMBEROFSEEDERS, ISOHUNT, KAT, MININOVA, WAFFLES, WAFFLES_UID, WAFFLES_PASSKEY, DOWNLOAD_TORRENT_DIR, \
LIBRARYSCAN_INTERVAL, DOWNLOAD_SCAN_INTERVAL, SAB_HOST, SAB_USERNAME, SAB_PASSWORD, SAB_APIKEY, SAB_CATEGORY, \
- NZBMATRIX, NZBMATRIX_USERNAME, NZBMATRIX_APIKEY, NEWZNAB, NEWZNAB_HOST, NEWZNAB_APIKEY, \
+ NZBMATRIX, NZBMATRIX_USERNAME, NZBMATRIX_APIKEY, NEWZNAB, NEWZNAB_HOST, NEWZNAB_APIKEY, NEWZNAB_ENABLED, EXTRA_NEWZNABS,\
NZBSORG, NZBSORG_UID, NZBSORG_HASH, NEWZBIN, NEWZBIN_UID, NEWZBIN_PASSWORD, LASTFM_USERNAME, INTERFACE, FOLDER_PERMISSIONS, \
ENCODERFOLDER, ENCODER, BITRATE, SAMPLINGFREQUENCY, MUSIC_ENCODER, ADVANCEDENCODER, ENCODEROUTPUTFORMAT, ENCODERQUALITY, ENCODERVBRCBR, \
ENCODERLOSSLESS, PROWL_ENABLED, PROWL_PRIORITY, PROWL_KEYS, PROWL_ONSNATCH, MIRRORLIST, MIRROR, CUSTOMHOST, CUSTOMPORT, \
@@ -340,6 +342,8 @@ def initialize():
NEWZNAB = bool(check_setting_int(CFG, 'Newznab', 'newznab', 0))
NEWZNAB_HOST = check_setting_str(CFG, 'Newznab', 'newznab_host', '')
NEWZNAB_APIKEY = check_setting_str(CFG, 'Newznab', 'newznab_apikey', '')
+ NEWZNAB_ENABLED = bool(check_setting_int(CFG, 'Newznab', 'newznab_enabled', 1))
+ EXTRA_NEWZNABS = check_setting_str(CFG, 'Newznab', 'extra_newznabs', [], log=False)
NZBSORG = bool(check_setting_int(CFG, 'NZBsorg', 'nzbsorg', 0))
NZBSORG_UID = check_setting_str(CFG, 'NZBsorg', 'nzbsorg_uid', '')
@@ -613,6 +617,8 @@ def config_write():
new_config['Newznab']['newznab'] = int(NEWZNAB)
new_config['Newznab']['newznab_host'] = NEWZNAB_HOST
new_config['Newznab']['newznab_apikey'] = NEWZNAB_APIKEY
+ new_config['Newznab']['newznab_enabled'] = int(NEWZNAB_ENABLED)
+ new_config['Newznab']['extra_newznabs'] = EXTRA_NEWZNABS
new_config['NZBsorg'] = {}
new_config['NZBsorg']['nzbsorg'] = int(NZBSORG)
diff --git a/headphones/searcher.py b/headphones/searcher.py
index 95e14a5e..a7808220 100644
--- a/headphones/searcher.py
+++ b/headphones/searcher.py
@@ -216,6 +216,16 @@ def searchNZB(albumid=None, new=False, losslessOnly=False):
logger.info(u"No results found from NZBMatrix for %s" % term)
if headphones.NEWZNAB:
+
+ newznab_hosts = [[headphones.NEWZNAB_HOST, headphones.NEWZNAB_APIKEY, headphones.NEWZNAB_ENABLED]]
+
+ # This is just to make sure we don't have any empty string for EXTRA_NEWZNABS
+ if not headphones.EXTRA_NEWZNABS:
+ headphones.EXTRA_NEWZNABS = []
+
+ for newznab_host in headphones.EXTRA_NEWZNABS:
+ newznab_hosts.append(newznab_host)
+
provider = "newznab"
if headphones.PREFERRED_QUALITY == 3 or losslessOnly:
categories = "3040"
@@ -227,44 +237,49 @@ def searchNZB(albumid=None, new=False, losslessOnly=False):
if albums['Type'] == 'Other':
categories = "3030"
logger.info("Album type is audiobook/spokenword. Using audiobook category")
+
+ for newznab_host in newznab_hosts:
+
+ if newznab_host[2] == 0 or newznab_host[2] == '0':
+ continue
- params = { "t": "search",
- "apikey": headphones.NEWZNAB_APIKEY,
- "cat": categories,
- "maxage": headphones.USENET_RETENTION,
- "q": term
- }
-
- searchURL = headphones.NEWZNAB_HOST + '/api?' + urllib.urlencode(params)
-
- logger.info(u'Parsing results from %s' % (searchURL, headphones.NEWZNAB_HOST))
+ params = { "t": "search",
+ "apikey": newznab_host[1],
+ "cat": categories,
+ "maxage": headphones.USENET_RETENTION,
+ "q": term
+ }
- try:
- data = urllib2.urlopen(searchURL, timeout=20).read()
- except urllib2.URLError, e:
- logger.warn('Error fetching data from %s: %s' % (headphones.NEWZNAB_HOST, e))
- data = False
+ searchURL = newznab_host[0] + '/api?' + urllib.urlencode(params)
+
+ logger.info(u'Parsing results from %s' % (searchURL, newznab_host[0]))
- if data:
-
- d = feedparser.parse(data)
+ try:
+ data = urllib2.urlopen(searchURL, timeout=20).read()
+ except urllib2.URLError, e:
+ logger.warn('Error fetching data from %s: %s' % (newznab_host[0], e))
+ data = False
+
+ if data:
- if not len(d.entries):
- logger.info(u"No results found from %s for %s" % (headphones.NEWZNAB_HOST, term))
- pass
-
- else:
- for item in d.entries:
- try:
- url = item.link
- title = item.title
- size = int(item.links[1]['length'])
+ d = feedparser.parse(data)
+
+ if not len(d.entries):
+ logger.info(u"No results found from %s for %s" % (newznab_host[0], term))
+ pass
+
+ else:
+ for item in d.entries:
+ try:
+ url = item.link
+ title = item.title
+ size = int(item.links[1]['length'])
+
+ resultlist.append((title, size, url, provider))
+ logger.info('Found %s. Size: %s' % (title, helpers.bytes_to_mb(size)))
- resultlist.append((title, size, url, provider))
- logger.info('Found %s. Size: %s' % (title, helpers.bytes_to_mb(size)))
-
- except Exception, e:
- logger.error(u"An unknown error occurred trying to parse the feed: %s" % e)
+ except Exception, e:
+ logger.error(u"An unknown error occurred trying to parse the feed: %s" % e)
if headphones.NZBSORG:
provider = "nzbsorg"
diff --git a/headphones/webserve.py b/headphones/webserve.py
index fc0332e7..2d190bf8 100644
--- a/headphones/webserve.py
+++ b/headphones/webserve.py
@@ -384,6 +384,8 @@ class WebInterface(object):
"use_newznab" : checked(headphones.NEWZNAB),
"newznab_host" : headphones.NEWZNAB_HOST,
"newznab_api" : headphones.NEWZNAB_APIKEY,
+ "newznab_enabled" : checked(headphones.NEWZNAB_ENABLED),
+ "extra_newznabs" : headphones.EXTRA_NEWZNABS,
"use_nzbsorg" : checked(headphones.NZBSORG),
"nzbsorg_uid" : headphones.NZBSORG_UID,
"nzbsorg_hash" : headphones.NZBSORG_HASH,
@@ -458,13 +460,13 @@ class WebInterface(object):
def configUpdate(self, http_host='0.0.0.0', http_username=None, http_port=8181, http_password=None, launch_browser=0, api_enabled=0, api_key=None, download_scan_interval=None, nzb_search_interval=None, libraryscan_interval=None,
sab_host=None, sab_username=None, sab_apikey=None, sab_password=None, sab_category=None, download_dir=None, blackhole=0, blackhole_dir=None,
- usenet_retention=None, nzbmatrix=0, nzbmatrix_username=None, nzbmatrix_apikey=None, newznab=0, newznab_host=None, newznab_apikey=None,
+ usenet_retention=None, nzbmatrix=0, nzbmatrix_username=None, nzbmatrix_apikey=None, newznab=0, newznab_host=None, newznab_apikey=None, newznab_enabled=0,
nzbsorg=0, nzbsorg_uid=None, nzbsorg_hash=None, newzbin=0, newzbin_uid=None, newzbin_password=None, preferred_quality=0, preferred_bitrate=None, detect_bitrate=0, move_files=0,
torrentblackhole_dir=None, download_torrent_dir=None, numberofseeders=10, use_isohunt=0, use_kat=0, use_mininova=0, waffles=0, waffles_uid=None, waffles_passkey=None,
rename_files=0, correct_metadata=0, cleanup_files=0, add_album_art=0, embed_album_art=0, embed_lyrics=0, destination_dir=None, folder_format=None, file_format=None, include_extras=0, autowant_upcoming=False, autowant_all=False, interface=None, log_dir=None,
music_encoder=0, encoder=None, bitrate=None, samplingfrequency=None, encoderfolder=None, advancedencoder=None, encoderoutputformat=None, encodervbrcbr=None, encoderquality=None, encoderlossless=0,
prowl_enabled=0, prowl_onsnatch=0, prowl_keys=None, prowl_priority=0, xbmc_enabled=0, xbmc_host=None, xbmc_username=None, xbmc_password=None, xbmc_update=0, xbmc_notify=0,
- nma_enabled=False, nma_apikey=None, nma_priority=0, synoindex_enabled=False, mirror=None, customhost=None, customport=None, customsleep=None, hpuser=None, hppass=None):
+ nma_enabled=False, nma_apikey=None, nma_priority=0, synoindex_enabled=False, mirror=None, customhost=None, customport=None, customsleep=None, hpuser=None, hppass=None, **kwargs):
headphones.HTTP_HOST = http_host
headphones.HTTP_PORT = http_port
@@ -491,6 +493,7 @@ class WebInterface(object):
headphones.NEWZNAB = newznab
headphones.NEWZNAB_HOST = newznab_host
headphones.NEWZNAB_APIKEY = newznab_apikey
+ headphones.NEWZNAB_ENABLED = newznab_enabled
headphones.NZBSORG = nzbsorg
headphones.NZBSORG_UID = nzbsorg_uid
headphones.NZBSORG_HASH = nzbsorg_hash
@@ -554,6 +557,22 @@ class WebInterface(object):
headphones.CUSTOMSLEEP = customsleep
headphones.HPUSER = hpuser
headphones.HPPASS = hppass
+
+ # Handle the variable config options. Note - keys with False values aren't getting passed
+
+ headphones.EXTRA_NEWZNABS = []
+
+ for kwarg in kwargs:
+ if kwarg.startswith('newznab_host'):
+ newznab_number = kwarg[12:]
+ newznab_host = kwargs['newznab_host' + newznab_number]
+ newznab_api = kwargs['newznab_api' + newznab_number]
+ try:
+ newznab_enabled = int(kwargs['newznab_enabled' + newznab_number])
+ except KeyError:
+ newznab_enabled = 0
+
+ headphones.EXTRA_NEWZNABS.append([newznab_host, newznab_api, newznab_enabled])
headphones.config_write()
|