FIX:(#1905) Unicode errors when logging and system language is not a subset of english, IMP: Added post-processing queue (currently just for forceProcess api, but will be used by default for all post-processing actions soon), IMP: Multiple Torznab support added, IMP: Logging values for number of files and size/file added to config, IMP: Pushover notifications can be sent to specific device now, IMP: Added nzbget, newznab, nzb.su and dognzb test options, IMP: Added graphical checkmark/x when performing various tests (providers, downloaders, notifiers) within configuration, IMP: Removed some more unnecessary logging lines from searches

This commit is contained in:
evilhero 2018-04-06 13:46:39 -04:00
parent 6f57c19290
commit a895f3f8d3
18 changed files with 1045 additions and 404 deletions

View File

@ -62,6 +62,18 @@ def main():
if not mylar.SYS_ENCODING or mylar.SYS_ENCODING in ('ANSI_X3.4-1968', 'US-ASCII', 'ASCII'):
mylar.SYS_ENCODING = 'UTF-8'
#setup logger for non-english
try:
language = locale.getdefaultlocale()[0][:2]
except:
language = 'en'
mylar.LOG_LANG = language
if language != 'en':
print 'language detected as non-English. Forcing specific logging module - errors WILL NOT be captured in the logs'
else:
print 'log language set to %s' % mylar.LOG_LANG
# Set up and gather command line arguments
parser = argparse.ArgumentParser(description='Automated Comic Book Downloader')
subparsers = parser.add_subparsers(title='Subcommands', dest='maintenance')
@ -98,11 +110,21 @@ def main():
if args.verbose:
mylar.VERBOSE = True
if args.quiet:
#print 'Verbose/Debugging mode enabled...'
#mylar.LOG_LEVEL = 2
elif args.quiet:
mylar.QUIET = True
#print 'Quiet mode enabled...'
#mylar.LOG_LEVEL = 0
else:
#print 'Normal logging mode enabled...'
#mylar.LOG_LEVEL = 1
mylar.VERBOSE = False
# Do an intial setup of the logger.
logger.initLogger(console=not mylar.QUIET, log_dir=False, init=True, verbose=mylar.VERBOSE)
if mylar.LOG_LANG == 'en':
logger.initLogger(console=not mylar.QUIET, log_dir=False, init=True, verbose=mylar.VERBOSE)
#logger.mylar_log.initLogger(loglevel=mylar.LOG_LEVEL)
if args.daemon:
if sys.platform == 'win32':
@ -125,7 +147,7 @@ def main():
except IOError, e:
raise SystemExit("Unable to write PID file: %s [%d]" % (e.strerror, e.errno))
else:
logger.warn("Not running in daemon mode. PID file creation disabled.")
print("Not running in daemon mode. PID file creation disabled.")
if args.datadir:
mylar.DATA_DIR = args.datadir
@ -147,6 +169,19 @@ def main():
else:
mylar.NOWEEKLY = False
# Put the database in the DATA_DIR
mylar.DB_FILE = os.path.join(mylar.DATA_DIR, 'mylar.db')
# Read config and start logging
if mylar.MAINTENANCE is False:
print('Initializing startup sequence....')
#try:
mylar.initialize(mylar.CONFIG_FILE)
#except Exception as e:
# print e
# raise SystemExit('FATAL ERROR')
if mylar.MAINTENANCE is False:
filechecker.validateAndCreateDirectory(mylar.DATA_DIR, True)
@ -154,9 +189,6 @@ def main():
if not os.access(mylar.DATA_DIR, os.W_OK):
raise SystemExit('Cannot write to the data directory: ' + mylar.DATA_DIR + '. Exiting...')
# Put the database in the DATA_DIR
mylar.DB_FILE = os.path.join(mylar.DATA_DIR, 'mylar.db')
# backup the db and configs before they load.
if args.backup:
print '[AUTO-BACKUP] Backing up .db and config.ini files for safety.'
@ -198,17 +230,6 @@ def main():
i += 1
# Read config and start logging
if mylar.MAINTENANCE is False:
logger.info('Initializing startup sequence....')
try:
mylar.initialize(mylar.CONFIG_FILE)
except Exception as e:
print e
raise SystemExit('FATAL ERROR')
# Rename the main thread
threading.currentThread().name = "MAIN"

View File

@ -395,6 +395,7 @@
</div>
<div align="center" class="row">
<img name="sabnzbd_statusicon" id="sabnzbd_statusicon" src="interfaces/default/images/successs.png" style="float:right;visibility:hidden;" height="20" width="20" />
<input type="button" value="Test SABnzbd" id="test_sab" style="float:center" /></br>
<input type="text" name="sabstatus" style="text-align:center; font-size:11px;" id="sabstatus" size="50" DISABLED />
</div>
@ -403,20 +404,20 @@
<fieldset id="nzbget_options">
<div class="row">
<label>NZBGet Host:</label>
<input type="text" name="nzbget_host" value="${config['nzbget_host']}" size="30">
<input type="text" id="nzbget_host" name="nzbget_host" value="${config['nzbget_host']}" size="30">
<small>usually http://localhost</small>
</div>
<div class="row">
<label>NZBGet Port:</label>
<input type="text" name="nzbget_port" value="${config['nzbget_port']}" size="36">
<input type="text" id="nzbget_port" name="nzbget_port" value="${config['nzbget_port']}" size="36">
</div>
<div class="row">
<label>NZBGet Username:</label>
<input type="text" name="nzbget_username" value="${config['nzbget_user']}" size="20">
<input type="text" id="nzbget_username" name="nzbget_username" value="${config['nzbget_user']}" size="20">
</div>
<div class="row">
<label>NZBGet Password:</label>
<input type="password" name="nzbget_password" value="${config['nzbget_pass']| h}" size="20">
<input type="password" id="nzbget_password" name="nzbget_password" value="${config['nzbget_pass']| h}" size="20">
</div>
<div class="row">
<label>NZBGet Download Directory</label>
@ -446,6 +447,12 @@
<input type="checkbox" id="nzbget_client_post_processing" onclick="initConfigCheckbox($this));" name="nzbget_client_post_processing" value="1" ${config['nzbget_client_post_processing']} /><label>Enable Completed Download Handling<label>
<small>The category label above is used to when completed download handling is enabled</small>
</div>
<div align="center" class="row">
<img name="nzbget_statusicon" id="nzbget_statusicon" src="interfaces/default/images/successs.png" style="float:right;visibility:hidden;" height="20" width="20" />
<input type="button" value="Test NZBGet" id="test_nzbget" style="float:center" /></br>
<input type="text" name="nzbgetstatus" style="text-align:center; font-size:11px;" id="nzbgetstatus" size="50" DISABLED />
</div>
</fieldset>
<fieldset id="blackhole_options">
@ -595,6 +602,7 @@
<small>Automatically start torrent on successful loading within rtorrent client</small>
</div>
<div class="row">
<img name="rtorrent_statusicon" id="rtorrent_statusicon" src="interfaces/default/images/successs.png" style="float:right;visibility:hidden;" height="20" width="20" />
<input type="button" value="Test Connection" id="rtorrent_test" />
</div>
</fieldset>
@ -692,7 +700,7 @@
</div>
<div class="config">
<div class="row checkbox">
<input type="checkbox" name="nzbsu_verify" value="1" ${config['nzbsu_verify']} /><label>Verify SSL</label>
<input type="checkbox" name="nzbsu_verify" id="nzbsu_verify" value="1" ${config['nzbsu_verify']} /><label>Verify SSL</label>
</div>
<div class="row">
<label>NZB.SU UID</label>
@ -701,8 +709,12 @@
</div>
<div class="row">
<label>NZB.SU API</label>
<input type="text" name="nzbsu_apikey" value="${config['nzbsu_api']}" size="36">
<input type="text" name="nzbsu_apikey" id="nzbsu_apikey" value="${config['nzbsu_api']}" size="36">
</div>
<div>
<img name="nzbsu_statusicon" id="nzbsu_statusicon" src="interfaces/default/images/success.png" style="float:right;visibility:hidden;" height="20" width="20" />
<input type="button" class="newznabtest" value="Test Connection" id="test_nzbsu" name="test_nzbsu" style="float:right;margin-right:10px;" />
</div>
</div>
</fieldset>
@ -712,12 +724,16 @@
</div>
<div class="config">
<div class="row checkbox">
<input id="dognzb_verify" type="checkbox" name="dognzb_verify" value="1" ${config['dognzb_verify']} /><label>Verify SSL</label>
<input id="dognzb_verify" type="checkbox" name="dognzb_verify" id="dognzb_verify" value="1" ${config['dognzb_verify']} /><label>Verify SSL</label>
</div>
<div class="row">
<label>DOGNZB API</label>
<input type="text" name="dognzb_apikey" value="${config['dognzb_api']}" size="36">
</div>
<input type="text" name="dognzb_apikey" id="dognzb_apikey" value="${config['dognzb_api']}" size="36">
</div>
<div>
<img name="dognzb_statusicon" id="dognzb_statusicon" src="interfaces/default/images/success.png" style="float:right;visibility:hidden;" height="20" width="20" />
<input type="button" class="newznabtest" value="Test Connection" id="test_dognzb" name="test_dognzb" style="float:right;margin-right:10px;" />
</div>
</div>
</fieldset>
@ -780,6 +796,7 @@
<small>( monitor the NEW releases feed & your personal notifications )</small>
</div>
<div align="center" class="row">
<img name="test32p_statusicon" id="test32p_statusicon" src="interfaces/default/images/success.png" style="float:right;visibility:hidden;" height="20" width="20" />
<input type="button" value="Test Connection" id="test_32p" style="float:center" /></br>
<input type="text" name="status32p" style="text-align:center; font-size:11px;" id="status32p" size="50" DISABLED />
</div>
@ -797,24 +814,51 @@
<div class="row checkbox left clearfix">
<input type="checkbox" id="enable_torznab" onclick="initConfigCheckbox($(this));" name="enable_torznab" value=1 ${config['enable_torznab']} /><label>Enable Torznab</label>
</div>
<div class="config">
<div class="row">
<label>Torznab Name</label>
<input type="text" name="torznab_name" value="${config['torznab_name']}" size="30">
</div>
<div class="row">
<label>Torznab Host</label>
<input type="text" name="torznab_host" value="${config['torznab_host']}" size="30">
</div>
<div class="row">
<label>Torznab API</label>
<input type="text" name="torznab_apikey" value="${config['torznab_apikey']}" size="36">
</div>
<div class="row">
<label>Torznab Category</label>
<input type="text" name="torznab_category" value="${config['torznab_category']}" size="12">
</div>
</div>
<div id="torznab_providers">
<%
torznab_number = 1
%>
%for torznab in config['extra_torznabs']:
<%
if torznab[4] == '1' or torznab[4] == 1:
torznab_enabled = "checked"
else:
torznab_enabled = ""
%>
<div class="config" id="torznab${torznab_number}">
<div class="row">
<label>Torznab Name</label>
<input type="text" name="torznab_name${torznab_number}" id="torznab_name${torznab_number}" value="${torznab[0]}" size="30">
</div>
<div class="row">
<label>Torznab Host</label>
<input type="text" name="torznab_host${torznab_number}" id="torznab_host${torznab_number}" value="${torznab[1]}" size="30">
</div>
<div class="row">
<label>Torznab API</label>
<input type="text" name="torznab_apikey${torznab_number}" id="torznab_apikey${torznab_number}" value="${torznab[2]}" size="36">
</div>
<div class="row">
<label>Torznab Category</label>
<input type="text" name="torznab_category${torznab_number}" id="torznab_category${torznab_number}" value="${torznab[3]}" size="12">
</div>
<div class="row checkbox">
<input id="torznab_enabled${torznab_number}" type="checkbox" name="torznab_enabled${torznab_number}" value="1" ${torznab_enabled} /><label>Enabled</label>
<img name="torznabstatus${torznab_number}" id="torznabstatus${torznab_number}" src="interfaces/default/images/success.png" style="float:right;visibility:hidden;" height="20" width="20" />
<input type="button" class="torznabtest" value="Test ${torznab[0]}" id="torznab_test${torznab_number}" name="torznab_test${torznab_number}" style="float:right;margin-right:10px;" />
</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>
</div>
</fieldset>
@ -864,9 +908,9 @@
<small>( only needed for RSS feed )</small>
</div>
<div class="row checkbox">
<input id="newznab_enabled" type="checkbox" name="newznab_enabled${newznab_number}" value="1" ${newznab_enabled} /><label>Enabled</label>
<input type="button" value="Test ${newznab[0]}" name="${newznab_number}" id="newznabtest" style="float:center" />
<img name="newznabstatus${newznab_number}" id="newznabstatus${newznab_number}" src="interfaces/default/images/checkmark.png" style="vertical-align: middle; margin: 3px; margin-top: -1px; display: none" height="10" width="10">
<input id="newznab_enabled${newznab_number}" type="checkbox" name="newznab_enabled${newznab_number}" value="1" ${newznab_enabled} /><label>Enabled</label>
<img name="newznabstatus${newznab_number}" id="newznabstatus${newznab_number}" src="interfaces/default/images/success.png" style="float:right;visibility:hidden;" height="20" width="20" />
<input type="button" class="newznabtest" value="Test ${newznab[0]}" id="newznab_test${newznab_number}" name="newznab_test${newznab_number}" style="float:right;margin-right:10px;" />
</div>
<div class="row">
<input type="button" class="remove" id="newznab${newznab_number}" value="Remove ${newznab[0]}">
@ -903,9 +947,9 @@
<fieldset>
<legend>Quality</legend>
<div class="row radio left clearfix">
<input type="radio" style="vertical-align: middle; margin: 3px; margin-top: -1px;" name="preferred_quality" value="1" ${config['pref_qual_1']} /><label>cbr</label>
<input type="radio" style="vertical-align: middle; margin: 3px; margin-top: -1px;" name="preferred_quality" value="2" ${config['pref_qual_2']} /><label>cbz</label>
<input type="radio" style="vertical-align: middle; margin: 3px; margin-top: -1px;" name="preferred_quality" value="0" ${config['pref_qual_0']} /><label>Whichever - just get it</label>
<input type="radio" style="vertical-align: middle; margin: 3px; margin-top: -1px;" name="preferred_quality" value="1" ${config['pref_qual_1']} /><label>cbr</label>
<input type="radio" style="vertical-align: middle; margin: 3px; margin-top: -1px;" name="preferred_quality" value="2" ${config['pref_qual_2']} /><label>cbz</label>
<input type="radio" style="vertical-align: middle; margin: 3px; margin-top: -1px;" name="preferred_quality" value="0" ${config['pref_qual_0']} /><label>Whichever - just get it</label>
</div>
</fieldset>
<fieldset>
@ -1209,7 +1253,7 @@
</div>
<div id="prowloptions">
<div class="row">
<label>API key</label><input type="text" name="prowl_keys" value="${config['prowl_keys']}" size="50">
<label>API key</label><input type="text" id="prowl_keys" name="prowl_keys" value="${config['prowl_keys']}" size="50">
</div>
<div class="row checkbox">
<input type="checkbox" name="prowl_onsnatch" value="1" ${config['prowl_onsnatch']} /><label>Notify on snatch?</label>
@ -1219,6 +1263,7 @@
<input type="text" name="prowl_priority" value="${config['prowl_priority']}" size="2">
</div>
<div class="row">
<img name="prowl_statusicon" id="prowl_statusicon" src="interfaces/default/images/successs.png" style="float:right;visibility:hidden;" height="20" width="20" />
<input type="button" value="Test PROWL" id="prowl_test" />
</div>
</div>
@ -1263,6 +1308,7 @@
</select>
</div>
<div align="center" class="row">
<img name="nma_statusicon" id="nma_statusicon" src="interfaces/default/images/successs.png" style="float:right;visibility:hidden;" height="20" width="20" />
<input type="button" value="Test NMA" id="nma_test" style="float:center" /></br>
<input type="text" name="nmastatus" style="text-align:center; font-size:11px;" id="nmastatus" size="55" DISABLED />
</div>
@ -1281,6 +1327,9 @@
<div class="row">
<label>User key</label><input type="text" name="pushover_userkey" id="pushover_userkey" value="${config['pushover_userkey']}" size="50">
</div>
<div class="row">
<label>Device</label><input type="text" title="Specific Device ID to push notifications to" name="pushover_device" id="pushover_device" value="${config['pushover_device']}" size="50">
</div>
<div class="row checkbox">
<input type="checkbox" name="pushover_onsnatch" value="1" ${config['pushover_onsnatch']} /><label>Notify on snatch?</label>
</div>
@ -1289,6 +1338,7 @@
<input type="text" name="pushover_priority" value="${config['pushover_priority']}" size="2">
</div>
<div align="center" class="row">
<img name="pushover_statusicon" id="pushover_statusicon" src="interfaces/default/images/successs.png" style="float:right;visibility:hidden;" height="20" width="20" />
<input type="button" value="Test Pushover" id="pushover_test" style="float:center" /></br>
<input type="text" name="pushoverstatus" style="text-align:center; font-size:11px;" id="pushoverstatus" size="55" DISABLED />
</div>
@ -1308,6 +1358,7 @@
<label>Boxcar Token</label>
<input type="text" name="boxcar_token" value="${config['boxcar_token']}" size="30">
<div class="row">
<img name="boxcar_statusicon" id="boxcar_statusicon" src="interfaces/default/images/successs.png" style="float:right;visibility:hidden;" height="20" width="20" />
<input type="button" value="Test Boxcar" id="boxcar_test" />
</div>
</div>
@ -1339,6 +1390,7 @@
<small>Send to all subscribers of the channel with this tag (Optional)</small>
</div>
<div align="center" class="row">
<img name="pushbullet_statusicon" id="pushbullet_statusicon" src="interfaces/default/images/successs.png" style="float:right;visibility:hidden;" height="20" width="20" />
<input type="button" value="Test Pushbullet" id="pushbullet_test" style="float:center" /></br>
<input type="text" name="pbstatus" style="text-align:center; font-size:11px;" id="pbstatus" size="55" DISABLED />
</div>
@ -1361,6 +1413,7 @@
<input type="checkbox" name="telegram_onsnatch" value="1" ${config['telegram_onsnatch']} /><label>Notify on snatch?</label>
</div>
<div align="center" class="row">
<img name="telegram_statusicon" id="telegram_statusicon" src="interfaces/default/images/successs.png" style="float:right;visibility:hidden;" height="20" width="20" />
<input type="button" value="Test Telegram" id="telegram_test" style="float:center" /></br>
<input type="text" name="telegramstatus" style="text-align:center; font-size:11px;" id="telegramstatus" size="55" DISABLED />
</div>
@ -1380,6 +1433,7 @@
<input type="checkbox" name="slack_onsnatch" value="1" ${config['slack_onsnatch']} /><label>Notify on snatch?</label>
</div>
<div align="center" class="row">
<img name="slack_statusicon" id="slack_statusicon" src="interfaces/default/images/successs.png" style="float:right;visibility:hidden;" height="20" width="20" />
<input type="button" value="Test Slack" id="slack_test" style="float:center" /></br>
<input type="text" name="slackstatus" style="text-align:center; font-size:11px;" id="slackstatus" size="55" DISABLED />
</div>
@ -1820,6 +1874,7 @@
});
var deletedNewznabs = 0;
var deletedTorznabs = 0;
$(".remove").click(function() {
$(this).parent().parent().remove();
@ -1843,6 +1898,7 @@
};
$("#test_32p").click(function(){
var imagechk = document.getElementById("test32p_statusicon");
$.get('test_32p',
function(data){
if (data.error != undefined) {
@ -1854,14 +1910,26 @@
inkd = numberWithCommas(inkd);
$('#status32p').val(obj['status']);
$('#inkdrops32p span').text('Inkdrops Available: '+inkd);
$('#ajaxMsg').html("<div class='msg'><span class='ui-icon ui-icon-check'></span>"+data+"</div>");
if ( data.indexOf("Successfully") > -1){
imagechk.src = "";
imagechk.src = "interfaces/default/images/success.png";
imagechk.style.visibility = "visible";
} else {
imagechk.src = "";
imagechk.src = "interfaces/default/images/fail.png";
imagechk.style.visibility = "visible";
}
});
$('#ajaxMsg').addClass('success').fadeIn().delay(3000).fadeOut();
});
$('#test_sab').click(function () {
var sabhost = document.getElementById('sab_host').value;
var sabuser = document.getElementById('sab_username').value;
var sabpass = document.getElementById('sab_password').value;
var sabapi = document.getElementById('sab_apikey').value;
var imagechk = document.getElementById("sabnzbd_statusicon");
var sabhost = document.getElementById("sab_host").value;
var sabuser = document.getElementById("sab_username").value;
var sabpass = document.getElementById("sab_password").value;
var sabapi = document.getElementById("sab_apikey").value;
$.get("SABtest",
{ sabhost: sabhost, sabusername: sabuser, sabpassword: sabpass, sabapikey: sabapi },
function(data){
@ -1870,8 +1938,44 @@
return;
}
$('#sabstatus').val(data);
// $('#sab_apikey').val(data);
$('#ajaxMsg').html("<div class='msg'><span class='ui-icon ui-icon-check'></span>"+data+"</div>");
if ( data.indexOf("Successfully") > -1){
imagechk.src = "";
imagechk.src = "interfaces/default/images/success.png";
imagechk.style.visibility = "visible";
} else {
imagechk.src = "";
imagechk.src = "interfaces/default/images/fail.png";
imagechk.style.visibility = "visible";
}
});
$('#ajaxMsg').addClass('success').fadeIn().delay(3000).fadeOut();
});
$('#test_nzbget').click(function () {
var imagechk = document.getElementById("nzbget_statusicon");
var nzbhost = document.getElementById("nzbget_host").value;
var nzbport = document.getElementById("nzbget_port").value;
var nzbuser = document.getElementById("nzbget_username").value;
var nzbpass = document.getElementById("nzbget_password").value;
$.get("NZBGet_test",
{ nzbhost: nzbhost, nzbport: nzbport, nzbusername: nzbuser, nzbpassword: nzbpass },
function(data){
if (data.error != undefined) {
alert(data.error);
return;
}
$('#nzbgetstatus').val(data);
$('#ajaxMsg').html("<div class='msg'><span class='ui-icon ui-icon-check'></span>"+data+"</div>");
if ( data.indexOf("Successfully") > -1){
imagechk.src = "";
imagechk.src = "interfaces/default/images/success.png";
imagechk.style.visibility = "visible";
} else {
imagechk.src = "";
imagechk.src = "interfaces/default/images/fail.png";
imagechk.style.visibility = "visible";
}
});
$('#ajaxMsg').addClass('success').fadeIn().delay(3000).fadeOut();
});
@ -1929,16 +2033,32 @@
$("#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 Name</label><input type=\"text\" name=\"newznab_name" + intId + "\" size=\"36\"></div><div class=\"row\"><label>Newznab Host</label><input type=\"text\" name=\"newznab_host" + intId + "\" + value=\"http://\" + size=\"30\"></div><div class=\"row checkbox\"><input type=\"checkbox\" name=\"newznab_verify" + intId + "\" value=\"0\" checked /><label>Verify SSL</label></div><div class=\"row\"><label>Newznab API</label><input type=\"text\" name=\"newznab_api" + intId + "\" size=\"36\"></div><div class=\"row\"><label>Newznab UID</label><input type=\"text\" name=\"newznab_uid" + intId + "\" size=\"15\"></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>");
removeButton.click(function() {
var newzformfields = $("<div class=\"config\" id=\"newznab" + intId + "\"><div class=\"row\"><label>Newznab Name</label><input type=\"text\" id=\"newznab_name" + intId + "\" name=\"newznab_name" + intId + "\" size=\"36\"></div><div class=\"row\"><label>Newznab Host</label><input type=\"text\" id=\"newznab_host" + intId + "\" name=\"newznab_host" + intId + "\" + value=\"http://\" + size=\"30\"></div><div class=\"row checkbox\"><input type=\"checkbox\" id=\"newznab_verify" + intId + "\" name=\"newznab_verify" + intId + "\" value=\"0\" checked /><label>Verify SSL</label></div><div class=\"row\"><label>Newznab API</label><input type=\"text\" id=\"newznab_api" + intId + "\" name=\"newznab_api" + intId + "\" size=\"36\"></div><div class=\"row\"><label>Newznab UID</label><input type=\"text\" id=\"newznab_uid" + intId + "\" name=\"newznab_uid" + intId + "\" size=\"15\"></div><div class=\"row checkbox\"><input type=\"checkbox\" name=\"newznab_enabled" + intId + "\" value=\"1\" checked /><label>Enabled</label></div>");
var newztestButton = $("<div class=\"row\"><img name=\"newznabstatus" + intId + "\" id=\"newznabstatus" + intId + "\" src=\"interfaces/default/images/success.png\" style=\"float:right;visibility:hidden;\" height=\"20\" width=\"20\" /><input type=\"button\" class=\"newznabtest\" value=\"Test\" id=\"newznab_test" + intId + "\" name=\"newznab_test" + intId + "\" style=\"float:right;margin-right:10px;\" /></div>");
var newzremoveButton = $("<div class=\"row\"><input type=\"button\" class=\"remove\" value=\"Remove\" /></div>");
newzremoveButton.click(function() {
$(this).parent().remove();
deletedNewznabs = deletedNewznabs + 1;
});
formfields.append(removeButton);
formfields.append("</div>");
$("#add_newznab").before(formfields);
newzformfields.append(newztestButton);
newzformfields.append(newzremoveButton);
newzformfields.append("</div>");
$("#add_newznab").before(newzformfields);
});
$("#add_torznab").click(function() {
var intId = $("#torznab_providers > div").size() + deletedTorznabs + 1;
var torformfields = $("<div class=\"config\" id=\"torznab" + intId + "\"><div class=\"row\"><label>Torznab Name</label><input type=\"text\" id=\"torznab_name" + intId + "\" name=\"torznab_name" + intId + "\" size=\"36\"></div><div class=\"row\"><label>Torznab Host</label><input type=\"text\" id=\"torznab_host" + intId + "\" name=\"torznab_host" + intId + "\" + value=\"http://\" + size=\"30\"></div><div class=\"row\"><label>Torznab API</label><input type=\"text\" id=\"torznab_apikey" + intId + "\" name=\"torznab_apikey" + intId + "\" size=\"36\"></div><div class=\"row\"><label>Torznab Category</label><input type=\"text\" id=\"torznab_category" + intId + "\" name=\"torznab_category" + intId + "\" size=\"36\"></div><div class=\"row checkbox\"><input type=\"checkbox\" name=\"torznab_enabled" + intId + "\" value=\"1\" checked /><label>Enabled</label></div>");
var tortestButton = $("<div class=\"row\"><img name=\"torznabstatus" + intId + "\" id=\"torznabstatus" + intId + "\" src=\"interfaces/default/images/success.png\" style=\"float:right;visibility:hidden;\" height=\"20\" width=\"20\" /><input type=\"button\" class=\"torznabtest\" value=\"Test\" id=\"torznab_test" + intId + "\" name=\"torznab_test" + intId + "\" style=\"float:right;margin-right:10px;\" /></div>");
var torremoveButton = $("<div class=\"row\"><input type=\"button\" class=\"remove\" value=\"Remove\" /></div>");
torremoveButton.click(function() {
$(this).parent().remove();
deletedTorznabs = deletedTorznabs + 1;
});
torformfields.append(tortestButton);
torformfields.append(torremoveButton);
torformfields.append("</div>");
$("#add_torznab").before(torformfields);
});
function addAction() {
@ -1946,14 +2066,14 @@
};
$('#rtorrent_test').click(function () {
var host = document.getElementById('rtorrent_host').value;
var username = document.getElementById('rtorrent_username').value;
var password = document.getElementById('rtorrent_password').value;
var auth = document.getElementById('rtorrent_authentication').value;
var verify = document.getElementById('rtorrent_verify').value;
var ssl = document.getElementById('rtorrent_ssl').value;
var rpc_url = document.getElementById('rtorrent_rpc_url').value;
alert(host);
var imagechk = document.getElementById("rtorrent_statusicon");
var host = document.getElementById("rtorrent_host").value;
var username = document.getElementById("rtorrent_username").value;
var password = document.getElementById("rtorrent_password").value;
var auth = document.getElementById("rtorrent_authentication").value;
var verify = document.getElementById("rtorrent_verify").value;
var ssl = document.getElementById("rtorrent_ssl").value;
var rpc_url = document.getElementById("rtorrent_rpc_url").value;
$.get("testrtorrent",
{ host: host, username: username, password: password, auth: auth, verify: verify, ssl: ssl, rpc_url: rpc_url },
function(data){
@ -1963,16 +2083,40 @@
}
//$('#rtorrentstatus').val(data);
$('#ajaxMsg').html("<div class='msg'><span class='ui-icon ui-icon-check'></span>"+data+"</div>");
if ( data.indexOf("Successfully") > -1){
imagechk.src = "";
imagechk.src = "interfaces/default/images/success.png";
imagechk.style.visibility = "visible";
} else {
imagechk.src = "";
imagechk.src = "interfaces/default/images/fail.png";
imagechk.style.visibility = "visible";
}
});
$('#ajaxMsg').addClass('success').fadeIn().delay(3000).fadeOut();
});
$('#newznabtest').click(function () {
var newznab = document.getElementById("newznabtest").getAttribute("name");
var name = document.getElementById("newznab_name"+newznab).value;
var host = document.getElementById("newznab_host"+newznab).value;;
var ssl = document.getElementById("newznab_verify"+newznab).value;
var apikey = document.getElementById("newznab_api"+newznab).value;
$(".newznabtest").click(function () {
var newznab = this.attributes["name"].value.replace('newznab_test', '');
if ( newznab.indexOf("test_dognzb") > -1) {
var imagechk = document.getElementById("dognzb_statusicon");
var name = 'DOGnzb';
var host = 'https://api.dognzb.cr';
var ssl = document.getElementById("dognzb_verify").value;
var apikey = document.getElementById("dognzb_apikey").value;
} else if ( newznab.indexOf("test_nzbsu") > -1) {
var imagechk = document.getElementById("nzbsu_statusicon");
var name = 'nzb.su';
var host = 'https://api.nzb.su';
var ssl = document.getElementById("nzbsu_verify").value;
var apikey = document.getElementById("nzbsu_apikey").value;
} else {
var imagechk = document.getElementById("newznabstatus"+newznab);
var name = document.getElementById("newznab_name"+newznab).value;
var host = document.getElementById("newznab_host"+newznab).value;;
var ssl = document.getElementById("newznab_verify"+newznab).value;
var apikey = document.getElementById("newznab_api"+newznab).value;
}
$.get("testnewznab",
{ name: name, host: host, ssl: ssl, apikey: apikey },
function(data){
@ -1980,14 +2124,50 @@
alert(data.error);
return;
}
document.getElementById("newznabstatus" + newznab).style.display = "inline";
$('#ajaxMsg').html("<div class='msg'><span class='ui-icon ui-icon-check'></span>"+data+"</div>");
if ( data.indexOf("Successfully") > -1){
imagechk.src = "";
imagechk.src = "interfaces/default/images/success.png";
imagechk.style.visibility = "visible";
} else {
imagechk.src = "";
imagechk.src = "interfaces/default/images/fail.png";
imagechk.style.visibility = "visible";
}
});
$('#ajaxMsg').addClass('success').fadeIn().delay(3000).fadeOut();
});
$(".torznabtest").click(function () {
var torznab = this.attributes["name"].value.replace('torznab_test', '');
var imagechk = document.getElementById("tornabstatus"+torznab);
var name = document.getElementById("torznab_name"+torznab).value;
var host = document.getElementById("torznab_host"+torznab).value;
var apikey = document.getElementById("torznab_api"+torznab).value;
$.get("testtorznab",
{ name: name, host: host, ssl: ssl, apikey: apikey },
function(data){
if (data.error != undefined) {
alert(data.error);
return;
}
$('#ajaxMsg').html("<div class='msg'><span class='ui-icon ui-icon-check'></span>"+data+"</div>");
if ( data.indexOf("Successfully") > -1){
imagechk.src = "";
imagechk.src = "interfaces/default/images/success.png";
imagechk.style.visibility = "visible";
} else {
imagechk.src = "";
imagechk.src = "interfaces/default/images/fail.png";
imagechk.style.visibility = "visible";
}
});
$('#ajaxMsg').addClass('success').fadeIn().delay(3000).fadeOut();
});
$('#nma_test').click(function () {
var apikey = document.getElementById('nma_apikey').value;
var imagechk = document.getElementById("nma_statusicon");
var apikey = document.getElementById("nma_apikey").value;
$.get("testNMA",
{ apikey: apikey },
function(data){
@ -1997,21 +2177,50 @@
}
$('#nmastatus').val(data);
$('#ajaxMsg').html("<div class='msg'><span class='ui-icon ui-icon-check'></span>"+data+"</div>");
if ( data.indexOf("Successfully") > -1){
imagechk.src = "";
imagechk.src = "interfaces/default/images/success.png";
imagechk.style.visibility = "visible";
} else {
imagechk.src = "";
imagechk.src = "interfaces/default/images/fail.png";
imagechk.style.visibility = "visible";
}
});
$('#ajaxMsg').addClass('success').fadeIn().delay(3000).fadeOut();
});
$('#prowl_test').click(function () {
var imagechk = document.getElementById("prowl_statusicon");
var apikey = document.getElementById("prowl_keys");
$.get("testprowl",
function (data) { $('#ajaxMsg').html("<div class='msg'><span class='ui-icon ui-icon-check'></span>"+data+"</div>"); });
{ apikey: apikey },
function (data) {
if (data.error != undefined) {
alert(data.error);
return;
}
$('#ajaxMsg').html("<div class='msg'><span class='ui-icon ui-icon-check'></span>"+data+"</div>");
if ( data.indexOf("Successfully") > -1){
imagechk.src = "";
imagechk.src = "interfaces/default/images/success.png";
imagechk.style.visibility = "visible";
} else {
imagechk.src = "";
imagechk.src = "interfaces/default/images/fail.png";
imagechk.style.visibility = "visible";
}
});
$('#ajaxMsg').addClass('success').fadeIn().delay(3000).fadeOut();
});
$('#pushover_test').click(function () {
var apikey = document.getElementById('pushover_apikey').value;
var userkey = document.getElementById('pushover_userkey').value;
var imagechk = document.getElementById("pushover_statusicon");
var apikey = document.getElementById("pushover_apikey").value;
var userkey = document.getElementById("pushover_userkey").value;
var device = document.getElementById("pushover_device").value;
$.get("testpushover",
{ apikey: apikey, userkey: userkey },
{ apikey: apikey, userkey: userkey , device: device},
function(data){
if (data.error != undefined) {
alert(data.error);
@ -2019,18 +2228,47 @@
}
$('#pushoverstatus').val(data);
$('#ajaxMsg').html("<div class='msg'><span class='ui-icon ui-icon-check'></span>"+data+"</div>");
if ( data.indexOf("Successfully") > -1){
imagechk.src = "";
imagechk.src = "interfaces/default/images/success.png";
imagechk.style.visibility = "visible";
} else {
imagechk.src = "";
imagechk.src = "interfaces/default/images/fail.png";
imagechk.style.visibility = "visible";
}
});
$('#ajaxMsg').addClass('success').fadeIn().delay(3000).fadeOut();
});
$('#boxcar_test').click(function () {
var imagechk = document.getElementById("boxcar_statusicon");
var token = document.getElementById("boxcar_token");
$.get("testboxcar",
function (data) { $('#ajaxMsg').html("<div class='msg'><span class='ui-icon ui-icon-check'></span>"+data+"</div>"); });
{ token: token },
function (data) {
if (data.error != undefined) {
alert(data.error);
return;
}
$('#pushoverstatus').val(data);
$('#ajaxMsg').html("<div class='msg'><span class='ui-icon ui-icon-check'></span>"+data+"</div>");
if ( data.indexOf("Successfully") > -1){
imagechk.src = "";
imagechk.src = "interfaces/default/images/success.png";
imagechk.style.visibility = "visible";
} else {
imagechk.src = "";
imagechk.src = "interfaces/default/images/fail.png";
imagechk.style.visibility = "visible";
}
});
$('#ajaxMsg').addClass('success').fadeIn().delay(3000).fadeOut();
});
$('#pushbullet_test').click(function () {
var apikey = document.getElementById('pushbullet_apikey').value;
var imagechk = document.getElementById("pushbullet_statusicon");
var apikey = document.getElementById("pushbullet_apikey").value;
$.get("testpushbullet",
{ apikey: apikey },
function(data){
@ -2040,13 +2278,23 @@
}
$('#pbstatus').val(data);
$('#ajaxMsg').html("<div class='msg'><span class='ui-icon ui-icon-check'></span>"+data+"</div>");
if ( data.indexOf("Successfully") > -1){
imagechk.src = "";
imagechk.src = "interfaces/default/images/success.png";
imagechk.style.visibility = "visible";
} else {
imagechk.src = "";
imagechk.src = "interfaces/default/images/fail.png";
imagechk.style.visibility = "visible";
}
});
$('#ajaxMsg').addClass('success').fadeIn().delay(3000).fadeOut();
});
$('#telegram_test').click(function () {
var userid = document.getElementById('telegram_userid').value;
var token = document.getElementById('telegram_token').value;
var imagechk = document.getElementById("telegram_statusicon");
var userid = document.getElementById("telegram_userid").value;
var token = document.getElementById("telegram_token").value;
$.get("testtelegram",
{ userid: userid, token: token },
function(data){
@ -2056,12 +2304,22 @@
}
$('#telegramstatus').val(data);
$('#ajaxMsg').html("<div class='msg'><span class='ui-icon ui-icon-check'></span>"+data+"</div>");
if ( data.indexOf("Successfully") > -1){
imagechk.src = "";
imagechk.src = "interfaces/default/images/success.png";
imagechk.style.visibility = "visible";
} else {
imagechk.src = "";
imagechk.src = "interfaces/default/images/fail.png";
imagechk.style.visibility = "visible";
}
});
$('#ajaxMsg').addClass('success').fadeIn().delay(3000).fadeOut();
});
$('#slack_test').click(function () {
var webhook_url = document.getElementById('slack_webhook_url').value;
var imagechk = document.getElementById("slack_statusicon");
var webhook_url = document.getElementById("slack_webhook_url").value;
$.get("testslack",
{ webhook_url: webhook_url },
function(data){
@ -2071,7 +2329,16 @@
}
$('#slackstatus').val(data);
$('#ajaxMsg').html("<div class='msg'><span class='ui-icon ui-icon-check'></span>"+data+"</div>");
});
if ( data.indexOf("Successfully") > -1){
imagechk.src = "";
imagechk.src = "interfaces/default/images/success.png";
imagechk.style.visibility = "visible";
} else {
imagechk.src = "";
imagechk.src = "interfaces/default/images/fail.png";
imagechk.style.visibility = "visible";
}
});
$('#ajaxMsg').addClass('success').fadeIn().delay(3000).fadeOut();
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@ -65,7 +65,7 @@ class FailedProcessor(object):
if queue: self.queue = queue
self.valreturn = []
def _log(self, message, level=logger.message):
def _log(self, message, level=logger): #.message):
"""
A wrapper for the internal logger which also keeps track of messages and saves them to a string

View File

@ -62,8 +62,12 @@ class PostProcessor(object):
if queue:
self.queue = queue
if mylar.APILOCK is True:
return {'status': 'IN PROGRESS'}
if apicall is True:
self.apicall = True
mylar.APILOCK = True
else:
self.apicall = False
@ -86,7 +90,7 @@ class PostProcessor(object):
else:
self.comicid = None
def _log(self, message, level=logger.message): #level=logger.MESSAGE):
def _log(self, message, level=logger): #.message): #level=logger.MESSAGE):
"""
A wrapper for the internal logger which also keeps track of messages and saves them to a string for sabnzbd post-processing logging functions.
@ -641,8 +645,10 @@ class PostProcessor(object):
if datematch == 'True':
if watchmatch['sub']:
logger.fdebug('%s[SUB: %s][CLOCATION: %s]' % (module, watchmatch['sub'], watchmatch['comiclocation']))
clocation = os.path.join(watchmatch['comiclocation'], watchmatch['sub'], helpers.conversion(watchmatch['comicfilename']))
else:
logger.fdebug('%s[CLOCATION] %s' % (module, watchmatch['comiclocation']))
if self.issueid is not None and os.path.isfile(watchmatch['comiclocation']):
clocation = watchmatch['comiclocation']
else:
@ -1272,6 +1278,8 @@ class PostProcessor(object):
logger.info('%s post-processing of pack completed for %s issues [FAILED: %s]' % (module, i, self.failed_files))
else:
logger.info('%s Manual post-processing completed for %s issues [FAILED: %s]' % (module, i, self.failed_files))
if mylar.APILOCK is True:
mylar.APILOCK = False
return
else:
pass
@ -2283,7 +2291,8 @@ class PostProcessor(object):
"mode": 'stop',
"issueid": issueid,
"comicid": comicid})
if self.apicall is True:
self.sendnotify(series, issueyear, issuenumOG, annchk, module)
return self.queue.put(self.valreturn)
self.sendnotify(series, issueyear, issuenumOG, annchk, module)

