mirror of https://github.com/evilhero/mylar
IMP: Added HTTPS support, with certificate/key generation, FIX: If a series had a ', search results would miss some key results when not hitting rss feeds, IMP: Better handling of series' that have non-alphanumeric characters when it comes to requesting search results, FIX: Removed some unnecessary spamming when file-checking/manual post-processing in relation to # signs
This commit is contained in:
parent
e80c39c085
commit
cd5a8b2be5
77
Mylar.py
77
Mylar.py
|
@ -15,6 +15,8 @@
|
|||
# along with Mylar. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os, sys, locale
|
||||
import errno
|
||||
import shutil
|
||||
import time
|
||||
import threading
|
||||
import signal
|
||||
|
@ -64,6 +66,7 @@ def main():
|
|||
parser.add_argument('-q', '--quiet', action='store_true', help='Turn off console logging')
|
||||
parser.add_argument('-d', '--daemon', action='store_true', help='Run as a daemon')
|
||||
parser.add_argument('-p', '--port', type=int, help='Force mylar to run on a specified port')
|
||||
parser.add_argument('-b', '--backup', action='store_true', help='Will automatically backup & keep the last 2 copies of the .db & ini files prior to startup')
|
||||
parser.add_argument('--datadir', help='Specify a directory where to store your data files')
|
||||
parser.add_argument('--config', help='Specify a config file to use')
|
||||
parser.add_argument('--nolaunch', action='store_true', help='Prevent browser from launching on startup')
|
||||
|
@ -85,7 +88,6 @@ def main():
|
|||
# except Exception, e:
|
||||
# sys.exit('Mylar failed to update.')
|
||||
|
||||
|
||||
if args.daemon:
|
||||
if sys.platform == 'win32':
|
||||
print "Daemonize not supported under Windows, starting normally"
|
||||
|
@ -142,6 +144,47 @@ def main():
|
|||
# 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.'
|
||||
backupdir = os.path.join(mylar.DATA_DIR, 'backup')
|
||||
|
||||
try:
|
||||
os.makedirs(backupdir)
|
||||
print '[AUTO-BACKUP] Directory does not exist for backup - creating : ' + backupdir
|
||||
except OSError as exception:
|
||||
if exception.errno != errno.EEXIST:
|
||||
print '[AUTO-BACKUP] Directory already exists.'
|
||||
raise
|
||||
|
||||
i = 0
|
||||
while (i < 2):
|
||||
if i == 0:
|
||||
ogfile = mylar.DB_FILE
|
||||
back = os.path.join(backupdir, 'mylar.db')
|
||||
back_1 = os.path.join(backupdir, 'mylar.db.1')
|
||||
else:
|
||||
ogfile = mylar.CONFIG_FILE
|
||||
back = os.path.join(backupdir, 'config.ini')
|
||||
back_1 = os.path.join(backupdir, 'config.ini.1')
|
||||
|
||||
try:
|
||||
print '[AUTO-BACKUP] Now Backing up mylar.db file'
|
||||
if os.path.isfile(back_1):
|
||||
print '[AUTO-BACKUP] ' + back_1 + ' exists. Deleting and keeping new.'
|
||||
os.remove(back_1)
|
||||
if os.path.isfile(back):
|
||||
print '[AUTO-BACKUP] Now renaming ' + back + ' to ' + back_1
|
||||
shutil.move(back, back_1)
|
||||
print '[AUTO-BACKUP] Now copying db file to ' + back
|
||||
shutil.copy(ogfile, back)
|
||||
|
||||
except OSError as exception:
|
||||
if exception.errno != errno.EXIST:
|
||||
raise
|
||||
|
||||
i+=1
|
||||
|
||||
mylar.CFG = ConfigObj(mylar.CONFIG_FILE, encoding='utf-8')
|
||||
|
||||
# Rename the main thread
|
||||
|
@ -160,16 +203,32 @@ def main():
|
|||
else:
|
||||
http_port = int(mylar.HTTP_PORT)
|
||||
|
||||
# Check if pyOpenSSL is installed. It is required for certificate generation
|
||||
# and for CherryPy.
|
||||
if mylar.ENABLE_HTTPS:
|
||||
try:
|
||||
import OpenSSL
|
||||
except ImportError:
|
||||
logger.warn("The pyOpenSSL module is missing. Install this " \
|
||||
"module to enable HTTPS. HTTPS will be disabled.")
|
||||
mylar.ENABLE_HTTPS = False
|
||||
|
||||
# Try to start the server. Will exit here is address is already in use.
|
||||
web_config = {
|
||||
'http_port': http_port,
|
||||
'http_host': mylar.HTTP_HOST,
|
||||
'http_root': mylar.HTTP_ROOT,
|
||||
'enable_https': mylar.ENABLE_HTTPS,
|
||||
'https_cert': mylar.HTTPS_CERT,
|
||||
'https_key': mylar.HTTPS_KEY,
|
||||
'http_username': mylar.HTTP_USERNAME,
|
||||
'http_password': mylar.HTTP_PASSWORD,
|
||||
}
|
||||
|
||||
# Try to start the server.
|
||||
webstart.initialize({
|
||||
'http_port': http_port,
|
||||
'http_host': mylar.HTTP_HOST,
|
||||
'http_root': mylar.HTTP_ROOT,
|
||||
'http_username': mylar.HTTP_USERNAME,
|
||||
'http_password': mylar.HTTP_PASSWORD,
|
||||
})
|
||||
webstart.initialize(web_config)
|
||||
|
||||
logger.info('Starting Mylar on port: %i' % http_port)
|
||||
#logger.info('Starting Mylar on port: %i' % http_port)
|
||||
|
||||
if mylar.LAUNCH_BROWSER and not args.nolaunch:
|
||||
mylar.launch_browser(mylar.HTTP_HOST, http_port, mylar.HTTP_ROOT)
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
<div align="center">
|
||||
<label><strong>Mylar is free to use,</br>
|
||||
but you can contribute and support the development</br>
|
||||
by giving a donation</strong></label></br></br>
|
||||
by buying me a coffee (or several)</strong></label></br></br>
|
||||
</div>
|
||||
<div style="width: 55%; margin: 0px auto;">
|
||||
<a href="https://flattr.com/submit/auto?user_id=evilhero&url=https://github.com/evilhero/mylar&title=Mylar%20Donation%description=Supporting&20the%development%20of%20Mylar&language=en_CA&hidden=1&category=software" target="_blank">
|
||||
|
@ -120,9 +120,27 @@
|
|||
<input type="text" name="http_host" value="${config['http_host']}" size="30">
|
||||
<small>e.g. localhost or 0.0.0.0</small>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>HTTP Port</label>
|
||||
<input type="text" name="http_port" value="${config['http_port']}" size="10">
|
||||
<div>
|
||||
<div class="row">
|
||||
<label>HTTP Port</label>
|
||||
<input type="text" name="http_port" value="${config['http_port']}" size="10">
|
||||
<div class="row checkbox">
|
||||
<input type="checkbox" name="enable_https" id="enable_https" value="1" ${config['enable_https']} />
|
||||
<label title="Enable HTTPS for web server for encrypted communication">
|
||||
Enable HTTPS
|
||||
</label>
|
||||
</div>
|
||||
<div id="https_options">
|
||||
<div class="row">
|
||||
<label>HTTPS Cert</label>
|
||||
<input type="text" title="the FULL path to the certificate" name="https_cert" value="${config['https_cert']}" size="30">
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>HTTPS Key</label>
|
||||
<input type="text" title="the FULL path to the key" name="https_key" value="${config['https_key']}" size="30">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label>HTTP Username</label>
|
||||
|
@ -136,6 +154,7 @@
|
|||
<div class="row checkbox">
|
||||
<input type="checkbox" name="launch_browser" value="1" ${config['launch_browser']} /> <label>Launch Browser on Startup</label>
|
||||
</div>
|
||||
|
||||
<!--
|
||||
<div class="row checkbox">
|
||||
<input type="checkbox" name="logverbose" value="2" ${config['logverbose']} /> <label>Verbose Logging</label>
|
||||
|
@ -150,6 +169,12 @@
|
|||
<input type="checkbox" name="cvapifix" value="1" ${config['cvapifix']} /> <label>Comicvine URL Fix</label>
|
||||
<br/><small>*Use this if CV's URL has changed*</small>
|
||||
</div>
|
||||
<!--
|
||||
<div class="row checkbox">
|
||||
<input type="checkbox" name="auto_update" value="1" ${config['auto_update']} /> <label>Automatic Updates</label>
|
||||
<br/><small>Install new updates with no intervention</small>
|
||||
</div>
|
||||
-->
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<legend>Annual Handling</legend>
|
||||
|
@ -1149,7 +1174,24 @@
|
|||
$('#api_key').val(data);
|
||||
});
|
||||
});
|
||||
|
||||
if ($("#enable_https").is(":checked"))
|
||||
{
|
||||
$("#https_options").show();
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#https_options").hide();
|
||||
}
|
||||
$("#enable_https").click(function(){
|
||||
if ($("#enable_https").is(":checked"))
|
||||
{
|
||||
$("#https_options").slideDown();
|
||||
}
|
||||
else
|
||||
{
|
||||
$("#https_options").slideUp();
|
||||
}
|
||||
});
|
||||
$('#sab_apikey').click(function(){ $('#sab_apikey').select() });
|
||||
$("#find_sabapi").click(function(){
|
||||
$.get('findsabAPI',
|
||||
|
@ -1185,6 +1227,7 @@
|
|||
});
|
||||
initActions();
|
||||
initConfigCheckbox("#launch_browser");
|
||||
initConfigCheckbox("#enable_https");
|
||||
initConfigCheckbox("#enable_api");
|
||||
initConfigCheckbox("#usenewznab");
|
||||
initConfigCheckbox("#usenzbsu");
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
# -*- coding: latin-1 -*-
|
||||
#
|
||||
# Copyright (C) Martin Sjögren and AB Strakt 2001, All rights reserved
|
||||
# Copyright (C) Jean-Paul Calderone 2008, All rights reserved
|
||||
# This file is licenced under the GNU LESSER GENERAL PUBLIC LICENSE Version 2.1 or later (aka LGPL v2.1)
|
||||
# Please see LGPL2.1.txt for more information
|
||||
"""
|
||||
Certificate generation module.
|
||||
"""
|
||||
|
||||
from OpenSSL import crypto
|
||||
import time
|
||||
|
||||
TYPE_RSA = crypto.TYPE_RSA
|
||||
TYPE_DSA = crypto.TYPE_DSA
|
||||
|
||||
serial = int(time.time())
|
||||
|
||||
|
||||
def createKeyPair(type, bits):
|
||||
"""
|
||||
Create a public/private key pair.
|
||||
|
||||
Arguments: type - Key type, must be one of TYPE_RSA and TYPE_DSA
|
||||
bits - Number of bits to use in the key
|
||||
Returns: The public/private key pair in a PKey object
|
||||
"""
|
||||
pkey = crypto.PKey()
|
||||
pkey.generate_key(type, bits)
|
||||
return pkey
|
||||
|
||||
def createCertRequest(pkey, digest="md5", **name):
|
||||
"""
|
||||
Create a certificate request.
|
||||
|
||||
Arguments: pkey - The key to associate with the request
|
||||
digest - Digestion method to use for signing, default is md5
|
||||
**name - The name of the subject of the request, possible
|
||||
arguments are:
|
||||
C - Country name
|
||||
ST - State or province name
|
||||
L - Locality name
|
||||
O - Organization name
|
||||
OU - Organizational unit name
|
||||
CN - Common name
|
||||
emailAddress - E-mail address
|
||||
Returns: The certificate request in an X509Req object
|
||||
"""
|
||||
req = crypto.X509Req()
|
||||
subj = req.get_subject()
|
||||
|
||||
for (key,value) in name.items():
|
||||
setattr(subj, key, value)
|
||||
|
||||
req.set_pubkey(pkey)
|
||||
req.sign(pkey, digest)
|
||||
return req
|
||||
|
||||
def createCertificate(req, (issuerCert, issuerKey), serial, (notBefore, notAfter), digest="md5"):
|
||||
"""
|
||||
Generate a certificate given a certificate request.
|
||||
|
||||
Arguments: req - Certificate reqeust to use
|
||||
issuerCert - The certificate of the issuer
|
||||
issuerKey - The private key of the issuer
|
||||
serial - Serial number for the certificate
|
||||
notBefore - Timestamp (relative to now) when the certificate
|
||||
starts being valid
|
||||
notAfter - Timestamp (relative to now) when the certificate
|
||||
stops being valid
|
||||
digest - Digest method to use for signing, default is md5
|
||||
Returns: The signed certificate in an X509 object
|
||||
"""
|
||||
cert = crypto.X509()
|
||||
cert.set_serial_number(serial)
|
||||
cert.gmtime_adj_notBefore(notBefore)
|
||||
cert.gmtime_adj_notAfter(notAfter)
|
||||
cert.set_issuer(issuerCert.get_subject())
|
||||
cert.set_subject(req.get_subject())
|
||||
cert.set_pubkey(req.get_pubkey())
|
||||
cert.sign(issuerKey, digest)
|
||||
return cert
|
|
@ -51,6 +51,7 @@ DAEMON = False
|
|||
PIDFILE= None
|
||||
CREATEPID = False
|
||||
SAFESTART = False
|
||||
AUTO_UPDATE = False
|
||||
|
||||
SCHED = Scheduler()
|
||||
|
||||
|
@ -104,6 +105,9 @@ HTTP_HOST = None
|
|||
HTTP_USERNAME = None
|
||||
HTTP_PASSWORD = None
|
||||
HTTP_ROOT = None
|
||||
ENABLE_HTTPS = False
|
||||
HTTPS_CERT = None
|
||||
HTTPS_KEY = None
|
||||
HTTPS_FORCE_ON = False
|
||||
API_ENABLED = False
|
||||
API_KEY = None
|
||||
|
@ -373,7 +377,7 @@ def initialize():
|
|||
with INIT_LOCK:
|
||||
|
||||
global __INITIALIZED__, DBCHOICE, DBUSER, DBPASS, DBNAME, COMICVINE_API, DEFAULT_CVAPI, CVAPI_COUNT, CVAPI_TIME, CVAPI_MAX, FULL_PATH, PROG_DIR, VERBOSE, DAEMON, COMICSORT, DATA_DIR, CONFIG_FILE, CFG, CONFIG_VERSION, LOG_DIR, CACHE_DIR, MAX_LOGSIZE, LOGVERBOSE, OLDCONFIG_VERSION, OS_DETECT, OS_LANG, OS_ENCODING, \
|
||||
queue, HTTP_PORT, HTTP_HOST, HTTP_USERNAME, HTTP_PASSWORD, HTTP_ROOT, HTTPS_FORCE_ON, API_ENABLED, API_KEY, LAUNCH_BROWSER, GIT_PATH, SAFESTART, \
|
||||
queue, HTTP_PORT, HTTP_HOST, HTTP_USERNAME, HTTP_PASSWORD, HTTP_ROOT, ENABLE_HTTPS, HTTPS_CERT, HTTPS_KEY, HTTPS_FORCE_ON, API_ENABLED, API_KEY, LAUNCH_BROWSER, GIT_PATH, SAFESTART, AUTO_UPDATE, \
|
||||
CURRENT_VERSION, LATEST_VERSION, CHECK_GITHUB, CHECK_GITHUB_ON_STARTUP, CHECK_GITHUB_INTERVAL, USER_AGENT, DESTINATION_DIR, MULTIPLE_DEST_DIRS, CREATE_FOLDERS, \
|
||||
DOWNLOAD_DIR, USENET_RETENTION, SEARCH_INTERVAL, NZB_STARTUP_SEARCH, INTERFACE, DUPECONSTRAINT, AUTOWANT_ALL, AUTOWANT_UPCOMING, ZERO_LEVEL, ZERO_LEVEL_N, COMIC_COVER_LOCAL, HIGHCOUNT, \
|
||||
LIBRARYSCAN, LIBRARYSCAN_INTERVAL, DOWNLOAD_SCAN_INTERVAL, NZB_DOWNLOADER, USE_SABNZBD, SAB_HOST, SAB_USERNAME, SAB_PASSWORD, SAB_APIKEY, SAB_CATEGORY, SAB_PRIORITY, SAB_DIRECTORY, USE_BLACKHOLE, BLACKHOLE_DIR, ADD_COMICS, COMIC_DIR, IMP_MOVE, IMP_RENAME, IMP_METADATA, \
|
||||
|
@ -410,6 +414,11 @@ def initialize():
|
|||
|
||||
if HTTP_PORT < 21 or HTTP_PORT > 65535:
|
||||
HTTP_PORT = 8090
|
||||
|
||||
if HTTPS_CERT == '':
|
||||
HTTPS_CERT = os.path.join(DATA_DIR, 'server.crt')
|
||||
if HTTPS_KEY == '':
|
||||
HTTPS_KEY = os.path.join(DATA_DIR, 'server.key')
|
||||
|
||||
CONFIG_VERSION = check_setting_str(CFG, 'General', 'config_version', '')
|
||||
DBCHOICE = check_setting_str(CFG, 'General', 'dbchoice', 'sqlite3')
|
||||
|
@ -427,10 +436,14 @@ def initialize():
|
|||
HTTP_USERNAME = check_setting_str(CFG, 'General', 'http_username', '')
|
||||
HTTP_PASSWORD = check_setting_str(CFG, 'General', 'http_password', '')
|
||||
HTTP_ROOT = check_setting_str(CFG, 'General', 'http_root', '/')
|
||||
ENABLE_HTTPS = bool(check_setting_int(CFG, 'General', 'enable_https', 0))
|
||||
HTTPS_CERT = check_setting_str(CFG, 'General', 'https_cert', '')
|
||||
HTTPS_KEY = check_setting_str(CFG, 'General', 'https_key', '')
|
||||
HTTPS_FORCE_ON = bool(check_setting_int(CFG, 'General', 'https_force_on', 0))
|
||||
API_ENABLED = bool(check_setting_int(CFG, 'General', 'api_enabled', 0))
|
||||
API_KEY = check_setting_str(CFG, 'General', 'api_key', '')
|
||||
LAUNCH_BROWSER = bool(check_setting_int(CFG, 'General', 'launch_browser', 1))
|
||||
AUTO_UPDATE = bool(check_setting_int(CFG, 'General', 'auto_update', 0))
|
||||
LOGVERBOSE = bool(check_setting_int(CFG, 'General', 'logverbose', 0))
|
||||
if LOGVERBOSE:
|
||||
VERBOSE = 2
|
||||
|
@ -924,6 +937,11 @@ def initialize():
|
|||
else:
|
||||
LATEST_VERSION = CURRENT_VERSION
|
||||
|
||||
# if AUTO_UPDATE:
|
||||
# if CURRENT_VERSION != LATEST_VERSION and INSTALL_TYPE != 'win' and COMMITS_BEHIND > 0:
|
||||
# logger.info('Auto-updating has been enabled. Attempting to auto-update.')
|
||||
# SIGNAL = 'update'
|
||||
|
||||
#check for syno_fix here
|
||||
if SYNO_FIX:
|
||||
parsepath = os.path.join(DATA_DIR, 'bs4', 'builder', '_lxml.py')
|
||||
|
@ -1100,10 +1118,14 @@ def config_write():
|
|||
new_config['General']['http_username'] = HTTP_USERNAME
|
||||
new_config['General']['http_password'] = HTTP_PASSWORD
|
||||
new_config['General']['http_root'] = HTTP_ROOT
|
||||
new_config['General']['enable_https'] = int(ENABLE_HTTPS)
|
||||
new_config['General']['https_cert'] = HTTPS_CERT
|
||||
new_config['General']['https_key'] = HTTPS_KEY
|
||||
new_config['General']['https_force_on'] = int(HTTPS_FORCE_ON)
|
||||
new_config['General']['api_enabled'] = int(API_ENABLED)
|
||||
new_config['General']['api_key'] = API_KEY
|
||||
new_config['General']['launch_browser'] = int(LAUNCH_BROWSER)
|
||||
new_config['General']['auto_update'] = int(AUTO_UPDATE)
|
||||
new_config['General']['log_dir'] = LOG_DIR
|
||||
new_config['General']['max_logsize'] = MAX_LOGSIZE
|
||||
new_config['General']['logverbose'] = int(LOGVERBOSE)
|
||||
|
|
|
@ -447,10 +447,8 @@ def listFiles(dir,watchcomic,Publisher,AlternateSearch=None,manual=None,sarc=Non
|
|||
fndit = 0
|
||||
blspc = 0
|
||||
if nono == '#':
|
||||
logger.info('# detected.')
|
||||
fndit = subname.find(nono)
|
||||
if subname[fndit+1].isdigit():
|
||||
logger.info('# detected before digits - assuming issue number.')
|
||||
subname = re.sub('#','',subname)
|
||||
continue
|
||||
while x < subcnt:
|
||||
|
|
|
@ -1649,6 +1649,42 @@ def duplicate_filecheck(filename, ComicID=None, IssueID=None, StoryArcID=None):
|
|||
rtnval = "write"
|
||||
return rtnval
|
||||
|
||||
def create_https_certificates(ssl_cert, ssl_key):
|
||||
"""
|
||||
Create a pair of self-signed HTTPS certificares and store in them in
|
||||
'ssl_cert' and 'ssl_key'. Method assumes pyOpenSSL is installed.
|
||||
|
||||
This code is stolen from SickBeard (http://github.com/midgetspy/Sick-Beard).
|
||||
"""
|
||||
|
||||
from mylar import logger
|
||||
|
||||
from OpenSSL import crypto
|
||||
from lib.certgen import createKeyPair, createCertRequest, createCertificate, \
|
||||
TYPE_RSA, serial
|
||||
|
||||
# Create the CA Certificate
|
||||
cakey = createKeyPair(TYPE_RSA, 2048)
|
||||
careq = createCertRequest(cakey, CN="Certificate Authority")
|
||||
cacert = createCertificate(careq, (careq, cakey), serial, (0, 60 * 60 * 24 * 365 * 10)) # ten years
|
||||
|
||||
pkey = createKeyPair(TYPE_RSA, 2048)
|
||||
req = createCertRequest(pkey, CN="Mylar")
|
||||
cert = createCertificate(req, (cacert, cakey), serial, (0, 60 * 60 * 24 * 365 * 10)) # ten years
|
||||
|
||||
# Save the key and certificate to disk
|
||||
try:
|
||||
with open(ssl_key, "w") as fp:
|
||||
fp.write(crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey))
|
||||
with open(ssl_cert, "w") as fp:
|
||||
fp.write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
|
||||
except IOError as e:
|
||||
logger.error("Error creating SSL key and certificate: %s", e)
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
from threading import Thread
|
||||
|
||||
class ThreadWithReturnValue(Thread):
|
||||
|
|
|
@ -789,8 +789,9 @@ def nzbdbsearch(seriesname,issue,comicid=None,nzbprov=None,searchYear=None,Comic
|
|||
return nzbinfo
|
||||
|
||||
def torsend2client(seriesname, issue, seriesyear, linkit, site):
|
||||
logger.info('matched on ' + str(seriesname))
|
||||
filename = re.sub('[\'\!\@\#\$\%\:\;\/\\=\?\.]', '',seriesname)
|
||||
logger.info('matched on ' + seriesname)
|
||||
filename = helpers.filesafe(seriesname)
|
||||
#filename = re.sub('[\'\!\@\#\$\%\:\;\/\\=\?\.]', '',seriesname)
|
||||
filename = re.sub(' ', '_', filename)
|
||||
filename += "_" + str(issue) + "_" + str(seriesyear)
|
||||
if site == 'CBT':
|
||||
|
|
|
@ -37,9 +37,14 @@ def search_init(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueD
|
|||
unaltered_ComicName = None
|
||||
if filesafe:
|
||||
if filesafe != ComicName and mode != 'want_ann':
|
||||
logger.info('[SEARCH] altering ComicName to search-safe Name : ' + filesafe)
|
||||
logger.info('[SEARCH] Special Characters exist within Series Title. Enabling search-safe Name : ' + filesafe)
|
||||
if AlternateSearch is None or AlternateSearch == 'None':
|
||||
AlternateSearch = filesafe
|
||||
else:
|
||||
AlternateSearch += '##' + filesafe
|
||||
unaltered_ComicName = ComicName
|
||||
ComicName = filesafe
|
||||
#ComicName = filesafe
|
||||
logger.info('AlternateSearch is : ' + AlternateSearch)
|
||||
if ComicYear == None: ComicYear = '2014'
|
||||
else: ComicYear = str(ComicYear)[:4]
|
||||
if Publisher == 'IDW Publishing': Publisher = 'IDW'
|
||||
|
@ -464,7 +469,7 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
|
|||
elif nzbprov == 'KAT':
|
||||
cmname = re.sub("%20", " ", str(comsrc))
|
||||
logger.fdebug("Sending request to [KAT] for " + str(cmname) + " : " + str(mod_isssearch))
|
||||
bb = rsscheck.torrents(pickfeed='KAT',seriesname=cmname,issue=mod_isssearch)
|
||||
bb = rsscheck.torrents(pickfeed='KAT',seriesname=cmname,issue=mod_isssearch)#cmname,issue=mod_isssearch)
|
||||
rss = "no"
|
||||
#if bb is not None: logger.fdebug("results: " + str(bb))
|
||||
elif nzbprov != 'experimental':
|
||||
|
@ -1018,6 +1023,7 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
|
|||
watchcomic_split = helpers.cleanName(str(findcomic))
|
||||
if '&' in watchcomic_split: watchcomic_split = re.sub('[/&]','and', watchcomic_split)
|
||||
watchcomic_nonsplit = re.sub('[\-\:\,\.\?]', ' ', watchcomic_split)
|
||||
watchcomic_nonsplit = re.sub('\'', '', watchcomic_nonsplit)
|
||||
watchcomic_split = watchcomic_nonsplit.split(None)
|
||||
|
||||
logger.fdebug(str(splitit) + " nzb series word count: " + str(splitst))
|
||||
|
@ -1288,7 +1294,7 @@ def NZB_SEARCH(ComicName, IssueNumber, ComicYear, SeriesYear, Publisher, IssueDa
|
|||
if '[RSS]' in tmpprov : tmpprov = re.sub('\[RSS\]','', tmpprov).strip()
|
||||
updater.nzblog(IssueID, nzbname, ComicName, SARC, IssueArcID, nzbid, tmpprov)
|
||||
#send out the notifications for the snatch.
|
||||
notify_snatch(nzbname, sent_to, modcomicname, comyear, IssueNumber, nzbprov)
|
||||
notify_snatch(nzbname, sent_to, helpers.filesafe(modcomicname), comyear, IssueNumber, nzbprov)
|
||||
prov_count == 0
|
||||
#break
|
||||
return foundc
|
||||
|
@ -1787,7 +1793,7 @@ def searcher(nzbprov, nzbname, comicinfo, link, IssueID, ComicID, tmpprov, direc
|
|||
if '[RSS]' in tmpprov : tmpprov = re.sub('\[RSS\]','', tmpprov).strip()
|
||||
updater.nzblog(IssueID, nzbname, ComicName, SARC=None, IssueArcID=None, id=nzbid, prov=tmpprov)
|
||||
#send out notifications for on snatch after the updater incase notification fails (it would bugger up the updater/pp scripts)
|
||||
notify_snatch(nzbname, sent_to, modcomicname, comyear, IssueNumber, nzbprov)
|
||||
notify_snatch(nzbname, sent_to, helpers.filesafe(modcomicname), comyear, IssueNumber, nzbprov)
|
||||
return
|
||||
|
||||
def notify_snatch(nzbname, sent_to, modcomicname, comyear, IssueNumber, nzbprov):
|
||||
|
|
|
@ -1232,8 +1232,14 @@ class WebInterface(object):
|
|||
raise cherrypy.HTTPRedirect("pullist")
|
||||
#return
|
||||
elif mode == 'want' or mode == 'want_ann' or manualsearch:
|
||||
cdname = myDB.selectone("SELECT ComicName, ComicName_Filesafe from comics where ComicID=?", [ComicID]).fetchone()
|
||||
ComicName = cdname['ComicName_Filesafe']
|
||||
cdname = myDB.selectone("SELECT * from comics where ComicID=?", [ComicID]).fetchone()
|
||||
ComicName_Filesafe = cdname['ComicName_Filesafe']
|
||||
SeriesYear = cdname['ComicYear']
|
||||
AlternateSearch = cdname['AlternateSearch']
|
||||
Publisher = cdname['ComicPublisher']
|
||||
UseAFuzzy = cdname['UseFuzzy']
|
||||
ComicVersion = cdname['ComicVersion']
|
||||
ComicName = cdname['ComicName']
|
||||
controlValueDict = {"IssueID": IssueID}
|
||||
newStatus = {"Status": "Wanted"}
|
||||
if mode == 'want':
|
||||
|
@ -1273,13 +1279,13 @@ class WebInterface(object):
|
|||
storedate = issues['IssueDate']
|
||||
else:
|
||||
storedate = issues['ReleaseDate']
|
||||
miy = myDB.selectone("SELECT * FROM comics WHERE ComicID=?", [ComicID]).fetchone()
|
||||
SeriesYear = miy['ComicYear']
|
||||
AlternateSearch = miy['AlternateSearch']
|
||||
Publisher = miy['ComicPublisher']
|
||||
UseAFuzzy = miy['UseFuzzy']
|
||||
ComicVersion = miy['ComicVersion']
|
||||
foundcom, prov = search.search_init(ComicName, ComicIssue, ComicYear, SeriesYear, Publisher, issues['IssueDate'], storedate, IssueID, AlternateSearch, UseAFuzzy, ComicVersion, mode=mode, ComicID=ComicID, manualsearch=manualsearch, filesafe=miy['ComicName_Filesafe'])
|
||||
#miy = myDB.selectone("SELECT * FROM comics WHERE ComicID=?", [ComicID]).fetchone()
|
||||
#SeriesYear = miy['ComicYear']
|
||||
#AlternateSearch = miy['AlternateSearch']
|
||||
#Publisher = miy['ComicPublisher']
|
||||
#UseAFuzzy = miy['UseFuzzy']
|
||||
#ComicVersion = miy['ComicVersion']
|
||||
foundcom, prov = search.search_init(ComicName, ComicIssue, ComicYear, SeriesYear, Publisher, issues['IssueDate'], storedate, IssueID, AlternateSearch, UseAFuzzy, ComicVersion, mode=mode, ComicID=ComicID, manualsearch=manualsearch, filesafe=ComicName_Filesafe)
|
||||
if foundcom == "yes":
|
||||
# file check to see if issue exists and update 'have' count
|
||||
if IssueID is not None:
|
||||
|
@ -3120,9 +3126,13 @@ class WebInterface(object):
|
|||
"http_user" : mylar.HTTP_USERNAME,
|
||||
"http_port" : mylar.HTTP_PORT,
|
||||
"http_pass" : mylar.HTTP_PASSWORD,
|
||||
"enable_https" : helpers.checked(mylar.ENABLE_HTTPS),
|
||||
"https_cert" : mylar.HTTPS_CERT,
|
||||
"https_key" : mylar.HTTPS_KEY,
|
||||
"api_enabled" : helpers.checked(mylar.API_ENABLED),
|
||||
"api_key" : mylar.API_KEY,
|
||||
"launch_browser" : helpers.checked(mylar.LAUNCH_BROWSER),
|
||||
"auto_update" : helpers.checked(mylar.AUTO_UPDATE),
|
||||
"logverbose" : helpers.checked(mylar.LOGVERBOSE),
|
||||
"max_logsize" : mylar.MAX_LOGSIZE,
|
||||
"annuals_on" : helpers.checked(mylar.ANNUALS_ON),
|
||||
|
@ -3438,7 +3448,7 @@ class WebInterface(object):
|
|||
readOptions.exposed = True
|
||||
|
||||
|
||||
def configUpdate(self, comicvine_api=None, http_host='0.0.0.0', http_username=None, http_port=8090, http_password=None, api_enabled=0, api_key=None, launch_browser=0, logverbose=0, annuals_on=0, max_logsize=None, download_scan_interval=None, nzb_search_interval=None, nzb_startup_search=0, libraryscan_interval=None,
|
||||
def configUpdate(self, comicvine_api=None, http_host='0.0.0.0', http_username=None, http_port=8090, http_password=None, enable_https=0, https_cert=None, https_key=None, api_enabled=0, api_key=None, launch_browser=0, auto_update=0, logverbose=0, annuals_on=0, max_logsize=None, download_scan_interval=None, nzb_search_interval=None, nzb_startup_search=0, libraryscan_interval=None,
|
||||
nzb_downloader=0, sab_host=None, sab_username=None, sab_apikey=None, sab_password=None, sab_category=None, sab_priority=None, sab_directory=None, log_dir=None, log_level=0, blackhole_dir=None,
|
||||
nzbget_host=None, nzbget_port=None, nzbget_username=None, nzbget_password=None, nzbget_category=None, nzbget_priority=None, nzbget_directory=None,
|
||||
usenet_retention=None, nzbsu=0, nzbsu_uid=None, nzbsu_apikey=None, dognzb=0, dognzb_uid=None, dognzb_apikey=None, newznab=0, newznab_host=None, newznab_name=None, newznab_apikey=None, newznab_uid=None, newznab_enabled=0,
|
||||
|
@ -3454,9 +3464,13 @@ class WebInterface(object):
|
|||
mylar.HTTP_PORT = http_port
|
||||
mylar.HTTP_USERNAME = http_username
|
||||
mylar.HTTP_PASSWORD = http_password
|
||||
mylar.ENABLE_HTTPS = enable_https
|
||||
mylar.HTTPS_CERT = https_cert
|
||||
mylar.HTTPS_KEY = https_key
|
||||
mylar.API_ENABLED = api_enabled
|
||||
mylar.API_KEY = api_key
|
||||
mylar.LAUNCH_BROWSER = launch_browser
|
||||
mylar.AUTO_UPDATE = auto_update
|
||||
mylar.LOGVERBOSE = logverbose
|
||||
mylar.ANNUALS_ON = int(annuals_on)
|
||||
mylar.MAX_LOGSIZE = max_logsize
|
||||
|
|
|
@ -19,19 +19,60 @@ import sys
|
|||
import cherrypy
|
||||
|
||||
import mylar
|
||||
|
||||
from mylar import logger
|
||||
from mylar.webserve import WebInterface
|
||||
from mylar.helpers import create_https_certificates
|
||||
|
||||
def initialize(options={}):
|
||||
def initialize(options):
|
||||
|
||||
# HTTPS stuff stolen from sickbeard
|
||||
enable_https = options['enable_https']
|
||||
https_cert = options['https_cert']
|
||||
https_key = options['https_key']
|
||||
|
||||
cherrypy.config.update({
|
||||
'log.screen': False,
|
||||
'server.thread_pool': 10,
|
||||
'server.socket_port': options['http_port'],
|
||||
'server.socket_host': options['http_host'],
|
||||
'engine.autoreload_on': False,
|
||||
})
|
||||
if enable_https:
|
||||
# If either the HTTPS certificate or key do not exist, try to make
|
||||
# self-signed ones.
|
||||
if not (https_cert and os.path.exists(https_cert)) or not (https_key and os.path.exists(https_key)):
|
||||
if not create_https_certificates(https_cert, https_key):
|
||||
logger.warn("Unable to create certificate and key. Disabling " \
|
||||
"HTTPS")
|
||||
enable_https = False
|
||||
|
||||
if not (os.path.exists(https_cert) and os.path.exists(https_key)):
|
||||
logger.warn("Disabled HTTPS because of missing certificate and " \
|
||||
"key.")
|
||||
enable_https = False
|
||||
|
||||
options_dict = {
|
||||
'server.socket_port': options['http_port'],
|
||||
'server.socket_host': options['http_host'],
|
||||
'server.thread_pool': 10,
|
||||
'tools.encode.on': True,
|
||||
'tools.encode.encoding': 'utf-8',
|
||||
'tools.decode.on': True,
|
||||
'log.screen': False,
|
||||
'engine.autoreload.on': False,
|
||||
}
|
||||
|
||||
if enable_https:
|
||||
options_dict['server.ssl_certificate'] = https_cert
|
||||
options_dict['server.ssl_private_key'] = https_key
|
||||
protocol = "https"
|
||||
else:
|
||||
protocol = "http"
|
||||
|
||||
logger.info("Starting Mylar on %s://%s:%d/", protocol,
|
||||
options['http_host'], options['http_port'])
|
||||
cherrypy.config.update(options_dict)
|
||||
|
||||
# cherrypy.config.update({
|
||||
# 'log.screen': False,
|
||||
# 'server.thread_pool': 10,
|
||||
# 'server.socket_port': options['http_port'],
|
||||
# 'server.socket_host': options['http_host'],
|
||||
# 'engine.autoreload_on': False,
|
||||
# })
|
||||
|
||||
conf = {
|
||||
'/': {
|
||||
|
@ -55,7 +96,7 @@ def initialize(options={}):
|
|||
},
|
||||
'/favicon.ico':{
|
||||
'tools.staticfile.on': True,
|
||||
'tools.staticfile.filename': "images/favicon.ico"
|
||||
'tools.staticfile.filename': os.path.join(os.path.abspath(os.curdir), 'images' + os.sep + 'favicon.ico')
|
||||
},
|
||||
'/cache':{
|
||||
'tools.staticdir.on': True,
|
||||
|
@ -70,7 +111,7 @@ def initialize(options={}):
|
|||
'tools.auth_basic.checkpassword': cherrypy.lib.auth_basic.checkpassword_dict(
|
||||
{options['http_username']:options['http_password']})
|
||||
})
|
||||
|
||||
conf['/api'] = {'tools.auth_basic.on': False}
|
||||
|
||||
# Prevent time-outs
|
||||
cherrypy.engine.timeout_monitor.unsubscribe()
|
||||
|
|
Loading…
Reference in New Issue