mirror of
https://github.com/rembo10/headphones.git
synced 2026-05-16 08:35:32 +01:00
Implemented Jackett (Custom Torznab) option for Torrent Search Providers
This commit is contained in:
@@ -516,6 +516,59 @@
|
||||
<fieldset>
|
||||
<legend>Torrents</legend>
|
||||
|
||||
<fieldset>
|
||||
<div class="row checkbox left">
|
||||
<input id="use_torznab" type="checkbox" class="bigcheck" name="use_torznab" value="1" ${config['use_torznab']} /><label for="use_torznab"><span class="option">Jackett / Torznab Providers</span></label>
|
||||
</div>
|
||||
<div id="torznab_providers">
|
||||
<div class="config" id="torznab1">
|
||||
<div class="row">
|
||||
<label>Torznab Host</label>
|
||||
<input type="text" name="torznab_host" value="${config['torznab_host']}" size="30">
|
||||
<small>e.g. http://localhost:9117/torznab/iptorrents</small>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>Torznab API</label>
|
||||
<input type="text" name="torznab_apikey" value="${config['torznab_apikey']}" size="36">
|
||||
</div>
|
||||
<div class="row checkbox">
|
||||
<input id="torznab_enabled" type="checkbox" name="torznab_enabled" value="1" ${config['torznab_enabled']} /><label>Enabled</label>
|
||||
</div>
|
||||
</div>
|
||||
<%
|
||||
torznab_number = 2
|
||||
%>
|
||||
%for torznab in config['extra_torznabs']:
|
||||
<%
|
||||
if torznab[2] == '1' or torznab[2] == 1:
|
||||
torznab_enabled = "checked"
|
||||
else:
|
||||
torznab_enabled = ""
|
||||
%>
|
||||
<div class="config" id="torznab${torznab_number}">
|
||||
<div class="row">
|
||||
<label>Torznab Host</label>
|
||||
<input type="text" name="torznab_host${torznab_number}" value="${torznab[0]}" size="30">
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>Torznab API</label>
|
||||
<input type="text" name="Torznab_api${torznab_number}" value="${torznab[1]}" size="36">
|
||||
</div>
|
||||
<div class="row checkbox">
|
||||
<input id="torznab_enabled" type="checkbox" name="torznab_enabled${torznab_number}" value="1" ${torznab_enabled} /><label>Enabled</label>
|
||||
</div>
|
||||
<div class="row">
|
||||
<input type="button" class="remove" id="torznab${torznab_number}" value="Remove ${torznab[0]}">
|
||||
</div>
|
||||
</div>
|
||||
<%
|
||||
torznab_number += 1
|
||||
%>
|
||||
%endfor
|
||||
<input type="button" value="Add Torznab" class="add_torznab" id="add_torznab" />
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<div class="row checkbox left">
|
||||
<input id="use_piratebay" type="checkbox" class="bigcheck" name="use_piratebay" value="1" ${config['use_piratebay']} /><label for="use_piratebay"><span class="option">The Pirate Bay</span></label>
|
||||
@@ -2152,11 +2205,18 @@
|
||||
|
||||
var deletedNewznabs = 0;
|
||||
|
||||
$(".remove").click(function() {
|
||||
$(".removeNewznab").click(function() {
|
||||
$(this).parent().parent().remove();
|
||||
deletedNewznabs = deletedNewznabs + 1;
|
||||
});
|
||||
|
||||
var deletedTorznabs = 0;
|
||||
|
||||
$(".removeTorznab").click(function() {
|
||||
$(this).parent().parent().remove();
|
||||
deletedTorznabs = deletedTorznabs + 1;
|
||||
});
|
||||
|
||||
$("#modify_extras").click(openExtrasDialog);
|
||||
|
||||
$("#include_extras").click(function(){
|
||||
@@ -2179,7 +2239,7 @@
|
||||
$("#add_newznab").click(function() {
|
||||
var intId = $("#newznab_providers > div").size() + deletedNewznabs + 1;
|
||||
var formfields = $("<div class=\"config\" id=\"newznab" + intId + "\"><div class=\"row\"><label>Newznab Host</label><input type=\"text\" name=\"newznab_host" + intId + "\" size=\"30\"></div><div class=\"row\"><label>Newznab API</label><input type=\"text\" name=\"newznab_api" + intId + "\" size=\"36\"></div><div class=\"row checkbox\"><input type=\"checkbox\" name=\"newznab_enabled" + intId + "\" value=\"1\" checked /><label>Enabled</label></div>");
|
||||
var removeButton = $("<div class=\"row\"><input type=\"button\" class=\"remove\" value=\"Remove\" /></div>");
|
||||
var removeButton = $("<div class=\"row\"><input type=\"button\" class=\"removeNewznab\" value=\"Remove\" /></div>");
|
||||
removeButton.click(function() {
|
||||
$(this).parent().remove();
|
||||
deletedNewznabs = deletedNewznabs + 1;
|
||||
@@ -2190,6 +2250,20 @@
|
||||
$("#add_newznab").before(formfields);
|
||||
});
|
||||
|
||||
$("#add_torznab").click(function() {
|
||||
var intId = $("#torznab_providers > div").size() + deletedTorznabs + 1;
|
||||
var formfields = $("<div class=\"config\" id=\"torznab" + intId + "\"><div class=\"row\"><label>Torznab Host</label><input type=\"text\" name=\"torznab_host" + intId + "\" size=\"30\"></div><div class=\"row\"><label>Torznab API</label><input type=\"text\" name=\"torznab_api" + intId + "\" size=\"36\"></div><div class=\"row checkbox\"><input type=\"checkbox\" name=\"torznab_enabled" + intId + "\" value=\"1\" checked /><label>Enabled</label></div>");
|
||||
var removeButton = $("<div class=\"row\"><input type=\"button\" class=\"removeTorznab\" value=\"Remove\" /></div>");
|
||||
removeButton.click(function() {
|
||||
$(this).parent().remove();
|
||||
deletedTorznabs = deletedTorznabs + 1;
|
||||
|
||||
});
|
||||
formfields.append(removeButton);
|
||||
formfields.append("</div>");
|
||||
$("#add_torznab").before(formfields);
|
||||
});
|
||||
|
||||
$(".hpuser").keyup(function() {
|
||||
$(".hpuser").val($(this).val());
|
||||
});
|
||||
@@ -2206,6 +2280,7 @@
|
||||
initConfigCheckbox("#use_newznab");
|
||||
initConfigCheckbox("#use_nzbsorg");
|
||||
initConfigCheckbox("#use_omgwtfnzbs");
|
||||
initConfigCheckbox("#use_torznab");
|
||||
initConfigCheckbox("#use_kat");
|
||||
initConfigCheckbox("#use_piratebay");
|
||||
initConfigCheckbox("#use_oldpiratebay");
|
||||
|
||||
@@ -81,6 +81,7 @@ _CONFIG_DEFINITIONS = {
|
||||
'ENCODER_PATH': (str, 'General', ''),
|
||||
'EXTRAS': (str, 'General', ''),
|
||||
'EXTRA_NEWZNABS': (list, 'Newznab', ''),
|
||||
'EXTRA_TORZNABS': (list, 'Torznab', ''),
|
||||
'FILE_FORMAT': (str, 'General', 'Track Artist - Album [Year] - Title'),
|
||||
'FILE_PERMISSIONS': (str, 'General', '0644'),
|
||||
'FILE_UNDERSCORES': (int, 'General', 0),
|
||||
@@ -140,6 +141,10 @@ _CONFIG_DEFINITIONS = {
|
||||
'NEWZNAB_APIKEY': (str, 'Newznab', ''),
|
||||
'NEWZNAB_ENABLED': (int, 'Newznab', 1),
|
||||
'NEWZNAB_HOST': (str, 'Newznab', ''),
|
||||
'TORZNAB': (int, 'Torznab', 0),
|
||||
'TORZNAB_APIKEY': (str, 'Torznab', ''),
|
||||
'TORZNAB_ENABLED': (int, 'Torznab', 1),
|
||||
'TORZNAB_HOST': (str, 'Torznab', ''),
|
||||
'NMA_APIKEY': (str, 'NMA', ''),
|
||||
'NMA_ENABLED': (int, 'NMA', 0),
|
||||
'NMA_ONSNATCH': (int, 'NMA', 0),
|
||||
@@ -351,6 +356,25 @@ class Config(object):
|
||||
extra_newznabs.append(item)
|
||||
self.EXTRA_NEWZNABS = extra_newznabs
|
||||
|
||||
def get_extra_torznabs(self):
|
||||
""" Return the extra torznab tuples """
|
||||
extra_torznabs = list(
|
||||
itertools.izip(*[itertools.islice(self.EXTRA_TORZNABS, i, None, 3)
|
||||
for i in range(3)])
|
||||
)
|
||||
return extra_torznabs
|
||||
|
||||
def clear_extra_torznabs(self):
|
||||
""" Forget about the configured extra torznabs """
|
||||
self.EXTRA_TORZNABS = []
|
||||
|
||||
def add_extra_torznab(self, torznab):
|
||||
""" Add a new extra torznab """
|
||||
extra_torznabs = self.EXTRA_TORZNABS
|
||||
for item in torznab:
|
||||
extra_torznabs.append(item)
|
||||
self.EXTRA_TORZNABS = extra_torznabs
|
||||
|
||||
def __getattr__(self, name):
|
||||
"""
|
||||
Returns something from the ini unless it is a real property
|
||||
|
||||
@@ -228,7 +228,7 @@ 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.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)
|
||||
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)
|
||||
|
||||
results = []
|
||||
myDB = db.DBConnection()
|
||||
@@ -1086,6 +1086,68 @@ def searchTorrent(album, new=False, losslessOnly=False, albumlength=None, choose
|
||||
|
||||
return proxy_url
|
||||
|
||||
if headphones.CONFIG.TORZNAB:
|
||||
provider = "torznab"
|
||||
torznab_hosts = []
|
||||
|
||||
if headphones.CONFIG.TORZNAB_HOST and headphones.CONFIG.TORZNAB_ENABLED:
|
||||
torznab_hosts.append((headphones.CONFIG.TORZNAB_HOST, headphones.CONFIG.TORZNAB_APIKEY, headphones.CONFIG.TORZNAB_ENABLED))
|
||||
|
||||
for torznab_host in headphones.CONFIG.get_extra_torznabs():
|
||||
if torznab_host[2] == '1' or torznab_host[2] == 1:
|
||||
torznab_hosts.append(torznab_host)
|
||||
|
||||
if headphones.CONFIG.PREFERRED_QUALITY == 3 or losslessOnly:
|
||||
categories = "3040"
|
||||
elif headphones.CONFIG.PREFERRED_QUALITY == 1 or allow_lossless:
|
||||
categories = "3040,3010"
|
||||
else:
|
||||
categories = "3010"
|
||||
|
||||
if album['Type'] == 'Other':
|
||||
categories = "3030"
|
||||
logger.info("Album type is audiobook/spokenword. Using audiobook category")
|
||||
|
||||
for torznab_host in torznab_hosts:
|
||||
|
||||
provider = torznab_host[0]
|
||||
|
||||
# Request results
|
||||
logger.info('Parsing results from %s using search term: %s' % (torznab_host[0],term))
|
||||
|
||||
headers = {'User-Agent': USER_AGENT}
|
||||
params = {
|
||||
"t": "search",
|
||||
"apikey": torznab_host[1],
|
||||
"cat": categories,
|
||||
"maxage": headphones.CONFIG.USENET_RETENTION,
|
||||
"q": term
|
||||
}
|
||||
|
||||
data = request.request_feed(
|
||||
url=torznab_host[0] + '/api?',
|
||||
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)
|
||||
else:
|
||||
for item in data.entries:
|
||||
try:
|
||||
url = item.link
|
||||
title = item.title
|
||||
size = int(item.links[1]['length'])
|
||||
if all(word.lower() in title.lower() for word in term.split()):
|
||||
logger.info('Found %s. Size: %s' % (title, helpers.bytes_to_mb(size)))
|
||||
resultlist.append((title, size, url, provider, 'torrent', True))
|
||||
else:
|
||||
logger.info('Skipping %s, not all search term words found' % title)
|
||||
|
||||
except Exception as e:
|
||||
logger.exception("An unknown error occurred trying to parse the feed: %s" % e)
|
||||
|
||||
if headphones.CONFIG.KAT:
|
||||
provider = "Kick Ass Torrents"
|
||||
ka_term = term.replace("!", "")
|
||||
|
||||
@@ -1065,6 +1065,11 @@ class WebInterface(object):
|
||||
"newznab_apikey": headphones.CONFIG.NEWZNAB_APIKEY,
|
||||
"newznab_enabled": checked(headphones.CONFIG.NEWZNAB_ENABLED),
|
||||
"extra_newznabs": headphones.CONFIG.get_extra_newznabs(),
|
||||
"use_torznab": checked(headphones.CONFIG.TORZNAB),
|
||||
"torznab_host": headphones.CONFIG.TORZNAB_HOST,
|
||||
"torznab_apikey": headphones.CONFIG.TORZNAB_APIKEY,
|
||||
"torznab_enabled": checked(headphones.CONFIG.TORZNAB_ENABLED),
|
||||
"extra_torznabs": headphones.CONFIG.get_extra_torznabs(),
|
||||
"use_nzbsorg": checked(headphones.CONFIG.NZBSORG),
|
||||
"nzbsorg_uid": headphones.CONFIG.NZBSORG_UID,
|
||||
"nzbsorg_hash": headphones.CONFIG.NZBSORG_HASH,
|
||||
@@ -1278,7 +1283,7 @@ class WebInterface(object):
|
||||
# Handle the variable config options. Note - keys with False values aren't getting passed
|
||||
|
||||
checked_configs = [
|
||||
"launch_browser", "enable_https", "api_enabled", "use_blackhole", "headphones_indexer", "use_newznab", "newznab_enabled",
|
||||
"launch_browser", "enable_https", "api_enabled", "use_blackhole", "headphones_indexer", "use_newznab", "newznab_enabled", "use_torznab", "torznab_enabled",
|
||||
"use_nzbsorg", "use_omgwtfnzbs", "use_kat", "use_piratebay", "use_oldpiratebay", "use_mininova", "use_waffles", "use_rutracker",
|
||||
"use_whatcd", "preferred_bitrate_allow_lossless", "detect_bitrate", "ignore_clean_releases", "freeze_db", "cue_split", "move_files",
|
||||
"rename_files", "correct_metadata", "cleanup_files", "keep_nfo", "add_album_art", "embed_album_art", "embed_lyrics",
|
||||
@@ -1316,6 +1321,21 @@ class WebInterface(object):
|
||||
del kwargs[key]
|
||||
extra_newznabs.append((newznab_host, newznab_api, newznab_enabled))
|
||||
|
||||
extra_torznabs = []
|
||||
for kwarg in [x for x in kwargs if x.startswith('torznab_host')]:
|
||||
torznab_host_key = kwarg
|
||||
torznab_number = kwarg[12:]
|
||||
if len(torznab_number):
|
||||
torznab_api_key = 'torznab_api' + torznab_number
|
||||
torznab_enabled_key = 'torznab_enabled' + torznab_number
|
||||
torznab_host = kwargs.get(torznab_host_key, '')
|
||||
torznab_api = kwargs.get(torznab_api_key, '')
|
||||
torznab_enabled = int(kwargs.get(torznab_enabled_key, 0))
|
||||
for key in [torznab_host_key, torznab_api_key, torznab_enabled_key]:
|
||||
if key in kwargs:
|
||||
del kwargs[key]
|
||||
extra_torznabs.append((torznab_host, torznab_api, torznab_enabled))
|
||||
|
||||
# Convert the extras to list then string. Coming in as 0 or 1 (append new extras to the end)
|
||||
temp_extras_list = []
|
||||
|
||||
@@ -1346,6 +1366,11 @@ class WebInterface(object):
|
||||
for extra_newznab in extra_newznabs:
|
||||
headphones.CONFIG.add_extra_newznab(extra_newznab)
|
||||
|
||||
headphones.CONFIG.clear_extra_torznabs()
|
||||
headphones.CONFIG.process_kwargs(kwargs)
|
||||
for extra_torznab in extra_torznabs:
|
||||
headphones.CONFIG.add_extra_torznab(extra_torznab)
|
||||
|
||||
# Sanity checking
|
||||
if headphones.CONFIG.SEARCH_INTERVAL and headphones.CONFIG.SEARCH_INTERVAL < 360:
|
||||
logger.info("Search interval too low. Resetting to 6 hour minimum")
|
||||
|
||||
Reference in New Issue
Block a user