View File

@ -51,6 +51,8 @@ FULL_PATH = None
MAINTENANCE = False
LOG_DIR = None
LOGTYPE = 'log'
LOG_LANG = 'en'
LOGLIST = []
ARGS = None
SIGNAL = None
SYS_ENCODING = None
@ -61,7 +63,6 @@ DAEMON = False
PIDFILE= None
CREATEPID = False
QUIET=False
LOG_LEVEL = 0
MAX_LOGSIZE = 5000000
SAFESTART = False
NOWEEKLY = False
@ -120,10 +121,10 @@ SNPOOL = None
NZBPOOL = None
SNATCHED_QUEUE = Queue.Queue()
NZB_QUEUE = Queue.Queue()
PP_QUEUE = Queue.Queue()
COMICSORT = None
PULLBYFILE = None
CFG = None
LOG_LIST = []
CURRENT_WEEKNUMBER = None
CURRENT_YEAR = None
INSTALL_TYPE = None
@ -133,6 +134,7 @@ LATEST_VERSION = None
COMMITS_BEHIND = None
LOCAL_IP = None
DOWNLOAD_APIKEY = None
APILOCK = False
CMTAGGER_PATH = None
STATIC_COMICRN_VERSION = "1.01"
STATIC_APC_VERSION = "2.01"
@ -153,11 +155,11 @@ def initialize(config_file):
with INIT_LOCK:
global CONFIG, _INITIALIZED, QUIET, CONFIG_FILE, OS_DETECT, MAINTENANCE, CURRENT_VERSION, LATEST_VERSION, COMMITS_BEHIND, INSTALL_TYPE, IMPORTLOCK, PULLBYFILE, INKDROPS_32P, \
DONATEBUTTON, CURRENT_WEEKNUMBER, CURRENT_YEAR, UMASK, USER_AGENT, SNATCHED_QUEUE, NZB_QUEUE, PULLNEW, COMICSORT, WANTED_TAB_OFF, CV_HEADERS, \
DONATEBUTTON, CURRENT_WEEKNUMBER, CURRENT_YEAR, UMASK, USER_AGENT, SNATCHED_QUEUE, NZB_QUEUE, PP_QUEUE, PULLNEW, COMICSORT, WANTED_TAB_OFF, CV_HEADERS, \
IMPORTBUTTON, IMPORT_FILES, IMPORT_TOTALFILES, IMPORT_CID_COUNT, IMPORT_PARSED_COUNT, IMPORT_FAILURE_COUNT, CHECKENABLED, CVURL, DEMURL, WWTURL, \
USE_SABNZBD, USE_NZBGET, USE_BLACKHOLE, USE_RTORRENT, USE_UTORRENT, USE_QBITTORRENT, USE_DELUGE, USE_TRANSMISSION, USE_WATCHDIR, SAB_PARAMS, \
PROG_DIR, DATA_DIR, CMTAGGER_PATH, DOWNLOAD_APIKEY, LOCAL_IP, STATIC_COMICRN_VERSION, STATIC_APC_VERSION, KEYS_32P, AUTHKEY_32P, FEED_32P, FEEDINFO_32P, \
MONITOR_STATUS, SEARCH_STATUS, RSS_STATUS, WEEKLY_STATUS, VERSION_STATUS, UPDATER_STATUS, DBUPDATE_INTERVAL, \
MONITOR_STATUS, SEARCH_STATUS, RSS_STATUS, WEEKLY_STATUS, VERSION_STATUS, UPDATER_STATUS, DBUPDATE_INTERVAL, LOG_LEVEL, LOG_LANG, APILOCK, \
SCHED_RSS_LAST, SCHED_WEEKLY_LAST, SCHED_MONITOR_LAST, SCHED_SEARCH_LAST, SCHED_VERSION_LAST, SCHED_DBUPDATE_LAST, COMICINFO
cc = mylar.config.Config(config_file)
@ -168,11 +170,11 @@ def initialize(config_file):
if _INITIALIZED:
return False
#set up the default values here if they're wrong.
#cc.configure()
# Start the logger, silence console logging if we need to
logger.initLogger(console=not QUIET, log_dir=CONFIG.LOG_DIR, verbose=VERBOSE) #logger.mylar_log.initLogger(verbose=VERBOSE)
if mylar.LOG_LANG == 'en':
logger.initLogger(console=not QUIET, log_dir=CONFIG.LOG_DIR, verbose=VERBOSE)
else:
logger.mylar_log.initLogger(loglevel=mylar.LOG_LEVEL)
# Also sets INSTALL_TYPE variable to 'win', 'git' or 'source'
CURRENT_VERSION, CONFIG.GIT_BRANCH = versioncheck.getVersion()
@ -407,6 +409,11 @@ def start():
elif CONFIG.NZB_DOWNLOADER == 1:
logger.info('[AUTO-COMPLETE-NZB] Succesfully started Completed post-processing handling for NZBGet - will now monitor for completed nzbs within nzbget and post-process automatically....')
if all([CONFIG.POST_PROCESSING is True, CONFIG.API_ENABLED is True]):
logger.info('[POST-PROCESS-QUEUE] Post Process queue enabled & monitoring for api requests....')
PPPOOL = threading.Thread(target=helpers.postprocess_main, args=(PP_QUEUE,), name="POST-PROCESS-QUEUE")
PPPOOL.start()
logger.info('[POST-PROCESS-QUEUE] Succesfully started Post-Processing Queuer....')
helpers.latestdate_fix()

View File

@ -330,6 +330,7 @@ class Api(object):
return
def _forceProcess(self, **kwargs):
if 'nzb_name' not in kwargs:
self.data = self._error_with_message('Missing parameter: nzb_name')
return
@ -358,8 +359,16 @@ class Api(object):
comicid = kwargs['comicid']
if 'apc_version' not in kwargs:
fp = process.Process(self.nzb_name, self.nzb_folder, issueid=issueid, failed=failed, comicid=comicid, apicall=True)
self.data = fp.post_process()
logger.info('Received API Request for PostProcessing %s [%s]. Queueing...' % (self.nzb_name, self.nzb_folder))
mylar.PP_QUEUE.put({'nzb_name': self.nzb_name,
'nzb_folder': self.nzb_folder,
'issueid': issueid,
'failed': failed,
'comicid': comicid,
'apicall': True})
self.data = 'Successfully submitted request for post-processing for %s' % self.nzb_name
#fp = process.Process(self.nzb_name, self.nzb_folder, issueid=issueid, failed=failed, comicid=comicid, apicall=True)
#self.data = fp.post_process()
else:
logger.info('[API] Api Call from ComicRN detected - initiating script post-processing.')
fp = webserve.WebInterface()

View File

@ -114,6 +114,7 @@ _CONFIG_DEFINITIONS = OrderedDict({
'LOG_DIR' : (str, 'Logs', None),
'MAX_LOGSIZE' : (int, 'Logs', 10000000),
'MAX_LOGFILES': (int, 'Logs', 5),
'LOG_LEVEL': (int, 'Logs', 0),
'GIT_PATH' : (str, 'Git', None),
@ -151,6 +152,7 @@ _CONFIG_DEFINITIONS = OrderedDict({
'PUSHOVER_ENABLED': (bool, 'PUSHOVER', False),
'PUSHOVER_PRIORITY': (int, 'PUSHOVER', 0),
'PUSHOVER_APIKEY': (str, 'PUSHOVER', None),
'PUSHOVER_DEVICE': (str, 'PUSHOVER', None),
'PUSHOVER_USERKEY': (str, 'PUSHOVER', None),
'PUSHOVER_ONSNATCH': (bool, 'PUSHOVER', False),
@ -227,6 +229,7 @@ _CONFIG_DEFINITIONS = OrderedDict({
'EXTRA_NEWZNABS': (str, 'Newznab', ""),
'ENABLE_TORZNAB': (bool, 'Torznab', False),
'EXTRA_TORZNABS': (str, 'Torznab', ""),
'TORZNAB_NAME': (str, 'Torznab', None),
'TORZNAB_HOST': (str, 'Torznab', None),
'TORZNAB_APIKEY': (str, 'Torznab', None),
@ -365,7 +368,7 @@ class Config(object):
count = sum(1 for line in open(self._config_file))
else:
count = 0
self.newconfig = 7
self.newconfig = 8
if count == 0:
CONFIG_VERSION = 0
MINIMALINI = False
@ -479,11 +482,16 @@ class Config(object):
def read(self):
self.config_vals()
setattr(self, 'EXTRA_NEWZNABS', self.get_extra_newznabs())
setattr(self, 'EXTRA_TORZNABS', self.get_extra_torznabs())
if any([self.CONFIG_VERSION == 0, self.CONFIG_VERSION < self.newconfig]):
try:
shutil.move(self._config_file, os.path.join(mylar.DATA_DIR, 'config.ini.backup'))
except:
logger.warn('Unable to make proper backup of config file in %s' % os.path.join(mylar.DATA_DIR, 'config.ini.backup'))
print('Unable to make proper backup of config file in %s' % os.path.join(mylar.DATA_DIR, 'config.ini.backup'))
if self.newconfig == 8:
print('Attempting to update configuration..')
#torznab multiple entries merged into extra_torznabs value
self.config_update()
setattr(self, 'CONFIG_VERSION', str(self.newconfig))
config.set('General', 'CONFIG_VERSION', str(self.newconfig))
print('Updating config to newest version : %s' % self.newconfig)
@ -493,6 +501,25 @@ class Config(object):
self.configure()
return self
def config_update(self):
if self.newconfig == 8:
print('Updating Configuration from %s to %s' % (self.CONFIG_VERSION, self.newconfig))
print('Checking for existing torznab configuration...')
if not any([self.TORZNAB_NAME is None, self.TORZNAB_HOST is None, self.TORZNAB_APIKEY is None, self.TORZNAB_CATEGORY is None]):
torznabs =[(self.TORZNAB_NAME, self.TORZNAB_HOST, self.TORZNAB_APIKEY, self.TORZNAB_CATEGORY, str(int(self.ENABLE_TORZNAB)))]
setattr(self, 'EXTRA_TORZNABS', torznabs)
config.set('Torznab', 'EXTRA_TORZNABS', str(torznabs))
print('Successfully converted existing torznab for multiple configuration allowance. Removing old references.')
else:
print('No existing torznab configuration found. Just removing config references at this point..')
config.remove_option('Torznab', 'torznab_name')
config.remove_option('Torznab', 'torznab_host')
config.remove_option('Torznab', 'torznab_apikey')
config.remove_option('Torznab', 'torznab_category')
config.remove_option('Torznab', 'torznab_verify')
print('Successfully removed old entries.')
print('Configuration upgraded to version %s' % self.newconfig)
def check_section(self, section, key):
""" Check if INI section exists, if not create it """
if config.has_section(section):
@ -579,7 +606,7 @@ class Config(object):
Given a big bunch of key value pairs, apply them to the ini.
"""
for name, value in kwargs.items():
if not any([(name.startswith('newznab') and name[-1].isdigit()), name.startswith('Torznab')]):
if not any([(name.startswith('newznab') and name[-1].isdigit()), name.startswith('torznab') and name[-1].isdigit()]):
key, definition_type, section, ini_key, default = self._define(name)
if definition_type == str:
try:
@ -643,6 +670,8 @@ class Config(object):
logger.fdebug("Writing configuration to file")
self.provider_sequence()
config.set('Newznab', 'extra_newznabs', ', '.join(self.write_extras(self.EXTRA_NEWZNABS)))
config.set('Torznab', 'extra_torznabs', ', '.join(self.write_extras(self.EXTRA_TORZNABS)))
###this should be moved elsewhere...
if type(self.BLACKLISTED_PUBLISHERS) != list:
if self.BLACKLISTED_PUBLISHERS is None:
@ -853,6 +882,10 @@ class Config(object):
extra_newznabs = zip(*[iter(self.EXTRA_NEWZNABS.split(', '))]*6)
return extra_newznabs
def get_extra_torznabs(self):
extra_torznabs = zip(*[iter(self.EXTRA_TORZNABS.split(', '))]*5)
return extra_torznabs
def provider_sequence(self):
PR = []
PR_NUM = 0
@ -872,11 +905,8 @@ class Config(object):
if self.EXPERIMENTAL:
PR.append('Experimental')
PR_NUM +=1
if self.ENABLE_TORZNAB:
PR.append('Torznab')
PR_NUM +=1
PPR = ['32p', 'public torrents', 'nzb.su', 'dognzb', 'Experimental', 'Torznab']
PPR = ['32p', 'public torrents', 'nzb.su', 'dognzb', 'Experimental']
if self.NEWZNAB:
for ens in self.EXTRA_NEWZNABS:
if str(ens[5]) == '1': # if newznabs are enabled
@ -890,6 +920,19 @@ class Config(object):
PPR.append(en_name)
PR_NUM +=1
if self.ENABLE_TORZNAB:
for ets in self.EXTRA_TORZNABS:
if str(ets[4]) == '1': # if torznabs are enabled
if ets[0] == "":
et_name = ets[1]
else:
et_name = ets[0]
if et_name.endswith("\""):
et_name = re.sub("\"", "", str(et_name)).strip()
PR.append(et_name)
PPR.append(et_name)
PR_NUM +=1
if self.PROVIDER_ORDER is not None:
try:
PRO_ORDER = zip(*[iter(self.PROVIDER_ORDER.split(', '))]*2)
@ -901,7 +944,7 @@ class Config(object):
POR = ', '.join(PO)
PRO_ORDER = zip(*[iter(POR.split(', '))]*2)
logger.fdebug('Original provider_order sequence: %s' % self.PROVIDER_ORDER)
logger.fdebug(u"Original provider_order sequence: %s" % self.PROVIDER_ORDER)
#if provider order exists already, load it and then append to end any NEW entries.
logger.fdebug('Provider sequence already pre-exists. Re-loading and adding/remove any new entries')
@ -990,7 +1033,7 @@ class Config(object):
def write_extras(self, value):
flattened = []
for item in value: #self.EXTRA_NEWZNABS:
for item in value:
for i in item:
try:
if "\"" in i and " \"" in i:

View File

@ -2959,6 +2959,31 @@ def latestdate_update():
logger.info('updating latest date for : ' + a['ComicID'] + ' to ' + a['LatestDate'] + ' #' + a['LatestIssue'])
myDB.upsert("comics", newVal, ctrlVal)
def postprocess_main(queue):
while True:
if mylar.APILOCK is True:
time.sleep(5)
elif mylar.APILOCK is False and queue.qsize() >= 1: #len(queue) > 1:
item = queue.get(True)
logger.info('Now loading from post-processing queue: %s' % item)
if item == 'exit':
logger.info('Cleaning up workers for shutdown')
break
if mylar.APILOCK is False:
pprocess = process.Process(item['nzb_name'], item['nzb_folder'], item['failed'], item['issueid'], item['comicid'], item['apicall'])
pp = pprocess.post_process()
time.sleep(5) #arbitrary sleep to let the process attempt to finish pp'ing
if mylar.APILOCK is True:
logger.info('Another item is post-processing still...')
time.sleep(15)
#mylar.PP_QUEUE.put(item)
else:
time.sleep(5)
def worker_main(queue):
while True:
item = queue.get(True)

411
mylar/logger.py Executable file → Normal file
View File

@ -25,171 +25,318 @@ from logging import getLogger, WARN, ERROR, INFO, DEBUG, StreamHandler, Formatte
from mylar import helpers
# These settings are for file logging only
FILENAME = 'mylar.log'
MAX_LOGSIZE = 1000000
MAX_FILES = 5
try:
if mylar.LOG_LANG == 'en':
pass
except:
mylar.LOG_LANG = 'en'
# Mylar logger
logger = logging.getLogger('mylar')
class LogListHandler(logging.Handler):
"""
Log handler for Web UI.
"""
if mylar.LOG_LANG != 'en':
# Simple rotating log handler that uses RotatingFileHandler
class RotatingLogger(object):
def emit(self, record):
message = self.format(record)
message = message.replace("\n", "<br />")
mylar.LOG_LIST.insert(0, (helpers.now(), message, record.levelname, record.threadName))
def __init__(self, filename):
def initLogger(console=False, log_dir=False, init=False, verbose=False):
#concurrentLogHandler/0.8.7 (to deal with windows locks)
#since this only happens on windows boxes, if it's nix/mac use the default logger.
if platform.system() == 'Windows':
#set the path to the lib here - just to make sure it can detect cloghandler & portalocker.
import sys
sys.path.append(os.path.join(mylar.PROG_DIR, 'lib'))
self.filename = filename
self.filehandler = None
self.consolehandler = None
def stopLogger(self):
lg = logging.getLogger('mylar')
lg.removeHandler(self.filehandler)
lg.removeHandler(self.consolehandler)
def handle_exception(self, exc_type, exc_value, exc_traceback):
if issubclass(exc_type, KeyboardInterrupt):
sys.__excepthook__(exc_type, exc_value, exc_traceback)
return
logger.exception('Uncaught Exception', excinfo=(exc_type, exc_value, exc_traceback))
sys.__excepthook__(exc_type, exc_value, None)
return
def initLogger(self, loglevel=1):
import sys
sys.excepthook = RotatingLogger.handle_exception
logging.getLogger('apscheduler.scheduler').setLevel(logging.WARN)
logging.getLogger('apscheduler.threadpool').setLevel(logging.WARN)
logging.getLogger('apscheduler.scheduler').propagate = False
logging.getLogger('apscheduler.threadpool').propagate = False
lg = logging.getLogger('mylar')
lg.setLevel(logging.DEBUG)
self.filename = os.path.join(mylar.CONFIG.LOG_DIR, self.filename)
#concurrentLogHandler/0.8.7 (to deal with windows locks)
#since this only happens on windows boxes, if it's nix/mac use the default logger.
if mylar.OS_DETECT == 'Windows':
#set the path to the lib here - just to make sure it can detect cloghandler & portalocker.
import sys
sys.path.append(os.path.join(mylar.PROG_DIR, 'lib'))
try:
from ConcurrentLogHandler.cloghandler import ConcurrentRotatingFileHandler as RFHandler
mylar.LOGTYPE = 'clog'
except ImportError:
mylar.LOGTYPE = 'log'
from logging.handlers import RotatingFileHandler as RFHandler
else:
mylar.LOGTYPE = 'log'
from logging.handlers import RotatingFileHandler as RFHandler
filehandler = RFHandler(
self.filename,
maxBytes=mylar.CONFIG.MAX_LOGSIZE,
backupCount=mylar.CONFIG.MAX_LOGFILES)
filehandler.setLevel(logging.DEBUG)
fileformatter = logging.Formatter('%(asctime)s - %(levelname)-7s :: %(message)s', '%d-%b-%Y %H:%M:%S')
filehandler.setFormatter(fileformatter)
lg.addHandler(filehandler)
self.filehandler = filehandler
if loglevel:
consolehandler = logging.StreamHandler()
if loglevel == 1:
consolehandler.setLevel(logging.INFO)
if loglevel >= 2:
consolehandler.setLevel(logging.DEBUG)
consoleformatter = logging.Formatter('%(asctime)s - %(levelname)s :: %(message)s', '%d-%b-%Y %H:%M:%S')
consolehandler.setFormatter(consoleformatter)
lg.addHandler(consolehandler)
self.consolehandler = consolehandler
@staticmethod
def log(message, level):
logger = logging.getLogger('mylar')
threadname = threading.currentThread().getName()
# Get the frame data of the method that made the original logger call
if len(inspect.stack()) > 2:
frame = inspect.getframeinfo(inspect.stack()[2][0])
program = os.path.basename(frame.filename)
method = frame.function
lineno = frame.lineno
else:
program = ""
method = ""
lineno = ""
if PY2:
message = safe_unicode(message)
message = message.encode(mylar.SYS_ENCODING)
if level != 'DEBUG' or mylar.LOG_LEVEL >= 2:
mylar.LOGLIST.insert(0, (helpers.now(), message, threadname))
if len(mylar.LOGLIST) > 2500:
del mylar.LOGLIST[-1]
message = "%s : %s:%s:%s : %s" % (threadname, program, method, lineno, message)
if level == 'DEBUG':
logger.debug(message)
elif level == 'INFO':
logger.info(message)
elif level == 'WARNING':
logger.warning(message)
else:
logger.error(message)
mylar_log = RotatingLogger('mylar.log')
filename = 'mylar.log'
def debug(message):
if mylar.LOG_LEVEL > 1:
mylar_log.log(message, level='DEBUG')
def fdebug(message):
if mylar.LOG_LEVEL > 1:
mylar_log.log(message, level='DEBUG')
def info(message):
if mylar.LOG_LEVEL > 0:
mylar_log.log(message, level='INFO')
def warn(message):
mylar_log.log(message, level='WARNING')
def error(message):
mylar_log.log(message, level='ERROR')
def safe_unicode(obj, *args):
""" return the unicode representation of obj """
if not PY2:
return str(obj, *args)
try:
from ConcurrentLogHandler.cloghandler import ConcurrentRotatingFileHandler as RFHandler
mylar.LOGTYPE = 'clog'
except ImportError:
return unicode(obj, *args)
except UnicodeDecodeError:
ascii_text = str(obj).encode('string_escape')
return unicode(ascii_text)
else:
# Mylar logger
logger = logging.getLogger('mylar')
class LogListHandler(logging.Handler):
"""
Log handler for Web UI.
"""
def emit(self, record):
message = self.format(record)
message = message.replace("\n", "<br />")
mylar.LOGLIST.insert(0, (helpers.now(), message, record.levelname, record.threadName))
def initLogger(console=False, log_dir=False, init=False, verbose=False):
#concurrentLogHandler/0.8.7 (to deal with windows locks)
#since this only happens on windows boxes, if it's nix/mac use the default logger.
if platform.system() == 'Windows':
#set the path to the lib here - just to make sure it can detect cloghandler & portalocker.
import sys
sys.path.append(os.path.join(mylar.PROG_DIR, 'lib'))
try:
from ConcurrentLogHandler.cloghandler import ConcurrentRotatingFileHandler as RFHandler
mylar.LOGTYPE = 'clog'
except ImportError:
mylar.LOGTYPE = 'log'
from logging.handlers import RotatingFileHandler as RFHandler
else:
mylar.LOGTYPE = 'log'
from logging.handlers import RotatingFileHandler as RFHandler
else:
mylar.LOGTYPE = 'log'
from logging.handlers import RotatingFileHandler as RFHandler
if init is True:
max_size = 1000000 #1 MB
else:
if mylar.CONFIG.MAX_LOGSIZE:
max_size = mylar.CONFIG.MAX_LOGSIZE
if init is True:
max_size = 1000000 #1 MB
else:
max_size = 1000000 # 1 MB
if mylar.CONFIG.MAX_LOGSIZE:
max_size = mylar.CONFIG.MAX_LOGSIZE
else:
max_size = 1000000 # 1 MB
"""
Setup logging for Mylar. It uses the logger instance with the name
'mylar'. Three log handlers are added:
"""
Setup logging for Mylar. It uses the logger instance with the name
'mylar'. Three log handlers are added:
* RotatingFileHandler: for the file Mylar.log
* LogListHandler: for Web UI
* StreamHandler: for console
"""
* RotatingFileHandler: for the file Mylar.log
* LogListHandler: for Web UI
* StreamHandler: for console
"""
logging.getLogger('apscheduler.scheduler').setLevel(logging.WARN)
logging.getLogger('apscheduler.threadpool').setLevel(logging.WARN)
logging.getLogger('apscheduler.scheduler').propagate = False
logging.getLogger('apscheduler.threadpool').propagate = False
logging.getLogger('apscheduler.scheduler').setLevel(logging.WARN)
logging.getLogger('apscheduler.threadpool').setLevel(logging.WARN)
logging.getLogger('apscheduler.scheduler').propagate = False
logging.getLogger('apscheduler.threadpool').propagate = False
# Close and remove old handlers. This is required to reinit the loggers
# at runtime
for handler in logger.handlers[:]:
# Just make sure it is cleaned up.
if isinstance(handler, RFHandler):
handler.close()
elif isinstance(handler, logging.StreamHandler):
handler.flush()
# Close and remove old handlers. This is required to reinit the loggers
# at runtime
for handler in logger.handlers[:]:
# Just make sure it is cleaned up.
if isinstance(handler, RFHandler):
handler.close()
elif isinstance(handler, logging.StreamHandler):
handler.flush()
logger.removeHandler(handler)
logger.removeHandler(handler)
# Configure the logger to accept all messages
logger.propagate = False
# Configure the logger to accept all messages
logger.propagate = False
#1 is WARN level, 2 is ERROR
if init is True:
logger.setLevel(logging.DEBUG if verbose else logging.INFO)
else:
if mylar.CONFIG.LOG_LEVEL == 1:
logger.setLevel(logging.DEBUG if verbose else logging.WARN)
elif mylar.CONFIG.LOG_LEVEL == 2:
logger.setLevel(logging.DEBUG if verbose else logging.ERROR)
else:
#1 is WARN level, 2 is ERROR
if init is True:
logger.setLevel(logging.DEBUG if verbose else logging.INFO)
else:
if mylar.CONFIG.LOG_LEVEL == 1:
logger.setLevel(logging.DEBUG if verbose else logging.WARN)
elif mylar.CONFIG.LOG_LEVEL == 2:
logger.setLevel(logging.DEBUG if verbose else logging.ERROR)
else:
logger.setLevel(logging.DEBUG if verbose else logging.INFO)
# Add list logger
loglist_handler = LogListHandler()
loglist_handler.setLevel(logging.DEBUG)
logger.addHandler(loglist_handler)
# Add list logger
loglist_handler = LogListHandler()
loglist_handler.setLevel(logging.DEBUG)
logger.addHandler(loglist_handler)
# Setup file logger
if log_dir:
filename = os.path.join(log_dir, FILENAME)
file_formatter = Formatter('%(asctime)s - %(levelname)-7s :: %(name)s.%(funcName)s.%(lineno)s : %(threadName)s : %(message)s', '%d-%b-%Y %H:%M:%S')
file_handler = RFHandler(filename, "a", maxBytes=max_size, backupCount=MAX_FILES)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(file_formatter)
# Setup file logger
if log_dir:
filename = os.path.join(log_dir, 'mylar.log')
file_formatter = Formatter('%(asctime)s - %(levelname)-7s :: %(name)s.%(funcName)s.%(lineno)s : %(threadName)s : %(message)s', '%d-%b-%Y %H:%M:%S')
file_handler = RFHandler(filename, "a", maxBytes=max_size, backupCount=mylar.CONFIG.MAX_LOGFILES)
file_handler.setLevel(logging.DEBUG)
file_handler.setFormatter(file_formatter)
logger.addHandler(file_handler)
logger.addHandler(file_handler)
# Setup console logger
if console:
console_formatter = logging.Formatter('%(asctime)s - %(levelname)s :: %(name)s.%(funcName)s.%(lineno)s : %(threadName)s : %(message)s', '%d-%b-%Y %H:%M:%S')
console_handler = logging.StreamHandler()
console_handler.setFormatter(console_formatter)
console_handler.setLevel(logging.DEBUG)
# Setup console logger
if console:
console_formatter = logging.Formatter('%(asctime)s - %(levelname)s :: %(name)s.%(funcName)s.%(lineno)s : %(threadName)s : %(message)s', '%d-%b-%Y %H:%M:%S')
console_handler = logging.StreamHandler()
console_handler.setFormatter(console_formatter)
console_handler.setLevel(logging.DEBUG)
logger.addHandler(console_handler)
logger.addHandler(console_handler)
# Install exception hooks
initHooks()
# Install exception hooks
initHooks()
def initHooks(global_exceptions=True, thread_exceptions=True, pass_original=True):
"""
This method installs exception catching mechanisms. Any exception caught
will pass through the exception hook, and will be logged to the logger as
an error. Additionally, a traceback is provided.
def initHooks(global_exceptions=True, thread_exceptions=True, pass_original=True):
"""
This method installs exception catching mechanisms. Any exception caught
will pass through the exception hook, and will be logged to the logger as
an error. Additionally, a traceback is provided.
This is very useful for crashing threads and any other bugs, that may not
be exposed when running as daemon.
This is very useful for crashing threads and any other bugs, that may not
be exposed when running as daemon.
The default exception hook is still considered, if pass_original is True.
"""
The default exception hook is still considered, if pass_original is True.
"""
def excepthook(*exception_info):
# We should always catch this to prevent loops!
try:
message = "".join(traceback.format_exception(*exception_info))
logger.error("Uncaught exception: %s", message)
except:
pass
def excepthook(*exception_info):
# We should always catch this to prevent loops!
try:
message = "".join(traceback.format_exception(*exception_info))
logger.error("Uncaught exception: %s", message)
except:
pass
# Original excepthook
if pass_original:
sys.__excepthook__(*exception_info)
# Original excepthook
if pass_original:
sys.__excepthook__(*exception_info)
# Global exception hook
if global_exceptions:
sys.excepthook = excepthook
# Global exception hook
if global_exceptions:
sys.excepthook = excepthook
# Thread exception hook
if thread_exceptions:
old_init = threading.Thread.__init__
# Thread exception hook
if thread_exceptions:
old_init = threading.Thread.__init__
def new_init(self, *args, **kwargs):
old_init(self, *args, **kwargs)
old_run = self.run
def new_init(self, *args, **kwargs):
old_init(self, *args, **kwargs)
old_run = self.run
def new_run(*args, **kwargs):
try:
old_run(*args, **kwargs)
except (KeyboardInterrupt, SystemExit):
raise
except:
excepthook(*sys.exc_info())
self.run = new_run
def new_run(*args, **kwargs):
try:
old_run(*args, **kwargs)
except (KeyboardInterrupt, SystemExit):
raise
except:
excepthook(*sys.exc_info())
self.run = new_run
# Monkey patch the run() by monkey patching the __init__ method
threading.Thread.__init__ = new_init
# Monkey patch the run() by monkey patching the __init__ method
threading.Thread.__init__ = new_init
# Expose logger methods
info = logger.info
warn = logger.warn
error = logger.error
debug = logger.debug
warning = logger.warning
message = logger.info
exception = logger.exception
fdebug = logger.debug
# Expose logger methods
info = logger.info
warn = logger.warn
error = logger.error
debug = logger.debug
warning = logger.warning
message = logger.info
exception = logger.exception
fdebug = logger.debug

View File

@ -205,17 +205,26 @@ class NMA:
# No extra care has been put into API friendliness at the moment (read: https://pushover.net/api#friendly)
class PUSHOVER:
def __init__(self, test_apikey=None, test_userkey=None):
self.PUSHOVER_URL = 'https://api.pushover.net/1/messages.json'
def __init__(self, test_apikey=None, test_userkey=None, test_device=None):
if all([test_apikey is None, test_userkey is None, test_device is None]):
self.PUSHOVER_URL = 'https://api.pushover.net/1/messages.json'
else:
self.PUSHOVER_URL = 'https://api.pushover.net/1/users/validate.json'
self.enabled = mylar.CONFIG.PUSHOVER_ENABLED
if test_apikey is None:
if mylar.CONFIG.PUSHOVER_APIKEY is None or mylar.CONFIG.PUSHOVER_APIKEY == 'None':
self.apikey = 'a1KZ1L7d8JKdrtHcUR6eFoW2XGBmwG'
logger.warn('No Pushover Apikey is present. Fix it')
return False
else:
self.apikey = mylar.CONFIG.PUSHOVER_APIKEY
else:
self.apikey = test_apikey
if test_device is None:
self.device = mylar.CONFIG.PUSHOVER_DEVICE
else:
self.device = test_device
if test_userkey is None:
self.userkey = mylar.CONFIG.PUSHOVER_USERKEY
else:
@ -244,10 +253,21 @@ class PUSHOVER:
'title': event,
'priority': mylar.CONFIG.PUSHOVER_PRIORITY}
if all([self.device is not None, self.device != 'None']):
data.update({'device': self.device})
r = self._session.post(self.PUSHOVER_URL, data=data, verify=True)
if r.status_code == 200:
logger.info(module + ' PushOver notifications sent.')
try:
response = r.json()
if 'devices' in response:
logger.info('%s PushOver notifications sent. Available devices: %s' % (module, response))
else:
logger.info('%s PushOver notifications sent.' % module)
except Exception as e:
logger.warn('%s[ERROR] - %s' % (module, e))
return True
elif r.status_code >= 400 and r.status_code < 500:
logger.error(module + ' PushOver request failed: %s' % r.content)

View File

@ -37,7 +37,7 @@ class NZBGet(object):
self.nzb_url = '%s://%s:%s@%s:%s/xmlrpc' % (protocol, mylar.CONFIG.NZBGET_USERNAME, mylar.CONFIG.NZBGET_PASSWORD, nzbget_host, mylar.CONFIG.NZBGET_PORT)
self.server = xmlrpclib.ServerProxy(self.nzb_url)
def sender(self, filename):
def sender(self, filename, test=False):
if mylar.CONFIG.NZBGET_PRIORITY:
if any([mylar.CONFIG.NZBGET_PRIORITY == 'Default', mylar.CONFIG.NZBGET_PRIORITY == 'Normal']):
nzbgetpriority = 0

View File

@ -546,7 +546,7 @@ def torrentdbsearch(seriesname, issue, comicid=None, nzbprov=None, oneoff=False)
if any([comicid is None, comicid == 'None', oneoff is True]):
pass
else:
logger.fdebug('ComicID: ' + str(comicid))
#logger.fdebug('ComicID: ' + str(comicid))
snm = myDB.selectone("SELECT * FROM comics WHERE comicid=?", [comicid]).fetchone()
if snm is None:
logger.fdebug('Invalid ComicID of ' + str(comicid) + '. Aborting search.')
@ -575,7 +575,7 @@ def torrentdbsearch(seriesname, issue, comicid=None, nzbprov=None, oneoff=False)
tsearch += '%'
tsearch += '#%s' % issue[8:10]
tsearch += '%'
logger.fdebug('tsearch : ' + tsearch)
#logger.fdebug('tsearch : ' + tsearch)
AS_Alt = []
tresults = []
tsearch = '%' + tsearch
@ -585,7 +585,7 @@ def torrentdbsearch(seriesname, issue, comicid=None, nzbprov=None, oneoff=False)
if mylar.CONFIG.ENABLE_PUBLIC and nzbprov == 'Public Torrents':
tresults += myDB.select("SELECT * FROM rssdb WHERE Title like ? AND (Site='DEM' OR Site='WWT')", [tsearch])
logger.fdebug('seriesname_alt:' + str(seriesname_alt))
#logger.fdebug('seriesname_alt:' + str(seriesname_alt))
if seriesname_alt is None or seriesname_alt == 'None':
if not tresults:
logger.fdebug('no Alternate name given. Aborting search.')
@ -639,43 +639,22 @@ def torrentdbsearch(seriesname, issue, comicid=None, nzbprov=None, oneoff=False)
#torsplit = torTITLE.split(' ')
if mylar.CONFIG.PREFERRED_QUALITY == 1:
if 'cbr' in torTITLE:
logger.fdebug('Quality restriction enforced [ cbr only ]. Accepting result.')
else:
logger.fdebug('Quality restriction enforced [ cbr only ]. Rejecting result.')
if 'cbr' not in torTITLE:
#logger.fdebug('Quality restriction enforced [ cbr only ]. Rejecting result.')
continue
elif mylar.CONFIG.PREFERRED_QUALITY == 2:
if 'cbz' in torTITLE:
logger.fdebug('Quality restriction enforced [ cbz only ]. Accepting result.')
else:
logger.fdebug('Quality restriction enforced [ cbz only ]. Rejecting result.')
if 'cbz' not in torTITLE:
#logger.fdebug('Quality restriction enforced [ cbz only ]. Rejecting result.')
continue
logger.fdebug('tor-Title: ' + torTITLE)
#logger.fdebug('tor-Title: ' + torTITLE)
#logger.fdebug('there are ' + str(len(torsplit)) + ' sections in this title')
i=0
if nzbprov is not None:
if nzbprov != tor['Site'] and not any([mylar.CONFIG.ENABLE_PUBLIC, tor['Site'] != 'WWT', tor['Site'] != 'DEM']):
logger.fdebug('this is a result from ' + str(tor['Site']) + ', not the site I am looking for of ' + str(nzbprov))
#logger.fdebug('this is a result from ' + str(tor['Site']) + ', not the site I am looking for of ' + str(nzbprov))
continue
#0 holds the title/issue and format-type.
#--- this was for old cbt feeds, no longer used for 32p
# while (i < len(torsplit)):
# #we'll rebuild the string here so that it's formatted accordingly to be passed back to the parser.
# logger.fdebug('section(' + str(i) + '): ' + torsplit[i])
# #remove extensions
# titletemp = torsplit[i]
# titletemp = re.sub('cbr', '', titletemp)
# titletemp = re.sub('cbz', '', titletemp)
# titletemp = re.sub('none', '', titletemp)
# if i == 0:
# rebuiltline = titletemp
# else:
# rebuiltline = rebuiltline + ' (' + titletemp + ')'
# i+=1
# logger.fdebug('rebuiltline is :' + rebuiltline)
#----
seriesname_mod = seriesname
foundname_mod = torTITLE #torsplit[0]
seriesname_mod = re.sub("\\band\\b", " ", seriesname_mod.lower())
@ -696,40 +675,23 @@ def torrentdbsearch(seriesname, issue, comicid=None, nzbprov=None, oneoff=False)
formatrem_torsplit = re.sub('[\-]', ' ', formatrem_torsplit) #we replace the - with space so we'll get hits if differnces
formatrem_torsplit = re.sub('[\/]', ' ', formatrem_torsplit) #not necessary since if has a /, should be removed in above line
formatrem_torsplit = re.sub('\s+', ' ', formatrem_torsplit)
logger.fdebug(str(len(formatrem_torsplit)) + ' - formatrem_torsplit : ' + formatrem_torsplit.lower())
logger.fdebug(str(len(formatrem_seriesname)) + ' - formatrem_seriesname :' + formatrem_seriesname.lower())
#logger.fdebug(str(len(formatrem_torsplit)) + ' - formatrem_torsplit : ' + formatrem_torsplit.lower())
#logger.fdebug(str(len(formatrem_seriesname)) + ' - formatrem_seriesname :' + formatrem_seriesname.lower())
if formatrem_seriesname.lower() in formatrem_torsplit.lower() or any(x.lower() in formatrem_torsplit.lower() for x in AS_Alt):
logger.fdebug('matched to : ' + torTITLE)
logger.fdebug('matched on series title: ' + seriesname)
#logger.fdebug('matched to : ' + torTITLE)
#logger.fdebug('matched on series title: ' + seriesname)
titleend = formatrem_torsplit[len(formatrem_seriesname):]
titleend = re.sub('\-', '', titleend) #remove the '-' which is unnecessary
#remove extensions
titleend = re.sub('cbr', '', titleend)
titleend = re.sub('cbz', '', titleend)
titleend = re.sub('none', '', titleend)
logger.fdebug('titleend: ' + titleend)
#logger.fdebug('titleend: ' + titleend)
sptitle = titleend.split()
extra = ''
#the title on 32P has a mix-mash of crap...ignore everything after cbz/cbr to cleanit
#ctitle = torTITLE.find('cbr')
#if ctitle == 0:
# ctitle = torTITLE.find('cbz')
# if ctitle == 0:
# ctitle = torTITLE.find('none')
# if ctitle == 0:
# logger.fdebug('cannot determine title properly - ignoring for now.')
# continue
#cttitle = torTITLE[:ctitle]
# if tor['Site'] == '32P':
# st_pub = rebuiltline.find('(')
# if st_pub < 2 and st_pub != -1:
# st_end = rebuiltline.find(')')
# rebuiltline = rebuiltline[st_end +1:]
tortheinfo.append({
'title': torTITLE, #cttitle,
'link': tor['Link'],

View File

@ -94,6 +94,9 @@ def search_init(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueD
torprovider = []
torp = 0
torznabs = 0
torznab_hosts = []
logger.fdebug("Checking for torrent enabled.")
checked_once = False
if mylar.CONFIG.ENABLE_TORRENT_SEARCH: #and mylar.CONFIG.ENABLE_TORRENTS:
@ -103,9 +106,13 @@ def search_init(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueD
if mylar.CONFIG.ENABLE_PUBLIC:
torprovider.append('public torrents')
torp+=1
if mylar.CONFIG.ENABLE_TORZNAB:
torprovider.append('torznab')
torp+=1
if mylar.CONFIG.ENABLE_TORZNAB is True:
for torznab_host in mylar.CONFIG.EXTRA_TORZNABS:
if torznab_host[4] == '1' or torznab_host[4] == 1:
torznab_hosts.append(torznab_host)
torprovider.append('torznab:' + str(torznab_host[0]))
torznabs+=1
##nzb provider selection##
##'dognzb' or 'nzb.su' or 'experimental'
nzbprovider = []
@ -136,20 +143,19 @@ def search_init(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueD
logger.fdebug('nzbprovider(s): ' + str(nzbprovider))
# --------
logger.fdebug("there are : " + str(torp) + " torrent providers you have selected.")
torpr = torp - 1
torproviders = torp + torznabs
logger.fdebug('There are %s torrent providers you have selected.' % torproviders)
torpr = torproviders - 1
if torpr < 0:
torpr = -1
providercount = int(nzbp + newznabs)
logger.fdebug("there are : " + str(providercount) + " nzb providers you have selected.")
logger.fdebug("Usenet Retention : " + str(mylar.CONFIG.USENET_RETENTION) + " days")
#nzbpr = providercount - 1
#if nzbpr < 0:
# nzbpr == 0
if providercount > 0:
logger.fdebug("Usenet Retention : " + str(mylar.CONFIG.USENET_RETENTION) + " days")
findit = {}
findit['status'] = False
totalproviders = providercount + torp
totalproviders = providercount + torproviders
if totalproviders == 0:
logger.error('[WARNING] You have ' + str(totalproviders) + ' search providers enabled. I need at least ONE provider to work. Aborting search.')
@ -157,7 +163,7 @@ def search_init(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueD
nzbprov = None
return findit, nzbprov
prov_order, newznab_info = provider_sequence(nzbprovider, torprovider, newznab_hosts)
prov_order, torznab_info, newznab_info = provider_sequence(nzbprovider, torprovider, newznab_hosts, torznab_hosts)
# end provider order sequencing
logger.info('search provider order is ' + str(prov_order))
@ -271,12 +277,18 @@ def search_init(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueD
while (tmp_prov_count > prov_count):
send_prov_count = tmp_prov_count - prov_count
newznab_host = None
torznab_host = None
if prov_order[prov_count] == '32p':
searchprov = '32P'
elif prov_order[prov_count] == 'public torrents':
searchprov = 'Public Torrents'
elif prov_order[prov_count] == 'torznab':
searchprov = 'Torznab'
elif 'torznab' in prov_order[prov_count]:
searchprov = 'torznab'
for nninfo in torznab_info:
if nninfo['provider'] == prov_order[prov_count]:
torznab_host = nninfo['info']
if torznab_host is None:
logger.fdebug('there was an error - torznab information was blank and it should not be.')
elif 'newznab' in prov_order[prov_count]:
#this is for newznab
searchprov = 'newznab'
@ -287,6 +299,7 @@ def search_init(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueD
logger.fdebug('there was an error - newznab information was blank and it should not be.')
else:
newznab_host = None
torznab_host = None
searchprov = prov_order[prov_count].lower()
if searchprov == 'dognzb' and mylar.CONFIG.DOGNZB == 0:
@ -298,7 +311,7 @@ def search_init(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueD
prov_count+=1
continue
if searchmode == 'rss':
findit = NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDate, StoreDate, searchprov, send_prov_count, IssDateFix, IssueID, UseFuzzy, newznab_host, ComicVersion=ComicVersion, SARC=SARC, IssueArcID=IssueArcID, RSS="yes", ComicID=ComicID, issuetitle=issuetitle, unaltered_ComicName=unaltered_ComicName, oneoff=oneoff, cmloopit=cmloopit, manual=manual)
findit = NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDate, StoreDate, searchprov, send_prov_count, IssDateFix, IssueID, UseFuzzy, newznab_host, ComicVersion=ComicVersion, SARC=SARC, IssueArcID=IssueArcID, RSS="yes", ComicID=ComicID, issuetitle=issuetitle, unaltered_ComicName=unaltered_ComicName, oneoff=oneoff, cmloopit=cmloopit, manual=manual, torznab_host=torznab_host)
if findit['status'] is False:
if AlternateSearch is not None and AlternateSearch != "None":
chkthealt = AlternateSearch.split('##')
@ -308,7 +321,7 @@ def search_init(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueD
for calt in chkthealt:
AS_Alternate = re.sub('##', '', calt)
logger.info(u"Alternate Search pattern detected...re-adjusting to : " + str(AS_Alternate))
findit = NZB_SEARCH(AS_Alternate, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDate, StoreDate, searchprov, send_prov_count, IssDateFix, IssueID, UseFuzzy, newznab_host, ComicVersion=ComicVersion, SARC=SARC, IssueArcID=IssueArcID, RSS="yes", ComicID=ComicID, issuetitle=issuetitle, unaltered_ComicName=AS_Alternate, allow_packs=allow_packs, oneoff=oneoff, cmloopit=cmloopit, manual=manual)
findit = NZB_SEARCH(AS_Alternate, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDate, StoreDate, searchprov, send_prov_count, IssDateFix, IssueID, UseFuzzy, newznab_host, ComicVersion=ComicVersion, SARC=SARC, IssueArcID=IssueArcID, RSS="yes", ComicID=ComicID, issuetitle=issuetitle, unaltered_ComicName=AS_Alternate, allow_packs=allow_packs, oneoff=oneoff, cmloopit=cmloopit, manual=manual, torznab_host=torznab_host)
if findit['status'] is True:
break
if findit['status'] is True:
@ -318,7 +331,7 @@ def search_init(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueD
break
else:
findit = NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDate, StoreDate, searchprov, send_prov_count, IssDateFix, IssueID, UseFuzzy, newznab_host, ComicVersion=ComicVersion, SARC=SARC, IssueArcID=IssueArcID, RSS="no", ComicID=ComicID, issuetitle=issuetitle, unaltered_ComicName=unaltered_ComicName, allow_packs=allow_packs, oneoff=oneoff, cmloopit=cmloopit, manual=manual)
findit = NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDate, StoreDate, searchprov, send_prov_count, IssDateFix, IssueID, UseFuzzy, newznab_host, ComicVersion=ComicVersion, SARC=SARC, IssueArcID=IssueArcID, RSS="no", ComicID=ComicID, issuetitle=issuetitle, unaltered_ComicName=unaltered_ComicName, allow_packs=allow_packs, oneoff=oneoff, cmloopit=cmloopit, manual=manual, torznab_host=torznab_host)
if all([searchprov == '32P', checked_once is False]) or all([searchprov == 'Public Torrents', checked_once is False]):
checked_once = True
if findit['status'] is False:
@ -330,7 +343,7 @@ def search_init(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueD
for calt in chkthealt:
AS_Alternate = re.sub('##', '', calt)
logger.info(u"Alternate Search pattern detected...re-adjusting to : " + str(AS_Alternate))
findit = NZB_SEARCH(AS_Alternate, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDate, StoreDate, searchprov, send_prov_count, IssDateFix, IssueID, UseFuzzy, newznab_host, ComicVersion=ComicVersion, SARC=SARC, IssueArcID=IssueArcID, RSS="no", ComicID=ComicID, issuetitle=issuetitle, unaltered_ComicName=unaltered_ComicName, allow_packs=allow_packs, oneoff=oneoff, cmloopit=cmloopit, manual=manual)
findit = NZB_SEARCH(AS_Alternate, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDate, StoreDate, searchprov, send_prov_count, IssDateFix, IssueID, UseFuzzy, newznab_host, ComicVersion=ComicVersion, SARC=SARC, IssueArcID=IssueArcID, RSS="no", ComicID=ComicID, issuetitle=issuetitle, unaltered_ComicName=unaltered_ComicName, allow_packs=allow_packs, oneoff=oneoff, cmloopit=cmloopit, manual=manual, torznab_host=torznab_host)
if findit['status'] is True:
break
if findit['status'] is True:
@ -341,6 +354,8 @@ def search_init(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueD
if searchprov == 'newznab':
searchprov = newznab_host[0].rstrip()
elif searchprov == 'torznab':
searchprov = torznab_host[0].rstrip()
if manual is not True:
if IssueNumber is not None:
issuedisplay = IssueNumber
@ -388,7 +403,7 @@ def search_init(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueD
return findit, 'None'
def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDate, StoreDate, nzbprov, prov_count, IssDateFix, IssueID, UseFuzzy, newznab_host=None, ComicVersion=None, SARC=None, IssueArcID=None, RSS=None, ComicID=None, issuetitle=None, unaltered_ComicName=None, allow_packs=None, oneoff=False, cmloopit=None, manual=False):
def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDate, StoreDate, nzbprov, prov_count, IssDateFix, IssueID, UseFuzzy, newznab_host=None, ComicVersion=None, SARC=None, IssueArcID=None, RSS=None, ComicID=None, issuetitle=None, unaltered_ComicName=None, allow_packs=None, oneoff=False, cmloopit=None, manual=False, torznab_host=None):
if any([allow_packs is None, allow_packs == 'None', allow_packs == 0, allow_packs == '0']) and all([mylar.CONFIG.ENABLE_TORRENT_SEARCH, mylar.CONFIG.ENABLE_32P]):
allow_packs = False
@ -406,8 +421,15 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
elif nzbprov == 'experimental':
apikey = 'none'
verify = False
elif nzbprov == 'Torznab':
elif nzbprov == 'torznab':
name_torznab = torznab_host[0].rstrip()
host_torznab = torznab_host[1].rstrip()
apikey = torznab_host[2].rstrip()
verify = False
category_torznab = torznab_host[3]
if any([category_torznab is None, category_torznab == 'None']):
category_torznab = '8020'
logger.fdebug("using Torznab host of : " + str(name_torznab))
elif nzbprov == 'newznab':
#updated to include Newznab Name now
name_newznab = newznab_host[0].rstrip()
@ -431,11 +453,15 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
if RSS == "yes":
if 'newznab' in nzbprov:
tmpprov = name_newznab + '(' + nzbprov + ')' + ' [RSS]'
elif 'torznab' in nzbprov:
tmpprov = name_torznab + '(' + nzbprov + ')' + ' [RSS]'
else:
tmpprov = str(nzbprov) + " [RSS]"
else:
if 'newznab' in nzbprov:
tmpprov = name_newznab + ' (' + nzbprov + ')'
elif 'torznab' in nzbprov:
tmpprov = name_torznab + ' (' + nzbprov + ')'
else:
tmpprov = nzbprov
if IssueNumber is not None:
@ -558,6 +584,8 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
logger.fdebug("Sending request to RSS for " + str(findcomic) + " : " + str(mod_isssearch) + " (" + str(ComicYear) + ")")
if nzbprov == 'newznab':
nzbprov_fix = name_newznab
elif nzbprov == 'torznab':
nzbprov_fix = name_torznab
else: nzbprov_fix = nzbprov
bb = rsscheck.nzbdbsearch(findcomic, mod_isssearch, ComicID, nzbprov_fix, ComicYear, ComicVersion, oneoff)
if bb is None:
@ -601,15 +629,14 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
host_newznab_fix = str(host_newznab) + "/"
else: host_newznab_fix = host_newznab
findurl = str(host_newznab_fix) + "api?t=search&q=" + str(comsearch) + "&o=xml&cat=" + str(category_newznab)
elif nzbprov == 'Torznab':
if mylar.CONFIG.TORZNAB_HOST.endswith('/'):
#http://localhost:9117/api/iptorrents
torznab_fix = mylar.CONFIG.TORZNAB_HOST[:-1]
elif nzbprov == 'torznab':
if host_torznab[len(host_torznab)-1:len(host_torznab)] == '/':
torznab_fix = host_torznab[:-1]
else:
torznab_fix = mylar.CONFIG.TORZNAB_HOST
torznab_fix = host.torznab
findurl = str(torznab_fix) + "?t=search&q=" + str(comsearch)
if str(mylar.CONFIG.TORZNAB_CATEGORY): findurl += "&cat=" + str(mylar.CONFIG.TORZNAB_CATEGORY)
apikey = mylar.CONFIG.TORZNAB_APIKEY
if category_torznab is not None:
findurl += "&cat=" + str(category_torznab)
else:
logger.warn('You have a blank newznab entry within your configuration. Remove it, save the config and restart mylar to fix things. Skipping this blank provider until fixed.')
findurl = None
@ -1329,7 +1356,7 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
downloadit = True
else:
for x in mylar.COMICINFO:
if all([x['link'] == entry['link'], x['tmpprov'] == tmpprov]) or all([x['nzbid'] == nzbid, x['newznab'] == newznab_host]):
if all([x['link'] == entry['link'], x['tmpprov'] == tmpprov]) or all([x['nzbid'] == nzbid, x['newznab'] == newznab_host]) or all([x['nzbid'] == nzbid, x['torznab'] == torznab_host]):
nowrite = True
break
@ -1340,8 +1367,10 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
if newznab_host is not None:
tprov = newznab_host[0]
else:
kind = 'torrent'
tprov = nzbprov
kind = 'torrent'
if torznab_host is not None:
tprov = torznab_host[0]
mylar.COMICINFO.append({"ComicName": ComicName,
"ComicID": ComicID,
"IssueID": IssueID,
@ -1364,7 +1393,8 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
"kind": kind,
"SARC": SARC,
"IssueArcID": IssueArcID,
"newznab": newznab_host})
"newznab": newznab_host,
"torznab": torznab_host})
else:
@ -1662,7 +1692,7 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
#issue comparison now as well
if int(intIss) == int(comintIss):
nowrite = False
if nzbprov == 'Torznab' and 'worldwidetorrents' in entry['link']:
if nzbprov == 'torznab' and 'worldwidetorrents' in entry['link']:
nzbid = generate_id(nzbprov, entry['id'])
else:
nzbid = generate_id(nzbprov, entry['link'])
@ -1670,7 +1700,7 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
downloadit = True
else:
for x in mylar.COMICINFO:
if all([x['link'] == entry['link'], x['tmpprov'] == tmpprov]) or all([x['nzbid'] == nzbid, x['newznab'] == newznab_host]):
if all([x['link'] == entry['link'], x['tmpprov'] == tmpprov]) or all([x['nzbid'] == nzbid, x['newznab'] == newznab_host]) or all([x['nzbid'] == nzbid, x['torznab'] == torznab_host]):
nowrite = True
break
@ -1696,6 +1726,8 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
else:
kind = 'torrent'
tprov = nzbprov
if torznab_host is not None:
tprov = torznab_host[0]
mylar.COMICINFO.append({"ComicName": ComicName,
"ComicID": ComicID,
@ -1719,7 +1751,8 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
"kind": kind,
"SARC": SARC,
"IssueArcID": IssueArcID,
"newznab": newznab_host})
"newznab": newznab_host,
"torznab": torznab_host})
else:
log2file = log2file + "issues don't match.." + "\n"
downloadit = False
@ -1744,7 +1777,7 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
'link': entry['link']}
except:
links = entry['link']
searchresult = searcher(nzbprov, nzbname, mylar.COMICINFO, links, IssueID, ComicID, tmpprov, newznab=newznab_host)
searchresult = searcher(nzbprov, nzbname, mylar.COMICINFO, links, IssueID, ComicID, tmpprov, newznab=newznab_host, torznab=torznab_host)
if searchresult == 'downloadchk-fail':
foundc['status'] = False
@ -1833,7 +1866,8 @@ def searchforissue(issueid=None, new=False, rsscheck=None, manual=False):
myDB = db.DBConnection()
ens = [x for x in mylar.CONFIG.EXTRA_NEWZNABS if x[5] == '1']
if (any([mylar.CONFIG.NZBSU is True, mylar.CONFIG.DOGNZB is True, mylar.CONFIG.EXPERIMENTAL is True]) or all([mylar.CONFIG.NEWZNAB is True, len(ens) > 0]) and any([mylar.USE_SABNZBD is True, mylar.USE_NZBGET is True, mylar.USE_BLACKHOLE is True])) or (all([mylar.CONFIG.ENABLE_TORRENT_SEARCH is True, mylar.CONFIG.ENABLE_TORRENTS is True]) and any([mylar.CONFIG.ENABLE_PUBLIC is True, mylar.CONFIG.ENABLE_32P is True, mylar.CONFIG.ENABLE_TORZNAB is True])):
ets = [x for x in mylar.CONFIG.EXTRA_TORZNABS if x[4] == '1']
if (any([mylar.CONFIG.NZBSU is True, mylar.CONFIG.DOGNZB is True, mylar.CONFIG.EXPERIMENTAL is True]) or all([mylar.CONFIG.NEWZNAB is True, len(ens) > 0]) and any([mylar.USE_SABNZBD is True, mylar.USE_NZBGET is True, mylar.USE_BLACKHOLE is True])) or (all([mylar.CONFIG.ENABLE_TORRENT_SEARCH is True, mylar.CONFIG.ENABLE_TORRENTS is True]) and (any([mylar.CONFIG.ENABLE_PUBLIC is True, mylar.CONFIG.ENABLE_32P is True]) or all([mylar.CONFIG.ENABLE_TORZNAB is True, len(ets) > 0]))):
if not issueid or rsscheck:
if rsscheck:
@ -2053,8 +2087,8 @@ def searchforissue(issueid=None, new=False, rsscheck=None, manual=False):
def searchIssueIDList(issuelist):
myDB = db.DBConnection()
ens = [x for x in mylar.CONFIG.EXTRA_NEWZNABS if x[5] == '1']
logger.info('issuelist: %s' % issuelist)
if (any([mylar.CONFIG.NZBSU is True, mylar.CONFIG.DOGNZB is True, mylar.CONFIG.EXPERIMENTAL is True]) or all([mylar.CONFIG.NEWZNAB is True, len(ens) > 0]) and any([mylar.USE_SABNZBD is True, mylar.USE_NZBGET is True, mylar.USE_BLACKHOLE is True])) or (all([mylar.CONFIG.ENABLE_TORRENT_SEARCH is True, mylar.CONFIG.ENABLE_TORRENTS is True]) and any([mylar.CONFIG.ENABLE_PUBLIC is True, mylar.CONFIG.ENABLE_32P is True, mylar.CONFIG.ENABLE_TORZNAB is True])):
ets = [x for x in mylar.CONFIG.EXTRA_TORZNABS if x[4] == '1']
if (any([mylar.CONFIG.NZBSU is True, mylar.CONFIG.DOGNZB is True, mylar.CONFIG.EXPERIMENTAL is True]) or all([mylar.CONFIG.NEWZNAB is True, len(ens) > 0]) and any([mylar.USE_SABNZBD is True, mylar.USE_NZBGET is True, mylar.USE_BLACKHOLE is True])) or (all([mylar.CONFIG.ENABLE_TORRENT_SEARCH is True, mylar.CONFIG.ENABLE_TORRENTS is True]) and (any([mylar.CONFIG.ENABLE_PUBLIC is True, mylar.CONFIG.ENABLE_32P is True]) or all([mylar.CONFIG.NEWZNAB is True, len(ets) > 0]))):
for issueid in issuelist:
logger.info('searching for issueid: %s' % issueid)
issue = myDB.selectone('SELECT * from issues WHERE IssueID=?', [issueid]).fetchone()
@ -2089,20 +2123,23 @@ def searchIssueIDList(issuelist):
foundNZB, prov = search_init(comic['ComicName'], issue['Issue_Number'], str(IssueYear), comic['ComicYear'], Publisher, issue['IssueDate'], issue['ReleaseDate'], issue['IssueID'], AlternateSearch, UseFuzzy, ComicVersion, SARC=None, IssueArcID=None, mode=mode, ComicID=issue['ComicID'], filesafe=comic['ComicName_Filesafe'], allow_packs=AllowPacks)
if foundNZB['status'] is True:
updater.foundsearch(ComicID=issue['ComicID'], IssueID=issue['IssueID'], mode=mode, provider=prov, hash=foundNZB['info']['t_hash'])
logger.info('Completed search request.')
else:
logger.warn('There are no search providers enabled atm - not performing the requested search for obvious reasons')
def provider_sequence(nzbprovider, torprovider, newznab_hosts):
def provider_sequence(nzbprovider, torprovider, newznab_hosts, torznab_hosts):
#provider order sequencing here.
newznab_info = []
torznab_info = []
prov_order = []
nzbproviders_lower = [x.lower() for x in nzbprovider]
torproviders_lower = [y.lower() for y in torprovider]
if len(mylar.CONFIG.PROVIDER_ORDER) > 0:
for pr_order in sorted(mylar.CONFIG.PROVIDER_ORDER.items(), key=itemgetter(0), reverse=False):
if (pr_order[1].lower() in torprovider) or any(pr_order[1].lower() in x for x in nzbproviders_lower):
if any(pr_order[1].lower() in y for y in torproviders_lower) or any(pr_order[1].lower() in x for x in nzbproviders_lower):
if any(pr_order[1].lower() in x for x in nzbproviders_lower):
# this is for nzb providers
for np in nzbprovider:
@ -2123,13 +2160,27 @@ def provider_sequence(nzbprovider, torprovider, newznab_hosts):
elif pr_order[1].lower() in np.lower():
prov_order.append(pr_order[1])
break
else:
elif any(pr_order[1].lower() in y for y in torproviders_lower):
for tp in torprovider:
if (pr_order[1].lower() in tp.lower()):
prov_order.append(tp) #torrent provider
if all(['torznab' in tp, pr_order[1].lower() in tp.lower()]):
for torznab_host in torznab_hosts:
if torznab_host[0].lower() == pr_order[1].lower():
prov_order.append(tp)
torznab_info.append({"provider": tp,
"info": torznab_host})
break
else:
if torznab_host[0] == "":
if torznab_host[1].lower() == pr_order[1].lower():
prov_order.append(tp)
torznab_info.append({"provider": tp,
"info": torznab_host})
break
elif (pr_order[1].lower() in tp.lower()):
prov_order.append(pr_order[1])
break
return prov_order, newznab_info
return prov_order, torznab_info, newznab_info
def nzbname_create(provider, title=None, info=None):
#the nzbname here is used when post-processing
@ -2198,7 +2249,7 @@ def nzbname_create(provider, title=None, info=None):
logger.fdebug("nzbname used for post-processing:" + nzbname)
return nzbname
def searcher(nzbprov, nzbname, comicinfo, link, IssueID, ComicID, tmpprov, directsend=None, newznab=None):
def searcher(nzbprov, nzbname, comicinfo, link, IssueID, ComicID, tmpprov, directsend=None, newznab=None, torznab=None):
alt_nzbname = None
#load in the details of the issue from the tuple.
ComicName = comicinfo[0]['ComicName']
@ -2237,7 +2288,7 @@ def searcher(nzbprov, nzbname, comicinfo, link, IssueID, ComicID, tmpprov, direc
#if sab priority isn't selected, default to Normal (0)
nzbgetpriority = "0"
if nzbprov == 'Torznab':
if nzbprov == 'torznab':
nzbid = generate_id(nzbprov, link['id'])
link = link['link']
else:
@ -2292,7 +2343,7 @@ def searcher(nzbprov, nzbname, comicinfo, link, IssueID, ComicID, tmpprov, direc
else:
logger.fdebug('[FAILED_DOWNLOAD_CHECKER] Failed download checking is not available for one-off downloads atm. Fixed soon!')
if link and all([nzbprov != 'WWT', nzbprov != 'DEM', nzbprov != '32P', nzbprov != 'Torznab']):
if link and all([nzbprov != 'WWT', nzbprov != 'DEM', nzbprov != '32P', nzbprov != 'torznab']):
#generate nzbid here.
@ -2466,7 +2517,7 @@ def searcher(nzbprov, nzbname, comicinfo, link, IssueID, ComicID, tmpprov, direc
#blackhole
sent_to = None
t_hash = None
if mylar.USE_BLACKHOLE and all([nzbprov != '32P', nzbprov != 'WWT', nzbprov != 'DEM', nzbprov != 'Torznab']):
if mylar.USE_BLACKHOLE and all([nzbprov != '32P', nzbprov != 'WWT', nzbprov != 'DEM', nzbprov != 'torznab']):
logger.fdebug("using blackhole directory at : " + str(mylar.CONFIG.BLACKHOLE_DIR))
if os.path.exists(mylar.CONFIG.BLACKHOLE_DIR):
#copy the nzb from nzbpath to blackhole dir.
@ -2512,7 +2563,7 @@ def searcher(nzbprov, nzbname, comicinfo, link, IssueID, ComicID, tmpprov, direc
#end blackhole
#torrents (32P & DEM)
elif any([nzbprov == '32P', nzbprov == 'WWT', nzbprov == 'DEM', nzbprov == 'Torznab']):
elif any([nzbprov == '32P', nzbprov == 'WWT', nzbprov == 'DEM', nzbprov == 'torznab']):
logger.fdebug("ComicName:" + ComicName)
logger.fdebug("link:" + link)
logger.fdebug("Torrent Provider:" + nzbprov)
@ -3054,7 +3105,7 @@ def generate_id(nzbprov, link):
if '&id' not in tmpid or nzbid == '':
tmpid = urlparse.urlparse(link)[2]
nzbid = tmpid.rsplit('/', 1)[1]
elif nzbprov == 'Torznab':
elif nzbprov == 'torznab':
idtmp = urlparse.urlparse(link)[4]
idpos = idtmp.find('&')
nzbid = re.sub('id=', '', idtmp[:idpos]).strip()

View File

@ -44,7 +44,7 @@ class RTorrent(object):
mylar.CONFIG.RTORRENT_SSL,
mylar.CONFIG.RTORRENT_RPC_URL,
mylar.CONFIG.RTORRENT_CA_BUNDLE):
logger.error('could not connect to %s, exiting', mylar.CONFIG.RTORRENT_HOST)
logger.error('[ERROR] Could not connect to %s - exiting' % mylar.CONFIG.RTORRENT_HOST)
sys.exit(-1)
def main(self, torrent_hash=None, filepath=None, check=False):
@ -52,13 +52,13 @@ class RTorrent(object):
torrent = self.client.find_torrent(torrent_hash)
if torrent:
if check:
logger.fdebug('Successfully located torrent %s by hash on client. Detailed statistics to follow', torrent_hash)
logger.fdebug('Successfully located torrent %s by hash on client. Detailed statistics to follow' % torrent_hash)
else:
logger.warn("%s Torrent already exists. Not downloading at this time.", torrent_hash)
logger.warn("%s Torrent already exists. Not downloading at this time." % torrent_hash)
return
else:
if check:
logger.warn('Unable to locate torrent with a hash value of %s', torrent_hash)
logger.warn('Unable to locate torrent with a hash value of %s' % torrent_hash)
return
if filepath:
@ -76,7 +76,7 @@ class RTorrent(object):
torrent = self.client.find_torrent(torrent_hash)
if torrent is None:
logger.warn("Couldn't find torrent with hash: %s", torrent_hash)
logger.warn('Couldn\'t find torrent with hash: %s' % torrent_hash)
sys.exit(-1)
torrent_info = self.client.get_torrent(torrent)
@ -84,18 +84,18 @@ class RTorrent(object):
return torrent_info
if torrent_info['completed']:
logger.fdebug("Directory: %s", torrent_info['folder'])
logger.fdebug("Name: %s", torrent_info['name'])
logger.fdebug("FileSize: %s", helpers.human_size(torrent_info['total_filesize']))
logger.fdebug("Completed: %s", torrent_info['completed'])
logger.fdebug("Downloaded: %s", helpers.human_size(torrent_info['download_total']))
logger.fdebug("Uploaded: %s", helpers.human_size(torrent_info['upload_total']))
logger.fdebug("Ratio: %s", torrent_info['ratio'])
#logger.info("Time Started: %s", torrent_info['time_started'])
logger.fdebug("Seeding Time: %s", helpers.humanize_time(int(time.time()) - torrent_info['time_started']))
logger.fdebug('Directory: %s' % torrent_info['folder'])
logger.fdebug('Name: %s' % torrent_info['name'])
logger.fdebug('FileSize: %s' % helpers.human_size(torrent_info['total_filesize']))
logger.fdebug('Completed: %s' % torrent_info['completed'])
logger.fdebug('Downloaded: %s' % helpers.human_size(torrent_info['download_total']))
logger.fdebug('Uploaded: %s' % helpers.human_size(torrent_info['upload_total']))
logger.fdebug('Ratio: %s' % torrent_info['ratio'])
#logger.info('Time Started: %s' % torrent_info['time_started'])
logger.fdebug('Seeding Time: %s' % helpers.humanize_time(int(time.time()) - torrent_info['time_started']))
if torrent_info['label']:
logger.fdebug("Torrent Label: %s", torrent_info['label'])
logger.fdebug('Torrent Label: %s' % torrent_info['label'])
#logger.info(torrent_info)
return torrent_info
@ -106,5 +106,5 @@ class RTorrent(object):
metainfo = bencode.decode(torrent_file.read())
info = metainfo['info']
thehash = hashlib.sha1(bencode.encode(info)).hexdigest().upper()
logger.fdebug('Hash: ' + thehash)
logger.fdebug('Hash: %s' % thehash)
return thehash

View File

@ -2732,8 +2732,10 @@ class WebInterface(object):
valid_readingorder = None
#validate input here for reading order.
try:
if int(readingorder) > 0:
if int(readingorder) >= 0:
valid_readingorder = int(readingorder)
if valid_readingorder == 0:
valid_readingorder = 1
except ValueError:
logger.error('Non-Numeric/Negative readingorder submitted. Rejecting due to sequencing error.')
return
@ -2749,44 +2751,64 @@ class WebInterface(object):
return
new_readorder = []
for rc in readchk:
if issuearcid == rc['IssueArcID']:
oldreadorder = int(rc['ReadingOrder'])
new_readorder.append({'IssueArcID': issuearcid,
'IssueID': rc['IssueID'],
'ReadingOrder': valid_readingorder})
else:
if int(rc['ReadingOrder']) >= valid_readingorder:
reading_seq = int(rc['ReadingOrder']) + 1
oldreading_seq = None
logger.fdebug('[%s] Issue to renumber sequence from : %s' % (issuearcid, valid_readingorder))
reading_seq = 1
for rc in sorted(readchk, key=itemgetter('ReadingOrder'), reverse=False):
if str(issuearcid) == str(rc['IssueArcID']):
logger.fdebug('new order sequence detected at #: %s' % valid_readingorder)
if valid_readingorder > int(rc['ReadingOrder']):
oldreading_seq = int(rc['ReadingOrder'])
else:
reading_seq = int(rc['ReadingOrder']) - 1
if reading_seq == 0:
reading_seq = 1
new_readorder.append({'IssueArcID': rc['IssueArcID'],
'IssueID': rc['IssueID'],
'ReadingOrder': reading_seq})
oldreading_seq = int(rc['ReadingOrder']) + 1
reading_seq = valid_readingorder
issueid = rc['IssueID']
IssueArcID = issuearcid
elif int(rc['ReadingOrder']) < valid_readingorder:
logger.fdebug('keeping issue sequence of order #: %s' % rc['ReadingOrder'])
reading_seq = int(rc['ReadingOrder'])
issueid = rc['IssueID']
IssueArcID = rc['IssueArcID']
elif int(rc['ReadingOrder']) >= valid_readingorder:
if oldreading_seq is not None:
if valid_readingorder <= len(readchk):
reading_seq = int(rc['ReadingOrder'])
#reading_seq = oldreading_seq
else:
#valid_readingorder
if valid_readingorder < old_reading_seq:
logger.info('2')
reading_seq = int(rc['ReadingOrder'])
else:
logger.info('3')
reading_seq = oldreading_seq +1
logger.fdebug('old sequence discovered at %s to %s' % (oldreading_seq, reading_seq))
oldreading_seq = None
elif int(rc['ReadingOrder']) == valid_readingorder:
reading_seq = valid_readingorder +1
else:
reading_seq +=1 #valid_readingorder + (int(rc['ReadingOrder']) - valid_readingorder) +1
issueid = rc['IssueID']
IssueArcID = rc['IssueArcID']
logger.fdebug('reordering existing sequence as lower sequence has changed. Altering from %s to %s' % (rc['ReadingOrder'], reading_seq))
new_readorder.append({'IssueArcID': IssueArcID,
'IssueID': issueid,
'ReadingOrder': reading_seq})
#we resequence in the following way:
# everything before the new reading number stays the same
# everything after the new reading order gets incremented
# add in the new reading order at the desired sequence
# check for empty spaces (missing numbers in sequence) and fill them in.
logger.fdebug(new_readorder)
newrl = 0
logger.fdebug('new reading order: %s' % new_readorder)
#newrl = 0
for rl in sorted(new_readorder, key=itemgetter('ReadingOrder'), reverse=False):
if rl['ReadingOrder'] - 1 != newrl:
rorder = newrl + 1
logger.fdebug(rl['IssueID'] + ' - changing reading order seq to : ' + str(rorder))
else:
rorder = rl['ReadingOrder']
logger.fdebug(rl['IssueID'] + ' - setting reading order seq to : ' + str(rorder))
rl_ctrl = {"IssueID": rl['IssueID'],
"IssueArcID": rl['IssueArcID'],
"StoryArcID": storyarcid}
r1_new = {"ReadingOrder": rorder}
newrl = rorder
r1_new = {"ReadingOrder": rl['ReadingOrder']}
myDB.upsert("storyarcs", r1_new, rl_ctrl)
@ -3516,7 +3538,7 @@ class WebInterface(object):
ReadMassCopy.exposed = True
def logs(self):
return serve_template(templatename="logs.html", title="Log", lineList=mylar.LOG_LIST)
return serve_template(templatename="logs.html", title="Log", lineList=mylar.LOGLIST)
logs.exposed = True
def config_dump(self):
@ -3524,7 +3546,7 @@ class WebInterface(object):
config_dump.exposed = True
def clearLogs(self):
mylar.LOG_LIST = []
mylar.LOGLIST = []
logger.info("Web logs cleared")
raise cherrypy.HTTPRedirect("logs")
clearLogs.exposed = True
@ -3544,9 +3566,9 @@ class WebInterface(object):
filtered = []
if sSearch == "" or sSearch == None:
filtered = mylar.LOG_LIST[::]
filtered = mylar.LOGLIST[::]
else:
filtered = [row for row in mylar.LOG_LIST for column in row if sSearch.lower() in column.lower()]
filtered = [row for row in mylar.LOGLIST for column in row if sSearch.lower() in column.lower()]
sortcolumn = 0
if iSortCol_0 == '1':
sortcolumn = 2
@ -3558,7 +3580,7 @@ class WebInterface(object):
rows = [[row[0], row[2], row[1]] for row in rows]
return json.dumps({
'iTotalDisplayRecords': len(filtered),
'iTotalRecords': len(mylar.LOG_LIST),
'iTotalRecords': len(mylar.LOGLIST),
'aaData': rows,
})
getLog.exposed = True
@ -4465,10 +4487,7 @@ class WebInterface(object):
"dognzb_verify": helpers.checked(mylar.CONFIG.DOGNZB_VERIFY),
"experimental": helpers.checked(mylar.CONFIG.EXPERIMENTAL),
"enable_torznab": helpers.checked(mylar.CONFIG.ENABLE_TORZNAB),
"torznab_name": mylar.CONFIG.TORZNAB_NAME,
"torznab_host": mylar.CONFIG.TORZNAB_HOST,
"torznab_apikey": mylar.CONFIG.TORZNAB_APIKEY,
"torznab_category": mylar.CONFIG.TORZNAB_CATEGORY,
"extra_torznabs": sorted(mylar.CONFIG.EXTRA_TORZNABS, key=itemgetter(4), reverse=True),
"newznab": helpers.checked(mylar.CONFIG.NEWZNAB),
"extra_newznabs": sorted(mylar.CONFIG.EXTRA_NEWZNABS, key=itemgetter(5), reverse=True),
"enable_rss": helpers.checked(mylar.CONFIG.ENABLE_RSS),
@ -4541,6 +4560,7 @@ class WebInterface(object):
"pushover_onsnatch": helpers.checked(mylar.CONFIG.PUSHOVER_ONSNATCH),
"pushover_apikey": mylar.CONFIG.PUSHOVER_APIKEY,
"pushover_userkey": mylar.CONFIG.PUSHOVER_USERKEY,
"pushover_device": mylar.CONFIG.PUSHOVER_DEVICE,
"pushover_priority": mylar.CONFIG.PUSHOVER_PRIORITY,
"boxcar_enabled": helpers.checked(mylar.CONFIG.BOXCAR_ENABLED),
"boxcar_onsnatch": helpers.checked(mylar.CONFIG.BOXCAR_ONSNATCH),
@ -4823,6 +4843,28 @@ class WebInterface(object):
mylar.CONFIG.EXTRA_NEWZNABS.append((newznab_name, newznab_host, newznab_verify, newznab_api, newznab_uid, newznab_enabled))
mylar.CONFIG.EXTRA_TORZNABS = []
for kwarg in [x for x in kwargs if x.startswith('torznab_name')]:
if kwarg.startswith('torznab_name'):
torznab_number = kwarg[12:]
torznab_name = kwargs['torznab_name' + torznab_number]
if torznab_name == "":
torznab_name = kwargs['torznab_host' + torznab_number]
if torznab_name == "":
continue
torznab_host = helpers.clean_url(kwargs['torznab_host' + torznab_number])
torznab_api = kwargs['torznab_apikey' + torznab_number]
torznab_category = kwargs['torznab_category' + torznab_number]
try:
torznab_enabled = str(kwargs['torznab_enabled' + torznab_number])
except KeyError:
torznab_enabled = '0'
del kwargs[kwarg]
mylar.CONFIG.EXTRA_TORZNABS.append((torznab_name, torznab_host, torznab_api, torznab_category, torznab_enabled))
mylar.CONFIG.process_kwargs(kwargs)
#this makes sure things are set to the default values if they're not appropriately set.
@ -4922,6 +4964,45 @@ class WebInterface(object):
return "Invalid SABnzbd host specified"
SABtest.exposed = True
def NZBGet_test(self, nzbhost=None, nzbport=None, nzbusername=None, nzbpassword=None):
if nzbhost is None:
nzbhost = mylar.CONFIG.NZBGET_HOST
if nzbport is None:
nzbport = mylar.CONFIG.NZBGET_PORT
if nzbusername is None:
nzbusername = mylar.CONFIG.NZBGET_USERNAME
if nzbpassword is None:
nzbpassword = mylar.CONFIG.NZBGET_PASSWORD
logger.fdebug('Now attempting to test NZBGet connection')
if nzbusername is None or nzbpassword is None:
logger.error('No Username / Password provided for NZBGet credentials. Unable to test API key')
return "Invalid Username/Password provided"
logger.info('Now testing connection to NZBGet @ %s:%s' % (nzbhost, nzbport))
if nzbhost[:5] == 'https':
protocol = 'https'
nzbgethost = nzbhost[8:]
elif nzbhost[:4] == 'http':
protocol = 'http'
nzbgethost = nzbhost[7:]
nzb_url = '%s://%s:%s@%s:%s/xmlrpc' % (protocol, nzbusername, nzbpassword, nzbgethost, nzbport)
logger.info('nzb_url: %s' % nzb_url)
import xmlrpclib
nzbserver = xmlrpclib.ServerProxy(nzb_url)
try:
r = nzbserver.status()
except Exception as e:
logger.warn('Error fetching data: %s' % e)
return 'Unable to retrieve data from NZBGet'
logger.info('Successfully verified connection to NZBGet at %s:%s' % (nzbgethost, nzbport))
return "Successfully verified connection to NZBGet"
NZBGet_test.exposed = True
def shutdown(self):
mylar.SIGNAL = 'shutdown'
message = 'Shutting Down...'
@ -5231,8 +5312,8 @@ class WebInterface(object):
return "Error sending test message to Boxcar"
testboxcar.exposed = True
def testpushover(self, apikey, userkey):
pushover = notifiers.PUSHOVER(test_apikey=apikey, test_userkey=userkey)
def testpushover(self, apikey, userkey, device):
pushover = notifiers.PUSHOVER(test_apikey=apikey, test_userkey=userkey, test_device=device)
result = pushover.test_notify()
if result == True:
return "Successfully sent PushOver test - check to make sure it worked"

View File

@ -69,8 +69,7 @@ def initialize(options):
else:
protocol = "http"
logger.info("Starting Mylar on %s://%s:%d%s", protocol,
options['http_host'], options['http_port'], options['http_root'])
logger.info("Starting Mylar on %s://%s:%d%s" % (protocol,options['http_host'], options['http_port'], options['http_root']))
cherrypy.config.update(options_dict)
conf = {