mirror of
https://github.com/SickGear/SickGear.git
synced 2024-12-03 18:03:37 +00:00
Merge pull request #825 from JackDandy/feature/ChangeShutdown
Change consolidate shutdown with restart, improve systemd support, br…
This commit is contained in:
commit
6da0f7f7fe
9 changed files with 361 additions and 382 deletions
|
@ -191,6 +191,7 @@
|
|||
* Change improve performance and reduce start up time
|
||||
* Fix button "Checkout branch" when stuck on disabled
|
||||
* Add 'Download Log' to 'Logs & Errors' page
|
||||
* Change consolidate shutdown with restart, improve systemd support, bring order to on-init globals
|
||||
|
||||
[develop changelog]
|
||||
* Change send nzb data to NZBGet for Anizb instead of url
|
||||
|
|
269
SickBeard.py
269
SickBeard.py
|
@ -80,48 +80,69 @@ class SickGear(object):
|
|||
sickbeard.events = Events(self.shutdown)
|
||||
|
||||
# daemon constants
|
||||
self.runAsDaemon = False
|
||||
self.CREATEPID = False
|
||||
self.PIDFILE = ''
|
||||
self.run_as_daemon = False
|
||||
self.create_pid = False
|
||||
self.pid_file = ''
|
||||
|
||||
self.run_as_systemd = False
|
||||
self.console_logging = False
|
||||
|
||||
# webserver constants
|
||||
self.webserver = None
|
||||
self.forceUpdate = False
|
||||
self.forcedPort = None
|
||||
self.noLaunch = False
|
||||
self.force_update = False
|
||||
self.forced_port = None
|
||||
self.no_launch = False
|
||||
|
||||
self.web_options = None
|
||||
self.webhost = None
|
||||
self.start_port = None
|
||||
self.log_dir = None
|
||||
|
||||
@staticmethod
|
||||
def help_message():
|
||||
"""
|
||||
print help message for commandline options
|
||||
"""
|
||||
help_msg = '\n'
|
||||
help_msg += 'Usage: %s <option> <another option>\n' % sickbeard.MY_FULLNAME
|
||||
help_msg += '\n'
|
||||
help_msg += 'Options:\n'
|
||||
help_msg += '\n'
|
||||
help_msg += ' -h --help Prints this message\n'
|
||||
help_msg += ' -f --forceupdate Force update all shows in the DB (from tvdb) on startup\n'
|
||||
help_msg += ' -q --quiet Disables logging to console\n'
|
||||
help_msg += ' --nolaunch Suppress launching web browser on startup\n'
|
||||
help_msg = ['']
|
||||
help_msg += ['Usage: %s <option> <another option>\n' % sickbeard.MY_FULLNAME]
|
||||
help_msg += ['Options:\n']
|
||||
|
||||
if sys.platform == 'win32':
|
||||
help_msg += ' -d --daemon Running as real daemon is not supported on Windows\n'
|
||||
help_msg += ' On Windows, --daemon is substituted with: --quiet --nolaunch\n'
|
||||
help_tmpl = ' %-10s%-17s%s'
|
||||
for ln in [
|
||||
('-h', '--help', 'Prints this message'),
|
||||
('-f', '--forceupdate', 'Force update all shows in the DB (from tvdb) on startup'),
|
||||
('-q', '--quiet', 'Disables logging to console'),
|
||||
('', '--nolaunch', 'Suppress launching web browser on startup')
|
||||
]:
|
||||
help_msg += [help_tmpl % ln]
|
||||
|
||||
if 'win32' == sys.platform:
|
||||
for ln in [
|
||||
('-d', '--daemon', 'Running as daemon is not supported on Windows'),
|
||||
('', '', 'On Windows, --daemon is substituted with: --quiet --nolaunch')
|
||||
]:
|
||||
help_msg += [help_tmpl % ln]
|
||||
else:
|
||||
help_msg += ' -d --daemon Run as double forked daemon (includes options --quiet --nolaunch)\n'
|
||||
help_msg += ' --pidfile=<path> Combined with --daemon creates a pidfile (full path including filename)\n'
|
||||
for ln in [
|
||||
('-d', '--daemon', 'Run as double forked daemon (includes options --quiet --nolaunch)'),
|
||||
('-s', '--systemd', 'Run as systemd service (includes options --quiet --nolaunch)'),
|
||||
('', '--pidfile=<path>', 'Combined with --daemon creates a pidfile (full path including filename)')
|
||||
]:
|
||||
help_msg += [help_tmpl % ln]
|
||||
|
||||
help_msg += ' -p <port> --port=<port> Override default/configured port to listen on\n'
|
||||
help_msg += ' --datadir=<path> Override folder (full path) as location for\n'
|
||||
help_msg += ' storing database, configfile, cache, logfiles \n'
|
||||
help_msg += ' Default: %s\n' % sickbeard.PROG_DIR
|
||||
help_msg += ' --config=<path> Override config filename (full path including filename)\n'
|
||||
help_msg += ' to load configuration from \n'
|
||||
help_msg += ' Default: config.ini in %s or --datadir location\n' % sickbeard.PROG_DIR
|
||||
help_msg += ' --noresize Prevent resizing of the banner/posters even if PIL is installed\n'
|
||||
for ln in [
|
||||
('-p <port>', '--port=<port>', 'Override default/configured port to listen on'),
|
||||
('', '--datadir=<path>', 'Override folder (full path) as location for'),
|
||||
('', '', 'storing database, configfile, cache, logfiles'),
|
||||
('', '', 'Default: %s' % sickbeard.PROG_DIR),
|
||||
('', '--config=<path>', 'Override config filename (full path including filename)'),
|
||||
('', '', 'to load configuration from'),
|
||||
('', '', 'Default: config.ini in %s or --datadir location' % sickbeard.PROG_DIR),
|
||||
('', '--noresize', 'Prevent resizing of the banner/posters even if PIL is installed')
|
||||
]:
|
||||
help_msg += [help_tmpl % ln]
|
||||
|
||||
return help_msg
|
||||
return '\n'.join(help_msg)
|
||||
|
||||
def start(self):
|
||||
# do some preliminary stuff
|
||||
|
@ -150,23 +171,23 @@ class SickGear(object):
|
|||
|
||||
try:
|
||||
# pylint: disable=E1101
|
||||
# On non-unicode builds this will raise an AttributeError, if encoding type is not valid it throws a LookupError
|
||||
# On non-unicode builds this raises an AttributeError, if encoding type is not valid it throws a LookupError
|
||||
sys.setdefaultencoding(sickbeard.SYS_ENCODING)
|
||||
except:
|
||||
except (StandardError, Exception):
|
||||
print('Sorry, you MUST add the SickGear folder to the PYTHONPATH environment variable')
|
||||
print('or find another way to force Python to use %s for string encoding.' % sickbeard.SYS_ENCODING)
|
||||
sys.exit(1)
|
||||
|
||||
# Need console logging for SickBeard.py and SickBeard-console.exe
|
||||
self.consoleLogging = (not hasattr(sys, 'frozen')) or (sickbeard.MY_NAME.lower().find('-console') > 0)
|
||||
self.console_logging = (not hasattr(sys, 'frozen')) or (sickbeard.MY_NAME.lower().find('-console') > 0)
|
||||
|
||||
# Rename the main thread
|
||||
threading.currentThread().name = 'MAIN'
|
||||
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'hfqdp::',
|
||||
['help', 'forceupdate', 'quiet', 'nolaunch', 'daemon', 'pidfile=', 'port=',
|
||||
'datadir=', 'config=', 'noresize']) # @UnusedVariable
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'hfqdsp::',
|
||||
['help', 'forceupdate', 'quiet', 'nolaunch', 'daemon', 'systemd', 'pidfile=',
|
||||
'port=', 'datadir=', 'config=', 'noresize']) # @UnusedVariable
|
||||
except getopt.GetoptError:
|
||||
sys.exit(self.help_message())
|
||||
|
||||
|
@ -177,43 +198,50 @@ class SickGear(object):
|
|||
|
||||
# For now we'll just silence the logging
|
||||
if o in ('-q', '--quiet'):
|
||||
self.consoleLogging = False
|
||||
self.console_logging = False
|
||||
|
||||
# Should we update (from indexer) all shows in the DB right away?
|
||||
if o in ('-f', '--forceupdate'):
|
||||
self.forceUpdate = True
|
||||
self.force_update = True
|
||||
|
||||
# Suppress launching web browser
|
||||
# Needed for OSes without default browser assigned
|
||||
# Prevent duplicate browser window when restarting in the app
|
||||
if o in ('--nolaunch',):
|
||||
self.noLaunch = True
|
||||
self.no_launch = True
|
||||
|
||||
# Override default/configured port
|
||||
if o in ('-p', '--port'):
|
||||
try:
|
||||
self.forcedPort = int(a)
|
||||
self.forced_port = int(a)
|
||||
except ValueError:
|
||||
sys.exit('Port: %s is not a number. Exiting.' % a)
|
||||
|
||||
# Run as a double forked daemon
|
||||
if o in ('-d', '--daemon'):
|
||||
self.runAsDaemon = True
|
||||
self.run_as_daemon = True
|
||||
# When running as daemon disable consoleLogging and don't start browser
|
||||
self.consoleLogging = False
|
||||
self.noLaunch = True
|
||||
self.console_logging = False
|
||||
self.no_launch = True
|
||||
|
||||
if sys.platform == 'win32':
|
||||
self.runAsDaemon = False
|
||||
if 'win32' == sys.platform:
|
||||
self.run_as_daemon = False
|
||||
|
||||
# Run as a systemd service
|
||||
if o in ('-s', '--systemd') and 'win32' != sys.platform:
|
||||
self.run_as_systemd = True
|
||||
self.run_as_daemon = False
|
||||
self.console_logging = False
|
||||
self.no_launch = True
|
||||
|
||||
# Write a pidfile if requested
|
||||
if o in ('--pidfile',):
|
||||
self.CREATEPID = True
|
||||
self.PIDFILE = str(a)
|
||||
self.create_pid = True
|
||||
self.pid_file = str(a)
|
||||
|
||||
# If the pidfile already exists, sickbeard may still be running, so exit
|
||||
if os.path.exists(self.PIDFILE):
|
||||
sys.exit('PID file: %s already exists. Exiting.' % self.PIDFILE)
|
||||
if os.path.exists(self.pid_file):
|
||||
sys.exit('PID file: %s already exists. Exiting.' % self.pid_file)
|
||||
|
||||
# Specify folder to load the config file from
|
||||
if o in ('--config',):
|
||||
|
@ -228,19 +256,19 @@ class SickGear(object):
|
|||
sickbeard.NO_RESIZE = True
|
||||
|
||||
# The pidfile is only useful in daemon mode, make sure we can write the file properly
|
||||
if self.CREATEPID:
|
||||
if self.runAsDaemon:
|
||||
pid_dir = os.path.dirname(self.PIDFILE)
|
||||
if self.create_pid:
|
||||
if self.run_as_daemon:
|
||||
pid_dir = os.path.dirname(self.pid_file)
|
||||
if not os.access(pid_dir, os.F_OK):
|
||||
sys.exit(u"PID dir: %s doesn't exist. Exiting." % pid_dir)
|
||||
if not os.access(pid_dir, os.W_OK):
|
||||
sys.exit(u'PID dir: %s must be writable (write permissions). Exiting.' % pid_dir)
|
||||
|
||||
else:
|
||||
if self.consoleLogging:
|
||||
if self.console_logging:
|
||||
print(u'Not running in daemon mode. PID file creation disabled')
|
||||
|
||||
self.CREATEPID = False
|
||||
self.create_pid = False
|
||||
|
||||
# If they don't specify a config file then put it in the data dir
|
||||
if not sickbeard.CONFIG_FILE:
|
||||
|
@ -266,7 +294,7 @@ class SickGear(object):
|
|||
% os.path.dirname(sickbeard.CONFIG_FILE))
|
||||
os.chdir(sickbeard.DATA_DIR)
|
||||
|
||||
if self.consoleLogging:
|
||||
if self.console_logging:
|
||||
print(u'Starting up SickGear from %s' % sickbeard.CONFIG_FILE)
|
||||
|
||||
# Load the config and publish it to the sickbeard package
|
||||
|
@ -307,19 +335,19 @@ class SickGear(object):
|
|||
print(u'Rollback of [%s] successful.' % d)
|
||||
|
||||
# Initialize the config and our threads
|
||||
sickbeard.initialize(consoleLogging=self.consoleLogging)
|
||||
sickbeard.initialize(console_logging=self.console_logging)
|
||||
|
||||
if self.runAsDaemon:
|
||||
if self.run_as_daemon:
|
||||
self.daemonize()
|
||||
|
||||
# Get PID
|
||||
sickbeard.PID = os.getpid()
|
||||
|
||||
if self.forcedPort:
|
||||
logger.log(u'Forcing web server to port %s' % self.forcedPort)
|
||||
self.startPort = self.forcedPort
|
||||
if self.forced_port:
|
||||
logger.log(u'Forcing web server to port %s' % self.forced_port)
|
||||
self.start_port = self.forced_port
|
||||
else:
|
||||
self.startPort = sickbeard.WEB_PORT
|
||||
self.start_port = sickbeard.WEB_PORT
|
||||
|
||||
if sickbeard.WEB_LOG:
|
||||
self.log_dir = sickbeard.LOG_DIR
|
||||
|
@ -338,7 +366,7 @@ class SickGear(object):
|
|||
|
||||
# web server options
|
||||
self.web_options = {
|
||||
'port': int(self.startPort),
|
||||
'port': int(self.start_port),
|
||||
'host': self.webhost,
|
||||
'data_root': os.path.join(sickbeard.PROG_DIR, 'gui', sickbeard.GUI_NAME),
|
||||
'web_root': sickbeard.WEB_ROOT,
|
||||
|
@ -358,24 +386,26 @@ class SickGear(object):
|
|||
|
||||
self.webserver = WebServer(self.web_options)
|
||||
self.webserver.start()
|
||||
except Exception:
|
||||
logger.log(u'Unable to start web server, is something else running on port %d?' % self.startPort,
|
||||
except (StandardError, Exception):
|
||||
logger.log(u'Unable to start web server, is something else running on port %d?' % self.start_port,
|
||||
logger.ERROR)
|
||||
if sickbeard.LAUNCH_BROWSER and not self.runAsDaemon:
|
||||
if self.run_as_systemd:
|
||||
self.exit(0)
|
||||
if sickbeard.LAUNCH_BROWSER and not self.no_launch:
|
||||
logger.log(u'Launching browser and exiting', logger.ERROR)
|
||||
sickbeard.launch_browser(self.startPort)
|
||||
os._exit(1)
|
||||
sickbeard.launch_browser(self.start_port)
|
||||
self.exit(1)
|
||||
|
||||
# Check if we need to perform a restore first
|
||||
restoreDir = os.path.join(sickbeard.DATA_DIR, 'restore')
|
||||
if os.path.exists(restoreDir):
|
||||
if self.restore(restoreDir, sickbeard.DATA_DIR):
|
||||
restore_dir = os.path.join(sickbeard.DATA_DIR, 'restore')
|
||||
if os.path.exists(restore_dir):
|
||||
if self.restore(restore_dir, sickbeard.DATA_DIR):
|
||||
logger.log(u'Restore successful...')
|
||||
else:
|
||||
logger.log_error_and_exit(u'Restore FAILED!')
|
||||
|
||||
# Build from the DB to start with
|
||||
self.loadShowsFromDB()
|
||||
self.load_shows_from_db()
|
||||
|
||||
# Fire up all our threads
|
||||
sickbeard.start()
|
||||
|
@ -395,12 +425,12 @@ class SickGear(object):
|
|||
failed_history.trimHistory()
|
||||
|
||||
# Start an update if we're supposed to
|
||||
if self.forceUpdate or sickbeard.UPDATE_SHOWS_ON_START:
|
||||
if self.force_update or sickbeard.UPDATE_SHOWS_ON_START:
|
||||
sickbeard.showUpdateScheduler.action.run(force=True) # @UndefinedVariable
|
||||
|
||||
# Launch browser
|
||||
if sickbeard.LAUNCH_BROWSER and not (self.noLaunch or self.runAsDaemon):
|
||||
sickbeard.launch_browser(self.startPort)
|
||||
if sickbeard.LAUNCH_BROWSER and not self.no_launch:
|
||||
sickbeard.launch_browser(self.start_port)
|
||||
|
||||
# main loop
|
||||
while True:
|
||||
|
@ -415,9 +445,9 @@ class SickGear(object):
|
|||
try:
|
||||
pid = os.fork() # @UndefinedVariable - only available in UNIX
|
||||
if pid != 0:
|
||||
os._exit(0)
|
||||
except OSError as e:
|
||||
sys.stderr.write('fork #1 failed: %d (%s)\n' % (e.errno, e.strerror))
|
||||
self.exit(0)
|
||||
except OSError as er:
|
||||
sys.stderr.write('fork #1 failed: %d (%s)\n' % (er.errno, er.strerror))
|
||||
sys.exit(1)
|
||||
|
||||
os.setsid() # @UndefinedVariable - only available in UNIX
|
||||
|
@ -430,20 +460,20 @@ class SickGear(object):
|
|||
try:
|
||||
pid = os.fork() # @UndefinedVariable - only available in UNIX
|
||||
if pid != 0:
|
||||
os._exit(0)
|
||||
except OSError as e:
|
||||
sys.stderr.write('fork #2 failed: %d (%s)\n' % (e.errno, e.strerror))
|
||||
self.exit(0)
|
||||
except OSError as er:
|
||||
sys.stderr.write('fork #2 failed: %d (%s)\n' % (er.errno, er.strerror))
|
||||
sys.exit(1)
|
||||
|
||||
# Write pid
|
||||
if self.CREATEPID:
|
||||
if self.create_pid:
|
||||
pid = str(os.getpid())
|
||||
logger.log(u'Writing PID: %s to %s' % (pid, self.PIDFILE))
|
||||
logger.log(u'Writing PID: %s to %s' % (pid, self.pid_file))
|
||||
try:
|
||||
open(self.PIDFILE, 'w').write('%s\n' % pid)
|
||||
except IOError as e:
|
||||
logger.log_error_and_exit(
|
||||
u'Unable to write PID file: %s Error: %s [%s]' % (self.PIDFILE, e.strerror, e.errno))
|
||||
open(self.pid_file, 'w').write('%s\n' % pid)
|
||||
except IOError as er:
|
||||
logger.log_error_and_exit('Unable to write PID file: %s Error: %s [%s]' % (
|
||||
self.pid_file, er.strerror, er.errno))
|
||||
|
||||
# Redirect all output
|
||||
sys.stdout.flush()
|
||||
|
@ -458,10 +488,10 @@ class SickGear(object):
|
|||
os.dup2(stderr.fileno(), sys.stderr.fileno())
|
||||
|
||||
@staticmethod
|
||||
def remove_pid_file(PIDFILE):
|
||||
def remove_pid_file(pidfile):
|
||||
try:
|
||||
if os.path.exists(PIDFILE):
|
||||
os.remove(PIDFILE)
|
||||
if os.path.exists(pidfile):
|
||||
os.remove(pidfile)
|
||||
|
||||
except (IOError, OSError):
|
||||
return False
|
||||
|
@ -469,43 +499,42 @@ class SickGear(object):
|
|||
return True
|
||||
|
||||
@staticmethod
|
||||
def loadShowsFromDB():
|
||||
def load_shows_from_db():
|
||||
"""
|
||||
Populates the showList with shows from the database
|
||||
"""
|
||||
|
||||
logger.log(u'Loading initial show list')
|
||||
|
||||
myDB = db.DBConnection()
|
||||
sqlResults = myDB.select('SELECT * FROM tv_shows')
|
||||
my_db = db.DBConnection()
|
||||
sql_results = my_db.select('SELECT * FROM tv_shows')
|
||||
|
||||
sickbeard.showList = []
|
||||
for sqlShow in sqlResults:
|
||||
for sqlShow in sql_results:
|
||||
try:
|
||||
curShow = TVShow(int(sqlShow['indexer']), int(sqlShow['indexer_id']))
|
||||
curShow.nextEpisode()
|
||||
sickbeard.showList.append(curShow)
|
||||
except Exception as e:
|
||||
logger.log(
|
||||
u'There was an error creating the show in %s: %s' % (sqlShow['location'], str(e).decode('utf-8',
|
||||
'replace')),
|
||||
logger.ERROR)
|
||||
cur_show = TVShow(int(sqlShow['indexer']), int(sqlShow['indexer_id']))
|
||||
cur_show.nextEpisode()
|
||||
sickbeard.showList.append(cur_show)
|
||||
except Exception as er:
|
||||
logger.log('There was an error creating the show in %s: %s' % (
|
||||
sqlShow['location'], str(er).decode('utf-8', 'replace')), logger.ERROR)
|
||||
|
||||
def restore(self, srcDir, dstDir):
|
||||
@staticmethod
|
||||
def restore(src_dir, dst_dir):
|
||||
try:
|
||||
for file in os.listdir(srcDir):
|
||||
srcFile = os.path.join(srcDir, file)
|
||||
dstFile = os.path.join(dstDir, file)
|
||||
bakFile = os.path.join(dstDir, file + '.bak')
|
||||
shutil.move(dstFile, bakFile)
|
||||
shutil.move(srcFile, dstFile)
|
||||
for filename in os.listdir(src_dir):
|
||||
src_file = os.path.join(src_dir, filename)
|
||||
dst_file = os.path.join(dst_dir, filename)
|
||||
bak_file = os.path.join(dst_dir, '%s.bak' % filename)
|
||||
shutil.move(dst_file, bak_file)
|
||||
shutil.move(src_file, dst_file)
|
||||
|
||||
os.rmdir(srcDir)
|
||||
os.rmdir(src_dir)
|
||||
return True
|
||||
except:
|
||||
except (StandardError, Exception):
|
||||
return False
|
||||
|
||||
def shutdown(self, type):
|
||||
def shutdown(self, ev_type):
|
||||
if sickbeard.started:
|
||||
# stop all tasks
|
||||
sickbeard.halt()
|
||||
|
@ -519,14 +548,15 @@ class SickGear(object):
|
|||
self.webserver.shutDown()
|
||||
try:
|
||||
self.webserver.join(10)
|
||||
except:
|
||||
except (StandardError, Exception):
|
||||
pass
|
||||
|
||||
# if run as daemon delete the pidfile
|
||||
if self.runAsDaemon and self.CREATEPID:
|
||||
self.remove_pid_file(self.PIDFILE)
|
||||
if self.run_as_daemon and self.create_pid:
|
||||
self.remove_pid_file(self.pid_file)
|
||||
|
||||
if sickbeard.events.SystemEvent.RESTART == ev_type:
|
||||
|
||||
if type == sickbeard.events.SystemEvent.RESTART:
|
||||
install_type = sickbeard.versionCheckScheduler.action.install_type
|
||||
|
||||
popen_list = []
|
||||
|
@ -536,6 +566,12 @@ class SickGear(object):
|
|||
|
||||
if popen_list:
|
||||
popen_list += sickbeard.MY_ARGS
|
||||
|
||||
if self.run_as_systemd:
|
||||
logger.log(u'Restarting SickGear with exit(1) handler and %s' % popen_list)
|
||||
logger.close()
|
||||
self.exit(1)
|
||||
|
||||
if '--nolaunch' not in popen_list:
|
||||
popen_list += ['--nolaunch']
|
||||
logger.log(u'Restarting SickGear with %s' % popen_list)
|
||||
|
@ -543,8 +579,11 @@ class SickGear(object):
|
|||
subprocess.Popen(popen_list, cwd=os.getcwd())
|
||||
|
||||
# system exit
|
||||
os._exit(0)
|
||||
self.exit(0)
|
||||
|
||||
@staticmethod
|
||||
def exit(code):
|
||||
os._exit(code)
|
||||
|
||||
if __name__ == '__main__':
|
||||
if sys.hexversion >= 0x020600F0:
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
<span class="component-desc">
|
||||
<select name="tag" id="tag" class="form-control form-control-inline input-sm">
|
||||
#for $tag in $sickbeard.SHOW_TAGS:
|
||||
<option value="$tag" #if $tag == $sickbeard.DEFAULT_SHOW_TAG then 'selected="selected"' else ''#>$tag</option>
|
||||
<option value="$tag" #if $tag == $getattr(sickbeard, 'SHOW_TAG_DEFAULT', $getattr(sickbeard, 'DEFAULT_SHOW_TAG', None)) then 'selected="selected"' else ''#>$tag</option>
|
||||
#end for
|
||||
</select>
|
||||
<span>and display on the show list page under this section</span>
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
##
|
||||
#set sgHost = $sbHost
|
||||
#set sgPort = $sbHttpPort
|
||||
#set sgRoot = $sbRoot
|
||||
#set sgUseHttps = $sbHttpsEnabled
|
||||
#set themeSpinner = '-dark' if 'dark' == $sbThemeName else ''
|
||||
##
|
||||
<!DOCTYPE html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
@ -26,26 +33,12 @@
|
|||
<meta name="msapplication-config" content="$sbRoot/css/browserconfig.xml">
|
||||
|
||||
<script type="text/javascript" src="$sbRoot/js/lib/jquery-1.8.3.min.js?v=$sbPID"></script>
|
||||
|
||||
#try:
|
||||
#set sgHost = $sbHost
|
||||
#set sgPort = $sbHttpPort
|
||||
#set sgUseHttps = $sbHttpsEnabled
|
||||
#set themeSpinner = $sbThemeName
|
||||
#except NameMapper.NotFound:
|
||||
#set sgHost = 'localhost'
|
||||
#set sgPort = $sickbeard.WEB_PORT
|
||||
#set sgUseHttps = False
|
||||
#set themeSpinner = $sickbeard.THEME_NAME
|
||||
#end try
|
||||
#set themeSpinner = '-dark' if 'dark' == themeSpinner else ''
|
||||
##
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
<!--
|
||||
\$.SickGear = {
|
||||
Root: '$sbRoot',
|
||||
Host: '$sgHost',
|
||||
Port: '$sgPort',
|
||||
Root: '$sgRoot',
|
||||
UseHttps: #echo ('!1', '!0')[False != $sgUseHttps and 0 != $sgUseHttps]#
|
||||
};
|
||||
//-->
|
||||
|
@ -58,12 +51,12 @@ body{padding-top:0 !important}.sglogo{display:block;width:138px;height:74px;marg
|
|||
</style>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="$sbRoot/css/style.css?v=$sbPID">
|
||||
<link rel="stylesheet" type="text/css" href="$sbRoot/css/#echo ('dark', 'light')['' == themeSpinner]#.css?v=$sbPID">
|
||||
<link rel="stylesheet" type="text/css" href="$sbRoot/css/#echo ('dark', 'light')['' == $themeSpinner]#.css?v=$sbPID">
|
||||
|
||||
</head><body><span class="sglogo"></span>
|
||||
<div class="bfr"><img src="$sbRoot/images/loading16${themeSpinner}.gif" /><img src="$sbRoot/images/yes16.png" /><img src="$sbRoot/images/no16.png" /></div>
|
||||
|
||||
<h2 class="sub-title">Performing Restart</h2>
|
||||
<h2 class="sub-title">Performing #echo ('Restart', 'Shutdown')[$shutdown]#</h2>
|
||||
|
||||
<div id="shut_down_message">
|
||||
<span class="desc"><span class="grey-text">Waiting for SickGear to</span> shut down: </span>
|
||||
|
@ -71,17 +64,23 @@ body{padding-top:0 !important}.sglogo{display:block;width:138px;height:74px;marg
|
|||
</div>
|
||||
|
||||
<div class="hide" id="restart_message">
|
||||
#if not $shutdown
|
||||
<span class="desc"><span class="grey-text">Waiting for SickGear to</span> start up: </span>
|
||||
<span class="images"><i class="spinner"></i><span class="hide-yes"><i class="yes"></i></span><span class="hide-no"><i class="no"></i></span></span>
|
||||
#end if
|
||||
</div>
|
||||
|
||||
<div class="hide" id="refresh_message">
|
||||
#if not $shutdown
|
||||
<span class="desc"><span class="grey-text">Waiting for SickGear </span> home page: </span>
|
||||
<span class="images"><i class="spinner"></i></span>
|
||||
#end if
|
||||
</div>
|
||||
|
||||
<div class="hide" id="restart_fail_message">
|
||||
#if not $shutdown
|
||||
<span class="red-text">Error:</span> The restart timed out, perhaps something prevented SickGear from starting ?
|
||||
#end if
|
||||
</div>
|
||||
|
||||
</body></html>
|
||||
|
|
|
@ -11,8 +11,7 @@
|
|||
# Putting a minus (-) in front of file means no error warning if the file doesn't exist
|
||||
#
|
||||
# - Adjust ExecStart= to point to your python and SickGear executables.
|
||||
# The FIRST token of the command line must be an ABSOLUTE FILE NAME,
|
||||
# then followed by arguments for the process.
|
||||
# The FIRST token of the command line must be an ABSOLUTE FILE NAME, followed by arguments for the process.
|
||||
# If no --datadir is given, data is stored in same dir as SickBeard.py
|
||||
# Arguments can also be set in EnvironmentFile (except python)
|
||||
#
|
||||
|
@ -21,16 +20,6 @@
|
|||
# graphical.target equates to runlevel 5 (multi-user X11 graphical mode)
|
||||
#
|
||||
|
||||
### Example Using SickGear as daemon with pid file
|
||||
# Type=forking
|
||||
# PIDFile=/var/run/sickgear/sickgear.pid
|
||||
# ExecStart=/usr/bin/python2 /opt/sickgear/app/SickBeard.py -q --daemon --nolaunch --pidfile=/var/run/sickgear/sickgear.pid --datadir=/opt/sickgear/data
|
||||
|
||||
## Example Using SickGear as daemon without pid file
|
||||
# Type=forking
|
||||
# GuessMainPID=no
|
||||
# ExecStart=/usr/bin/python2 /opt/sickgear/app/SickBeard.py -q --daemon --nolaunch --datadir=/opt/sickgear/data
|
||||
|
||||
### Example Using simple
|
||||
# Type=simple
|
||||
# ExecStart=/usr/bin/python2 /opt/sickgear/app/SickBeard.py -q --nolaunch
|
||||
|
@ -43,15 +32,16 @@
|
|||
### Configuration
|
||||
|
||||
[Unit]
|
||||
Description=SickGear Daemon
|
||||
Description=SickGear Service
|
||||
|
||||
[Service]
|
||||
User=sickgear
|
||||
Group=sickgear
|
||||
|
||||
Type=forking
|
||||
GuessMainPID=no
|
||||
ExecStart=/usr/bin/python2 /opt/sickgear/app/SickBeard.py -q --daemon --nolaunch --datadir=/opt/sickgear/data
|
||||
Environment=PYTHONUNBUFFERED=true
|
||||
ExecStart=/usr/bin/python2 /opt/sickgear/app/SickBeard.py --systemd --datadir=/opt/sickgear/data
|
||||
KillMode=process
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
|
|
|
@ -83,7 +83,7 @@ searchQueueScheduler = None
|
|||
properFinderScheduler = None
|
||||
autoPostProcesserScheduler = None
|
||||
subtitlesFinderScheduler = None
|
||||
traktCheckerScheduler = None
|
||||
# traktCheckerScheduler = None
|
||||
background_mapping_task = None
|
||||
|
||||
showList = None
|
||||
|
@ -146,11 +146,8 @@ TRASH_ROTATE_LOGS = False
|
|||
HOME_SEARCH_FOCUS = True
|
||||
SORT_ARTICLE = False
|
||||
DEBUG = False
|
||||
DISPLAY_BACKGROUND = False
|
||||
DISPLAY_BACKGROUND_TRANSPARENT = None
|
||||
DISPLAY_ALL_SEASONS = True
|
||||
SHOW_TAGS = []
|
||||
DEFAULT_SHOW_TAG = ''
|
||||
SHOW_TAG_DEFAULT = ''
|
||||
SHOWLIST_TAGVIEW = ''
|
||||
|
||||
METADATA_XBMC = None
|
||||
|
@ -203,13 +200,13 @@ TORRENT_DIR = None
|
|||
DOWNLOAD_PROPERS = False
|
||||
CHECK_PROPERS_INTERVAL = None
|
||||
ALLOW_HIGH_PRIORITY = False
|
||||
NEWZNAB_DATA = ''
|
||||
|
||||
AUTOPOSTPROCESSER_FREQUENCY = None
|
||||
RECENTSEARCH_FREQUENCY = None
|
||||
RECENTSEARCH_FREQUENCY = 0
|
||||
UPDATE_FREQUENCY = None
|
||||
RECENTSEARCH_STARTUP = False
|
||||
BACKLOG_FREQUENCY = None
|
||||
BACKLOG_STARTUP = False
|
||||
BACKLOG_NOFULL = False
|
||||
|
||||
DEFAULT_AUTOPOSTPROCESSER_FREQUENCY = 10
|
||||
|
@ -458,7 +455,8 @@ EXTRA_SCRIPTS = []
|
|||
|
||||
GIT_PATH = None
|
||||
|
||||
IGNORE_WORDS = 'core2hd, hevc, MrLss, reenc, x265, danish, deutsch, dutch, flemish, french, german, italian, nordic, norwegian, portuguese, spanish, swedish, turkish'
|
||||
IGNORE_WORDS = 'core2hd, hevc, MrLss, reenc, x265, danish, deutsch, dutch, flemish, french, ' + \
|
||||
'german, italian, nordic, norwegian, portuguese, spanish, swedish, turkish'
|
||||
REQUIRE_WORDS = ''
|
||||
|
||||
CALENDAR_UNPROTECTED = False
|
||||
|
@ -499,81 +497,119 @@ def get_backlog_cycle_time():
|
|||
return max([cycletime, 720])
|
||||
|
||||
|
||||
def initialize(consoleLogging=True):
|
||||
def initialize(console_logging=True):
|
||||
with INIT_LOCK:
|
||||
|
||||
global BRANCH, GIT_REMOTE, CUR_COMMIT_HASH, CUR_COMMIT_BRANCH, ACTUAL_LOG_DIR, LOG_DIR, FILE_LOGGING_PRESET, WEB_PORT, WEB_LOG, ENCRYPTION_VERSION, WEB_ROOT, WEB_USERNAME, WEB_PASSWORD, WEB_HOST, WEB_IPV6, USE_API, API_KEY, ENABLE_HTTPS, HTTPS_CERT, HTTPS_KEY, \
|
||||
HANDLE_REVERSE_PROXY, USE_NZBS, USE_TORRENTS, NZB_METHOD, NZB_DIR, DOWNLOAD_PROPERS, CHECK_PROPERS_INTERVAL, ALLOW_HIGH_PRIORITY, TORRENT_METHOD, \
|
||||
SAB_USERNAME, SAB_PASSWORD, SAB_APIKEY, SAB_CATEGORY, SAB_HOST, \
|
||||
NZBGET_USERNAME, NZBGET_PASSWORD, NZBGET_CATEGORY, NZBGET_PRIORITY, NZBGET_HOST, NZBGET_USE_HTTPS, backlogSearchScheduler, \
|
||||
TORRENT_USERNAME, TORRENT_PASSWORD, TORRENT_HOST, TORRENT_PATH, TORRENT_SEED_TIME, TORRENT_PAUSED, TORRENT_HIGH_BANDWIDTH, TORRENT_LABEL, TORRENT_VERIFY_CERT, \
|
||||
USE_EMBY, EMBY_UPDATE_LIBRARY, EMBY_HOST, EMBY_APIKEY, \
|
||||
USE_KODI, KODI_ALWAYS_ON, KODI_NOTIFY_ONSNATCH, KODI_NOTIFY_ONDOWNLOAD, KODI_NOTIFY_ONSUBTITLEDOWNLOAD,\
|
||||
KODI_UPDATE_FULL, KODI_UPDATE_ONLYFIRST, KODI_UPDATE_LIBRARY, KODI_HOST, KODI_USERNAME, KODI_PASSWORD, \
|
||||
USE_XBMC, XBMC_ALWAYS_ON, XBMC_NOTIFY_ONSNATCH, XBMC_NOTIFY_ONDOWNLOAD, XBMC_NOTIFY_ONSUBTITLEDOWNLOAD,\
|
||||
XBMC_UPDATE_FULL, XBMC_UPDATE_ONLYFIRST, XBMC_UPDATE_LIBRARY, XBMC_HOST, XBMC_USERNAME, XBMC_PASSWORD, \
|
||||
USE_PLEX, PLEX_NOTIFY_ONSNATCH, PLEX_NOTIFY_ONDOWNLOAD, PLEX_NOTIFY_ONSUBTITLEDOWNLOAD, \
|
||||
PLEX_UPDATE_LIBRARY, PLEX_SERVER_HOST, PLEX_HOST, PLEX_USERNAME, PLEX_PASSWORD, \
|
||||
USE_TRAKT, TRAKT_CONNECTED_ACCOUNT, TRAKT_ACCOUNTS, TRAKT_MRU, TRAKT_VERIFY, TRAKT_REMOVE_WATCHLIST, TRAKT_TIMEOUT, TRAKT_USE_WATCHLIST, TRAKT_METHOD_ADD, TRAKT_START_PAUSED, traktCheckerScheduler, TRAKT_SYNC, TRAKT_DEFAULT_INDEXER, TRAKT_REMOVE_SERIESLIST, TRAKT_UPDATE_COLLECTION, \
|
||||
BACKLOG_FREQUENCY, DEFAULT_BACKLOG_FREQUENCY, MIN_BACKLOG_FREQUENCY, MAX_BACKLOG_FREQUENCY, BACKLOG_STARTUP, BACKLOG_NOFULL, SKIP_REMOVED_FILES, \
|
||||
showUpdateScheduler, __INITIALIZED__, LAUNCH_BROWSER, TRASH_REMOVE_SHOW, TRASH_ROTATE_LOGS, HOME_SEARCH_FOCUS, SORT_ARTICLE, showList, loadingShowList, UPDATE_SHOWS_ON_START, SHOW_UPDATE_HOUR, \
|
||||
NEWZNAB_DATA, INDEXER_DEFAULT, INDEXER_TIMEOUT, USENET_RETENTION, TORRENT_DIR, \
|
||||
QUALITY_DEFAULT, FLATTEN_FOLDERS_DEFAULT, SUBTITLES_DEFAULT, STATUS_DEFAULT, WANTED_BEGIN_DEFAULT, WANTED_LATEST_DEFAULT, RECENTSEARCH_STARTUP, \
|
||||
GROWL_NOTIFY_ONSNATCH, GROWL_NOTIFY_ONDOWNLOAD, GROWL_NOTIFY_ONSUBTITLEDOWNLOAD, TWITTER_NOTIFY_ONSNATCH, TWITTER_NOTIFY_ONDOWNLOAD, TWITTER_NOTIFY_ONSUBTITLEDOWNLOAD, \
|
||||
USE_GROWL, GROWL_HOST, GROWL_PASSWORD, USE_PROWL, PROWL_NOTIFY_ONSNATCH, PROWL_NOTIFY_ONDOWNLOAD, PROWL_NOTIFY_ONSUBTITLEDOWNLOAD, PROWL_API, PROWL_PRIORITY, PROG_DIR, \
|
||||
USE_PYTIVO, PYTIVO_NOTIFY_ONSNATCH, PYTIVO_NOTIFY_ONDOWNLOAD, PYTIVO_NOTIFY_ONSUBTITLEDOWNLOAD, PYTIVO_UPDATE_LIBRARY, PYTIVO_HOST, PYTIVO_SHARE_NAME, PYTIVO_TIVO_NAME, \
|
||||
# Misc
|
||||
global __INITIALIZED__, showList, providerList, newznabProviderList, torrentRssProviderList, \
|
||||
WEB_HOST, WEB_ROOT, ACTUAL_CACHE_DIR, CACHE_DIR, ZONEINFO_DIR, ADD_SHOWS_WO_DIR, CREATE_MISSING_SHOW_DIRS, \
|
||||
RECENTSEARCH_STARTUP, NAMING_FORCE_FOLDERS, SOCKET_TIMEOUT, DEBUG, INDEXER_DEFAULT, REMOVE_FILENAME_CHARS, \
|
||||
CONFIG_FILE
|
||||
# Schedulers
|
||||
# global traktCheckerScheduler
|
||||
global recentSearchScheduler, backlogSearchScheduler, showUpdateScheduler, \
|
||||
versionCheckScheduler, showQueueScheduler, searchQueueScheduler, \
|
||||
properFinderScheduler, autoPostProcesserScheduler, subtitlesFinderScheduler, background_mapping_task
|
||||
# Add Show Defaults
|
||||
global STATUS_DEFAULT, QUALITY_DEFAULT, SHOW_TAG_DEFAULT, FLATTEN_FOLDERS_DEFAULT, SUBTITLES_DEFAULT, \
|
||||
WANTED_BEGIN_DEFAULT, WANTED_LATEST_DEFAULT, SCENE_DEFAULT, ANIME_DEFAULT
|
||||
# Post processing
|
||||
global KEEP_PROCESSED_DIR
|
||||
# Views
|
||||
global GUI_NAME, HOME_LAYOUT, POSTER_SORTBY, POSTER_SORTDIR, DISPLAY_SHOW_SPECIALS, \
|
||||
EPISODE_VIEW_LAYOUT, EPISODE_VIEW_SORT, EPISODE_VIEW_DISPLAY_PAUSED, \
|
||||
EPISODE_VIEW_MISSED_RANGE, HISTORY_LAYOUT
|
||||
# Gen Config/Misc
|
||||
global LAUNCH_BROWSER, UPDATE_SHOWS_ON_START, SHOW_UPDATE_HOUR, \
|
||||
TRASH_REMOVE_SHOW, TRASH_ROTATE_LOGS, ACTUAL_LOG_DIR, LOG_DIR, INDEXER_TIMEOUT, ROOT_DIRS, \
|
||||
VERSION_NOTIFY, AUTO_UPDATE, UPDATE_FREQUENCY, NOTIFY_ON_UPDATE
|
||||
# Gen Config/Interface
|
||||
global THEME_NAME, DEFAULT_HOME, SHOWLIST_TAGVIEW, SHOW_TAGS, \
|
||||
HOME_SEARCH_FOCUS, USE_IMDB_INFO, IMDB_ACCOUNTS, SORT_ARTICLE, FUZZY_DATING, TRIM_ZERO, \
|
||||
DATE_PRESET, TIME_PRESET, TIME_PRESET_W_SECONDS, TIMEZONE_DISPLAY, \
|
||||
WEB_USERNAME, WEB_PASSWORD, CALENDAR_UNPROTECTED, USE_API, API_KEY, WEB_PORT, WEB_LOG, \
|
||||
ENABLE_HTTPS, HTTPS_CERT, HTTPS_KEY, WEB_IPV6, HANDLE_REVERSE_PROXY
|
||||
# Gen Config/Advanced
|
||||
global BRANCH, CUR_COMMIT_BRANCH, GIT_REMOTE, CUR_COMMIT_HASH, GIT_PATH, CPU_PRESET, ANON_REDIRECT, \
|
||||
ENCRYPTION_VERSION, PROXY_SETTING, PROXY_INDEXERS, FILE_LOGGING_PRESET
|
||||
# Search Settings/Episode
|
||||
global DOWNLOAD_PROPERS, CHECK_PROPERS_INTERVAL, RECENTSEARCH_FREQUENCY, \
|
||||
BACKLOG_DAYS, BACKLOG_NOFULL, BACKLOG_FREQUENCY, USENET_RETENTION, IGNORE_WORDS, REQUIRE_WORDS, \
|
||||
ALLOW_HIGH_PRIORITY, SEARCH_UNAIRED, UNAIRED_RECENT_SEARCH_ONLY
|
||||
# Search Settings/NZB search
|
||||
global USE_NZBS, NZB_METHOD, NZB_DIR, SAB_HOST, SAB_USERNAME, SAB_PASSWORD, SAB_APIKEY, SAB_CATEGORY, \
|
||||
NZBGET_USE_HTTPS, NZBGET_HOST, NZBGET_USERNAME, NZBGET_PASSWORD, NZBGET_CATEGORY, NZBGET_PRIORITY
|
||||
# Search Settings/Torrent search
|
||||
global USE_TORRENTS, TORRENT_METHOD, TORRENT_DIR, TORRENT_HOST, TORRENT_USERNAME, TORRENT_PASSWORD, \
|
||||
TORRENT_LABEL, TORRENT_PATH, TORRENT_SEED_TIME, TORRENT_PAUSED, TORRENT_HIGH_BANDWIDTH, TORRENT_VERIFY_CERT
|
||||
# Search Providers
|
||||
global PROVIDER_ORDER, NEWZNAB_DATA, PROVIDER_HOMES
|
||||
# Subtitles
|
||||
global USE_SUBTITLES, SUBTITLES_LANGUAGES, SUBTITLES_DIR, SUBTITLES_FINDER_FREQUENCY, \
|
||||
SUBTITLES_HISTORY, SUBTITLES_SERVICES_ENABLED, SUBTITLES_SERVICES_LIST
|
||||
# Post Processing/Post-Processing
|
||||
global TV_DOWNLOAD_DIR, PROCESS_METHOD, PROCESS_AUTOMATICALLY, AUTOPOSTPROCESSER_FREQUENCY, \
|
||||
POSTPONE_IF_SYNC_FILES, EXTRA_SCRIPTS, \
|
||||
DEFAULT_AUTOPOSTPROCESSER_FREQUENCY, MIN_AUTOPOSTPROCESSER_FREQUENCY, \
|
||||
UNPACK, SKIP_REMOVED_FILES, MOVE_ASSOCIATED_FILES, NFO_RENAME, RENAME_EPISODES, AIRDATE_EPISODES, \
|
||||
USE_FAILED_DOWNLOADS, DELETE_FAILED
|
||||
# Post Processing/Episode Naming
|
||||
global NAMING_PATTERN, NAMING_MULTI_EP, NAMING_STRIP_YEAR, NAMING_CUSTOM_ABD, NAMING_ABD_PATTERN, \
|
||||
NAMING_CUSTOM_SPORTS, NAMING_SPORTS_PATTERN, \
|
||||
NAMING_CUSTOM_ANIME, NAMING_ANIME_PATTERN, NAMING_ANIME_MULTI_EP, NAMING_ANIME
|
||||
# Post Processing/Metadata
|
||||
global metadata_provider_dict, METADATA_KODI, METADATA_MEDE8ER, METADATA_XBMC, METADATA_MEDIABROWSER, \
|
||||
METADATA_PS3, METADATA_TIVO, METADATA_WDTV, METADATA_XBMC_12PLUS
|
||||
# Notification Settings/HT and NAS
|
||||
global USE_EMBY, EMBY_UPDATE_LIBRARY, EMBY_HOST, EMBY_APIKEY, \
|
||||
USE_KODI, KODI_ALWAYS_ON, KODI_UPDATE_LIBRARY, KODI_UPDATE_FULL, KODI_UPDATE_ONLYFIRST, \
|
||||
KODI_HOST, KODI_USERNAME, KODI_PASSWORD, KODI_NOTIFY_ONSNATCH, \
|
||||
KODI_NOTIFY_ONDOWNLOAD, KODI_NOTIFY_ONSUBTITLEDOWNLOAD, \
|
||||
USE_XBMC, XBMC_ALWAYS_ON, XBMC_NOTIFY_ONSNATCH, XBMC_NOTIFY_ONDOWNLOAD, XBMC_NOTIFY_ONSUBTITLEDOWNLOAD, \
|
||||
XBMC_UPDATE_LIBRARY, XBMC_UPDATE_FULL, XBMC_UPDATE_ONLYFIRST, XBMC_HOST, XBMC_USERNAME, XBMC_PASSWORD, \
|
||||
USE_PLEX, PLEX_USERNAME, PLEX_PASSWORD, PLEX_UPDATE_LIBRARY, PLEX_SERVER_HOST, \
|
||||
PLEX_NOTIFY_ONSNATCH, PLEX_NOTIFY_ONDOWNLOAD, PLEX_NOTIFY_ONSUBTITLEDOWNLOAD, PLEX_HOST, \
|
||||
USE_NMJ, NMJ_HOST, NMJ_DATABASE, NMJ_MOUNT, \
|
||||
USE_NMJv2, NMJv2_HOST, NMJv2_DATABASE, NMJv2_DBLOC, \
|
||||
USE_SYNOINDEX, \
|
||||
USE_SYNOLOGYNOTIFIER, SYNOLOGYNOTIFIER_NOTIFY_ONSNATCH, \
|
||||
SYNOLOGYNOTIFIER_NOTIFY_ONDOWNLOAD, SYNOLOGYNOTIFIER_NOTIFY_ONSUBTITLEDOWNLOAD, \
|
||||
USE_PYTIVO, PYTIVO_HOST, PYTIVO_SHARE_NAME, PYTIVO_TIVO_NAME, \
|
||||
PYTIVO_NOTIFY_ONSNATCH, PYTIVO_NOTIFY_ONDOWNLOAD, PYTIVO_NOTIFY_ONSUBTITLEDOWNLOAD, PYTIVO_UPDATE_LIBRARY
|
||||
# Notification Settings/Devices
|
||||
global USE_GROWL, GROWL_NOTIFY_ONSNATCH, GROWL_NOTIFY_ONDOWNLOAD, GROWL_NOTIFY_ONSUBTITLEDOWNLOAD, \
|
||||
GROWL_HOST, GROWL_PASSWORD, \
|
||||
USE_PROWL, PROWL_NOTIFY_ONSNATCH, PROWL_NOTIFY_ONDOWNLOAD, PROWL_NOTIFY_ONSUBTITLEDOWNLOAD, \
|
||||
PROWL_API, PROWL_PRIORITY, \
|
||||
USE_LIBNOTIFY, LIBNOTIFY_NOTIFY_ONSNATCH, LIBNOTIFY_NOTIFY_ONDOWNLOAD, \
|
||||
LIBNOTIFY_NOTIFY_ONSUBTITLEDOWNLOAD, \
|
||||
USE_PUSHOVER, PUSHOVER_NOTIFY_ONSNATCH, PUSHOVER_NOTIFY_ONDOWNLOAD, PUSHOVER_NOTIFY_ONSUBTITLEDOWNLOAD, \
|
||||
PUSHOVER_USERKEY, PUSHOVER_APIKEY, PUSHOVER_PRIORITY, PUSHOVER_DEVICE, PUSHOVER_SOUND, \
|
||||
USE_BOXCAR2, BOXCAR2_NOTIFY_ONSNATCH, BOXCAR2_NOTIFY_ONDOWNLOAD, BOXCAR2_NOTIFY_ONSUBTITLEDOWNLOAD, \
|
||||
BOXCAR2_ACCESSTOKEN, BOXCAR2_SOUND, \
|
||||
USE_NMA, NMA_NOTIFY_ONSNATCH, NMA_NOTIFY_ONDOWNLOAD, NMA_NOTIFY_ONSUBTITLEDOWNLOAD, NMA_API, NMA_PRIORITY, \
|
||||
USE_PUSHALOT, PUSHALOT_NOTIFY_ONSNATCH, PUSHALOT_NOTIFY_ONDOWNLOAD, PUSHALOT_NOTIFY_ONSUBTITLEDOWNLOAD, PUSHALOT_AUTHORIZATIONTOKEN, \
|
||||
USE_PUSHBULLET, PUSHBULLET_NOTIFY_ONSNATCH, PUSHBULLET_NOTIFY_ONDOWNLOAD, PUSHBULLET_NOTIFY_ONSUBTITLEDOWNLOAD, PUSHBULLET_ACCESS_TOKEN, PUSHBULLET_DEVICE_IDEN, \
|
||||
versionCheckScheduler, VERSION_NOTIFY, AUTO_UPDATE, NOTIFY_ON_UPDATE, PROCESS_AUTOMATICALLY, UNPACK, CPU_PRESET, \
|
||||
KEEP_PROCESSED_DIR, PROCESS_METHOD, TV_DOWNLOAD_DIR, MIN_RECENTSEARCH_FREQUENCY, DEFAULT_UPDATE_FREQUENCY, MIN_UPDATE_FREQUENCY, UPDATE_FREQUENCY, \
|
||||
showQueueScheduler, searchQueueScheduler, ROOT_DIRS, CACHE_DIR, ACTUAL_CACHE_DIR, ZONEINFO_DIR, TIMEZONE_DISPLAY, \
|
||||
NAMING_PATTERN, NAMING_MULTI_EP, NAMING_ANIME_MULTI_EP, NAMING_FORCE_FOLDERS, NAMING_ABD_PATTERN, NAMING_CUSTOM_ABD, NAMING_SPORTS_PATTERN, NAMING_CUSTOM_SPORTS, NAMING_ANIME_PATTERN, NAMING_CUSTOM_ANIME, NAMING_STRIP_YEAR, \
|
||||
RENAME_EPISODES, AIRDATE_EPISODES, properFinderScheduler, PROVIDER_ORDER, PROVIDER_HOMES, autoPostProcesserScheduler, \
|
||||
providerList, newznabProviderList, torrentRssProviderList, \
|
||||
EXTRA_SCRIPTS, USE_TWITTER, TWITTER_USERNAME, TWITTER_PASSWORD, TWITTER_PREFIX, RECENTSEARCH_FREQUENCY, \
|
||||
USE_BOXCAR2, BOXCAR2_ACCESSTOKEN, BOXCAR2_NOTIFY_ONDOWNLOAD, BOXCAR2_NOTIFY_ONSUBTITLEDOWNLOAD, BOXCAR2_NOTIFY_ONSNATCH, BOXCAR2_SOUND, \
|
||||
USE_PUSHOVER, PUSHOVER_USERKEY, PUSHOVER_APIKEY, PUSHOVER_NOTIFY_ONDOWNLOAD, PUSHOVER_NOTIFY_ONSUBTITLEDOWNLOAD, PUSHOVER_NOTIFY_ONSNATCH, PUSHOVER_PRIORITY, PUSHOVER_DEVICE, PUSHOVER_SOUND, \
|
||||
USE_LIBNOTIFY, LIBNOTIFY_NOTIFY_ONSNATCH, LIBNOTIFY_NOTIFY_ONDOWNLOAD, LIBNOTIFY_NOTIFY_ONSUBTITLEDOWNLOAD, USE_NMJ, NMJ_HOST, NMJ_DATABASE, NMJ_MOUNT, USE_NMJv2, NMJv2_HOST, NMJv2_DATABASE, NMJv2_DBLOC, USE_SYNOINDEX, \
|
||||
USE_SYNOLOGYNOTIFIER, SYNOLOGYNOTIFIER_NOTIFY_ONSNATCH, SYNOLOGYNOTIFIER_NOTIFY_ONDOWNLOAD, SYNOLOGYNOTIFIER_NOTIFY_ONSUBTITLEDOWNLOAD, \
|
||||
USE_EMAIL, EMAIL_OLD_SUBJECTS, EMAIL_HOST, EMAIL_PORT, EMAIL_TLS, EMAIL_USER, EMAIL_PASSWORD, EMAIL_FROM, EMAIL_NOTIFY_ONSNATCH, EMAIL_NOTIFY_ONDOWNLOAD, EMAIL_NOTIFY_ONSUBTITLEDOWNLOAD, EMAIL_LIST, \
|
||||
METADATA_XBMC, METADATA_XBMC_12PLUS, METADATA_MEDIABROWSER, METADATA_PS3, METADATA_KODI, metadata_provider_dict, \
|
||||
GIT_PATH, MOVE_ASSOCIATED_FILES, POSTPONE_IF_SYNC_FILES, recentSearchScheduler, NFO_RENAME, \
|
||||
GUI_NAME, DEFAULT_HOME, HOME_LAYOUT, HISTORY_LAYOUT, DISPLAY_SHOW_SPECIALS, EPISODE_VIEW_LAYOUT, EPISODE_VIEW_SORT, EPISODE_VIEW_DISPLAY_PAUSED, EPISODE_VIEW_MISSED_RANGE, FUZZY_DATING, TRIM_ZERO, DATE_PRESET, TIME_PRESET, TIME_PRESET_W_SECONDS, THEME_NAME, \
|
||||
POSTER_SORTBY, POSTER_SORTDIR, \
|
||||
METADATA_WDTV, METADATA_TIVO, METADATA_MEDE8ER, IGNORE_WORDS, REQUIRE_WORDS, CALENDAR_UNPROTECTED, CREATE_MISSING_SHOW_DIRS, \
|
||||
ADD_SHOWS_WO_DIR, REMOVE_FILENAME_CHARS, USE_SUBTITLES, SUBTITLES_LANGUAGES, SUBTITLES_DIR, SUBTITLES_SERVICES_LIST, SUBTITLES_SERVICES_ENABLED, SUBTITLES_HISTORY, SUBTITLES_FINDER_FREQUENCY, subtitlesFinderScheduler, \
|
||||
USE_FAILED_DOWNLOADS, DELETE_FAILED, ANON_REDIRECT, TMDB_API_KEY, DEBUG, PROXY_SETTING, PROXY_INDEXERS, \
|
||||
AUTOPOSTPROCESSER_FREQUENCY, DEFAULT_AUTOPOSTPROCESSER_FREQUENCY, MIN_AUTOPOSTPROCESSER_FREQUENCY, \
|
||||
ANIME_DEFAULT, NAMING_ANIME, USE_ANIDB, ANIDB_USERNAME, ANIDB_PASSWORD, ANIDB_USE_MYLIST, \
|
||||
SCENE_DEFAULT, BACKLOG_DAYS, SEARCH_UNAIRED, UNAIRED_RECENT_SEARCH_ONLY, ANIME_TREAT_AS_HDTV, \
|
||||
COOKIE_SECRET, USE_IMDB_INFO, IMDB_ACCOUNTS, DISPLAY_BACKGROUND, DISPLAY_BACKGROUND_TRANSPARENT, DISPLAY_ALL_SEASONS, \
|
||||
SHOW_TAGS, DEFAULT_SHOW_TAG, SHOWLIST_TAGVIEW, background_mapping_task, CACHE_IMAGE_URL_LIST
|
||||
USE_PUSHALOT, PUSHALOT_NOTIFY_ONSNATCH, PUSHALOT_NOTIFY_ONDOWNLOAD, \
|
||||
PUSHALOT_NOTIFY_ONSUBTITLEDOWNLOAD, PUSHALOT_AUTHORIZATIONTOKEN, \
|
||||
USE_PUSHBULLET, PUSHBULLET_NOTIFY_ONSNATCH, PUSHBULLET_NOTIFY_ONDOWNLOAD, \
|
||||
PUSHBULLET_NOTIFY_ONSUBTITLEDOWNLOAD, PUSHBULLET_ACCESS_TOKEN, PUSHBULLET_DEVICE_IDEN
|
||||
# Notification Settings/Social
|
||||
global USE_TWITTER, TWITTER_NOTIFY_ONSNATCH, TWITTER_NOTIFY_ONDOWNLOAD, TWITTER_NOTIFY_ONSUBTITLEDOWNLOAD, \
|
||||
TWITTER_USERNAME, TWITTER_PASSWORD, TWITTER_PREFIX, \
|
||||
USE_TRAKT, TRAKT_CONNECTED_ACCOUNT, TRAKT_ACCOUNTS, TRAKT_MRU, TRAKT_VERIFY, \
|
||||
TRAKT_USE_WATCHLIST, TRAKT_REMOVE_WATCHLIST, TRAKT_TIMEOUT, TRAKT_METHOD_ADD, TRAKT_START_PAUSED, \
|
||||
TRAKT_SYNC, TRAKT_DEFAULT_INDEXER, TRAKT_REMOVE_SERIESLIST, TRAKT_UPDATE_COLLECTION, \
|
||||
USE_EMAIL, EMAIL_NOTIFY_ONSNATCH, EMAIL_NOTIFY_ONDOWNLOAD, EMAIL_NOTIFY_ONSUBTITLEDOWNLOAD, EMAIL_FROM, \
|
||||
EMAIL_HOST, EMAIL_PORT, EMAIL_TLS, EMAIL_USER, EMAIL_PASSWORD, EMAIL_LIST, EMAIL_OLD_SUBJECTS
|
||||
# Anime Settings
|
||||
global ANIME_TREAT_AS_HDTV, USE_ANIDB, ANIDB_USERNAME, ANIDB_PASSWORD, ANIDB_USE_MYLIST
|
||||
|
||||
if __INITIALIZED__:
|
||||
return False
|
||||
|
||||
CheckSection(CFG, 'General')
|
||||
CheckSection(CFG, 'Blackhole')
|
||||
CheckSection(CFG, 'SABnzbd')
|
||||
CheckSection(CFG, 'NZBget')
|
||||
CheckSection(CFG, 'Emby')
|
||||
CheckSection(CFG, 'Kodi')
|
||||
CheckSection(CFG, 'XBMC')
|
||||
CheckSection(CFG, 'PLEX')
|
||||
CheckSection(CFG, 'Growl')
|
||||
CheckSection(CFG, 'Prowl')
|
||||
CheckSection(CFG, 'Twitter')
|
||||
CheckSection(CFG, 'Boxcar2')
|
||||
CheckSection(CFG, 'NMJ')
|
||||
CheckSection(CFG, 'NMJv2')
|
||||
CheckSection(CFG, 'Synology')
|
||||
CheckSection(CFG, 'SynologyNotifier')
|
||||
CheckSection(CFG, 'pyTivo')
|
||||
CheckSection(CFG, 'NMA')
|
||||
CheckSection(CFG, 'Pushalot')
|
||||
CheckSection(CFG, 'Pushbullet')
|
||||
CheckSection(CFG, 'Subtitles')
|
||||
for stanza in ('General', 'Blackhole', 'SABnzbd', 'NZBget', 'Emby', 'Kodi', 'XBMC', 'PLEX',
|
||||
'Growl', 'Prowl', 'Twitter', 'Boxcar2', 'NMJ', 'NMJv2', 'Synology', 'SynologyNotifier',
|
||||
'pyTivo', 'NMA', 'Pushalot', 'Pushbullet', 'Subtitles'):
|
||||
CheckSection(CFG, stanza)
|
||||
|
||||
# wanted branch
|
||||
BRANCH = check_setting_str(CFG, 'General', 'branch', '')
|
||||
|
@ -619,12 +655,9 @@ def initialize(consoleLogging=True):
|
|||
TIME_PRESET_W_SECONDS = check_setting_str(CFG, 'GUI', 'time_preset', '%I:%M:%S %p')
|
||||
TIME_PRESET = TIME_PRESET_W_SECONDS.replace(u':%S', u'')
|
||||
TIMEZONE_DISPLAY = check_setting_str(CFG, 'GUI', 'timezone_display', 'network')
|
||||
DISPLAY_BACKGROUND = bool(check_setting_int(CFG, 'General', 'display_background', 0))
|
||||
DISPLAY_BACKGROUND_TRANSPARENT = check_setting_str(CFG, 'General', 'display_background_transparent',
|
||||
'transparent')
|
||||
DISPLAY_ALL_SEASONS = bool(check_setting_int(CFG, 'General', 'display_all_seasons', 1))
|
||||
SHOW_TAGS = check_setting_str(CFG, 'GUI', 'show_tags', 'Show List').split(',')
|
||||
DEFAULT_SHOW_TAG = check_setting_str(CFG, 'GUI', 'default_show_tag', 'Show List')
|
||||
SHOW_TAG_DEFAULT = check_setting_str(CFG, 'GUI', 'show_tag_default',
|
||||
check_setting_str(CFG, 'GUI', 'default_show_tag', 'Show List'))
|
||||
SHOWLIST_TAGVIEW = check_setting_str(CFG, 'GUI', 'showlist_tagview', 'standard')
|
||||
|
||||
ACTUAL_LOG_DIR = check_setting_str(CFG, 'General', 'log_dir', 'Logs')
|
||||
|
@ -639,17 +672,10 @@ def initialize(consoleLogging=True):
|
|||
SOCKET_TIMEOUT = check_setting_int(CFG, 'General', 'socket_timeout', 30)
|
||||
socket.setdefaulttimeout(SOCKET_TIMEOUT)
|
||||
|
||||
try:
|
||||
WEB_PORT = check_setting_int(CFG, 'General', 'web_port', 8081)
|
||||
except:
|
||||
WEB_PORT = 8081
|
||||
|
||||
if WEB_PORT < 21 or WEB_PORT > 65535:
|
||||
WEB_PORT = 8081
|
||||
|
||||
WEB_HOST = check_setting_str(CFG, 'General', 'web_host', '0.0.0.0')
|
||||
WEB_IPV6 = bool(check_setting_int(CFG, 'General', 'web_ipv6', 0))
|
||||
WEB_PORT = minimax(check_setting_int(CFG, 'General', 'web_port', 8081), 8081, 21, 65535)
|
||||
WEB_ROOT = check_setting_str(CFG, 'General', 'web_root', '').rstrip('/')
|
||||
WEB_IPV6 = bool(check_setting_int(CFG, 'General', 'web_ipv6', 0))
|
||||
WEB_LOG = bool(check_setting_int(CFG, 'General', 'web_log', 0))
|
||||
ENCRYPTION_VERSION = check_setting_int(CFG, 'General', 'encryption_version', 0)
|
||||
WEB_USERNAME = check_setting_str(CFG, 'General', 'web_username', '')
|
||||
|
@ -740,7 +766,6 @@ def initialize(consoleLogging=True):
|
|||
ALLOW_HIGH_PRIORITY = bool(check_setting_int(CFG, 'General', 'allow_high_priority', 1))
|
||||
|
||||
RECENTSEARCH_STARTUP = bool(check_setting_int(CFG, 'General', 'recentsearch_startup', 0))
|
||||
BACKLOG_STARTUP = bool(check_setting_int(CFG, 'General', 'backlog_startup', 0))
|
||||
BACKLOG_NOFULL = bool(check_setting_int(CFG, 'General', 'backlog_nofull', 0))
|
||||
SKIP_REMOVED_FILES = check_setting_int(CFG, 'General', 'skip_removed_files', 0)
|
||||
|
||||
|
@ -1033,8 +1058,8 @@ def initialize(consoleLogging=True):
|
|||
NEWZNAB_DATA = check_setting_str(CFG, 'Newznab', 'newznab_data', '')
|
||||
newznabProviderList = providers.getNewznabProviderList(NEWZNAB_DATA)
|
||||
|
||||
TORRENTRSS_DATA = check_setting_str(CFG, 'TorrentRss', 'torrentrss_data', '')
|
||||
torrentRssProviderList = providers.getTorrentRssProviderList(TORRENTRSS_DATA)
|
||||
torrentrss_data = check_setting_str(CFG, 'TorrentRss', 'torrentrss_data', '')
|
||||
torrentRssProviderList = providers.getTorrentRssProviderList(torrentrss_data)
|
||||
|
||||
# dynamically load provider settings
|
||||
for torrent_prov in [curProvider for curProvider in providers.sortedProviderList()
|
||||
|
@ -1077,7 +1102,7 @@ def initialize(consoleLogging=True):
|
|||
if hasattr(torrent_prov, 'enable_recentsearch'):
|
||||
torrent_prov.enable_recentsearch = bool(check_setting_int(CFG, prov_id_uc,
|
||||
prov_id + '_enable_recentsearch', 1)) or \
|
||||
not getattr(torrent_prov, 'supports_backlog', True)
|
||||
not getattr(torrent_prov, 'supports_backlog')
|
||||
if hasattr(torrent_prov, 'enable_backlog'):
|
||||
torrent_prov.enable_backlog = bool(check_setting_int(CFG, prov_id_uc, prov_id + '_enable_backlog', 1))
|
||||
if hasattr(torrent_prov, 'search_mode'):
|
||||
|
@ -1104,7 +1129,7 @@ def initialize(consoleLogging=True):
|
|||
if hasattr(nzb_prov, 'enable_recentsearch'):
|
||||
nzb_prov.enable_recentsearch = bool(check_setting_int(CFG, prov_id_uc,
|
||||
prov_id + '_enable_recentsearch', 1)) or \
|
||||
not getattr(nzb_prov, 'supports_backlog', True)
|
||||
not getattr(nzb_prov, 'supports_backlog')
|
||||
if hasattr(nzb_prov, 'enable_backlog'):
|
||||
nzb_prov.enable_backlog = bool(check_setting_int(CFG, prov_id_uc, prov_id + '_enable_backlog', 1))
|
||||
|
||||
|
@ -1113,7 +1138,7 @@ def initialize(consoleLogging=True):
|
|||
save_config()
|
||||
|
||||
# start up all the threads
|
||||
logger.sb_log_instance.initLogging(consoleLogging=consoleLogging)
|
||||
logger.sb_log_instance.initLogging(consoleLogging=console_logging)
|
||||
|
||||
# initialize the main SB database
|
||||
my_db = db.DBConnection()
|
||||
|
@ -1183,8 +1208,7 @@ def initialize(consoleLogging=True):
|
|||
search_recent.RecentSearcher(),
|
||||
cycleTime=update_interval,
|
||||
threadName='RECENTSEARCHER',
|
||||
run_delay=update_now if RECENTSEARCH_STARTUP
|
||||
else datetime.timedelta(minutes=5),
|
||||
run_delay=update_now if RECENTSEARCH_STARTUP else datetime.timedelta(minutes=5),
|
||||
prevent_cycle_run=searchQueueScheduler.action.is_recentsearch_in_progress)
|
||||
|
||||
if [x for x in providers.sortedProviderList() if x.is_active() and
|
||||
|
@ -1229,17 +1253,16 @@ def initialize(consoleLogging=True):
|
|||
# processors
|
||||
autoPostProcesserScheduler = scheduler.Scheduler(
|
||||
auto_post_processer.PostProcesser(),
|
||||
cycleTime=datetime.timedelta(
|
||||
minutes=AUTOPOSTPROCESSER_FREQUENCY),
|
||||
cycleTime=datetime.timedelta(minutes=AUTOPOSTPROCESSER_FREQUENCY),
|
||||
threadName='POSTPROCESSER',
|
||||
silent=not PROCESS_AUTOMATICALLY)
|
||||
|
||||
"""
|
||||
traktCheckerScheduler = scheduler.Scheduler(
|
||||
traktChecker.TraktChecker(),
|
||||
cycleTime=datetime.timedelta(hours=1),
|
||||
threadName='TRAKTCHECKER',
|
||||
silent=not USE_TRAKT)
|
||||
|
||||
"""
|
||||
subtitlesFinderScheduler = scheduler.Scheduler(
|
||||
subtitles.SubtitlesFinder(),
|
||||
cycleTime=datetime.timedelta(hours=SUBTITLES_FINDER_FREQUENCY),
|
||||
|
@ -1247,7 +1270,6 @@ def initialize(consoleLogging=True):
|
|||
silent=not USE_SUBTITLES)
|
||||
|
||||
showList = []
|
||||
loadingShowList = {}
|
||||
|
||||
background_mapping_task = threading.Thread(name='LOAD-MAPPINGS', target=indexermapper.load_mapped_ids)
|
||||
|
||||
|
@ -1255,60 +1277,56 @@ def initialize(consoleLogging=True):
|
|||
return True
|
||||
|
||||
|
||||
def enabled_schedulers(is_init=False):
|
||||
# ([], [traktCheckerScheduler])[USE_TRAKT] + \
|
||||
for s in ([], [events])[is_init] + \
|
||||
[recentSearchScheduler, backlogSearchScheduler, showUpdateScheduler,
|
||||
versionCheckScheduler, showQueueScheduler, searchQueueScheduler] + \
|
||||
([], [properFinderScheduler])[DOWNLOAD_PROPERS] + \
|
||||
([], [autoPostProcesserScheduler])[PROCESS_AUTOMATICALLY] + \
|
||||
([], [subtitlesFinderScheduler])[USE_SUBTITLES] + \
|
||||
([events], [])[is_init]:
|
||||
yield s
|
||||
|
||||
|
||||
def start():
|
||||
global __INITIALIZED__, backlogSearchScheduler, \
|
||||
showUpdateScheduler, versionCheckScheduler, showQueueScheduler, \
|
||||
properFinderScheduler, autoPostProcesserScheduler, searchQueueScheduler, \
|
||||
subtitlesFinderScheduler, USE_SUBTITLES, traktCheckerScheduler, \
|
||||
recentSearchScheduler, events, started, background_mapping_task
|
||||
global started
|
||||
|
||||
with INIT_LOCK:
|
||||
if __INITIALIZED__:
|
||||
# Load all Indexer mappings in background
|
||||
indexermapper.defunct_indexer = [i for i in indexerApi().all_indexers if indexerApi(i).config.get('defunct')]
|
||||
indexermapper.defunct_indexer = [
|
||||
i for i in indexerApi().all_indexers if indexerApi(i).config.get('defunct')]
|
||||
indexermapper.indexer_list = [i for i in indexerApi().all_indexers]
|
||||
background_mapping_task.start()
|
||||
|
||||
# start sysetm events queue
|
||||
events.start()
|
||||
|
||||
# start the recent search scheduler
|
||||
recentSearchScheduler.start()
|
||||
|
||||
# start the backlog scheduler
|
||||
backlogSearchScheduler.start()
|
||||
|
||||
# start the show updater
|
||||
showUpdateScheduler.start()
|
||||
|
||||
# start the version checker
|
||||
versionCheckScheduler.start()
|
||||
|
||||
# start the queue checker
|
||||
showQueueScheduler.start()
|
||||
|
||||
# start the search queue checker
|
||||
searchQueueScheduler.start()
|
||||
|
||||
# start the queue checker
|
||||
if DOWNLOAD_PROPERS:
|
||||
properFinderScheduler.start()
|
||||
|
||||
# start the proper finder
|
||||
if PROCESS_AUTOMATICALLY:
|
||||
autoPostProcesserScheduler.start()
|
||||
|
||||
# start the subtitles finder
|
||||
if USE_SUBTITLES:
|
||||
subtitlesFinderScheduler.start()
|
||||
|
||||
# start the trakt checker
|
||||
# if USE_TRAKT:
|
||||
# traktCheckerScheduler.start()
|
||||
for thread in enabled_schedulers(is_init=True):
|
||||
thread.start()
|
||||
|
||||
started = True
|
||||
|
||||
|
||||
def restart(soft=True):
|
||||
if soft:
|
||||
halt()
|
||||
save_all()
|
||||
logger.log(u'Re-initializing all data')
|
||||
initialize()
|
||||
else:
|
||||
events.put(events.SystemEvent.RESTART)
|
||||
|
||||
|
||||
def sig_handler(signum=None, _=None):
|
||||
is_ctrlbreak = 'win32' == sys.platform and signal.SIGBREAK == signum
|
||||
msg = u'Signal "%s" found' % (signal.SIGINT == signum and 'CTRL-C' or is_ctrlbreak and 'CTRL+BREAK' or
|
||||
signal.SIGTERM == signum and 'Termination' or signum)
|
||||
if None is signum or signum in (signal.SIGINT, signal.SIGTERM) or is_ctrlbreak:
|
||||
logger.log('%s, saving and exiting...' % msg)
|
||||
events.put(events.SystemEvent.SHUTDOWN)
|
||||
else:
|
||||
logger.log('%s, not exiting' % msg)
|
||||
|
||||
|
||||
def halt():
|
||||
global __INITIALIZED__, started
|
||||
|
||||
|
@ -1318,83 +1336,33 @@ def halt():
|
|||
|
||||
logger.log(u'Aborting all threads')
|
||||
|
||||
schedulers = [
|
||||
recentSearchScheduler,
|
||||
backlogSearchScheduler,
|
||||
showUpdateScheduler,
|
||||
versionCheckScheduler,
|
||||
showQueueScheduler,
|
||||
searchQueueScheduler,
|
||||
|
||||
properFinderScheduler,
|
||||
autoPostProcesserScheduler,
|
||||
subtitlesFinderScheduler,
|
||||
|
||||
events
|
||||
]
|
||||
|
||||
for thread in schedulers:
|
||||
for thread in enabled_schedulers():
|
||||
thread.stop.set()
|
||||
|
||||
for thread in schedulers:
|
||||
for thread in enabled_schedulers():
|
||||
logger.log('Waiting for the %s thread to exit' % thread.name)
|
||||
try:
|
||||
thread.join(10)
|
||||
except RuntimeError:
|
||||
pass
|
||||
|
||||
if PROCESS_AUTOMATICALLY:
|
||||
autoPostProcesserScheduler.stop.set()
|
||||
logger.log(u'Waiting for the POSTPROCESSER thread to exit')
|
||||
try:
|
||||
autoPostProcesserScheduler.join(10)
|
||||
except:
|
||||
pass
|
||||
|
||||
if DOWNLOAD_PROPERS:
|
||||
properFinderScheduler.stop.set()
|
||||
logger.log(u'Waiting for the PROPERFINDER thread to exit')
|
||||
try:
|
||||
properFinderScheduler.join(10)
|
||||
except:
|
||||
pass
|
||||
|
||||
if USE_SUBTITLES:
|
||||
subtitlesFinderScheduler.stop.set()
|
||||
logger.log(u'Waiting for the SUBTITLESFINDER thread to exit')
|
||||
try:
|
||||
subtitlesFinderScheduler.join(10)
|
||||
except:
|
||||
pass
|
||||
|
||||
if ADBA_CONNECTION:
|
||||
try:
|
||||
ADBA_CONNECTION.logout()
|
||||
except AniDBBannedError as e:
|
||||
logger.log(u'ANIDB Error %s' % ex(e), logger.DEBUG)
|
||||
except AniDBError as e:
|
||||
except AniDBError:
|
||||
pass
|
||||
logger.log(u'Waiting for the ANIDB CONNECTION thread to exit')
|
||||
try:
|
||||
ADBA_CONNECTION.join(10)
|
||||
except:
|
||||
except (StandardError, Exception):
|
||||
pass
|
||||
|
||||
__INITIALIZED__ = False
|
||||
started = False
|
||||
|
||||
|
||||
def sig_handler(signum=None, frame=None):
|
||||
is_ctrlbreak = 'win32' == sys.platform and signal.SIGBREAK == signum
|
||||
msg = u'Signal "%s" found' % (signal.SIGINT == signum and 'CTRL-C' or is_ctrlbreak and 'CTRL+BREAK' or
|
||||
signal.SIGTERM == signum and 'Termination' or signum)
|
||||
if None is signum or signum in (signal.SIGINT, signal.SIGTERM) or is_ctrlbreak:
|
||||
logger.log('%s, saving and exiting...' % msg)
|
||||
events.put(events.SystemEvent.SHUTDOWN)
|
||||
else:
|
||||
logger.log('%s, not exiting' % msg)
|
||||
|
||||
|
||||
def save_all():
|
||||
global showList
|
||||
|
||||
|
@ -1408,16 +1376,6 @@ def save_all():
|
|||
save_config()
|
||||
|
||||
|
||||
def restart(soft=True):
|
||||
if soft:
|
||||
halt()
|
||||
save_all()
|
||||
logger.log(u'Re-initializing all data')
|
||||
initialize()
|
||||
else:
|
||||
events.put(events.SystemEvent.RESTART)
|
||||
|
||||
|
||||
def save_config():
|
||||
new_config = ConfigObj()
|
||||
new_config.filename = CONFIG_FILE
|
||||
|
@ -1463,7 +1421,6 @@ def save_config():
|
|||
new_config['General']['check_propers_interval'] = CHECK_PROPERS_INTERVAL
|
||||
new_config['General']['allow_high_priority'] = int(ALLOW_HIGH_PRIORITY)
|
||||
new_config['General']['recentsearch_startup'] = int(RECENTSEARCH_STARTUP)
|
||||
new_config['General']['backlog_startup'] = int(BACKLOG_STARTUP)
|
||||
new_config['General']['backlog_nofull'] = int(BACKLOG_NOFULL)
|
||||
new_config['General']['skip_removed_files'] = int(SKIP_REMOVED_FILES)
|
||||
new_config['General']['quality_default'] = int(QUALITY_DEFAULT)
|
||||
|
@ -1501,9 +1458,6 @@ def save_config():
|
|||
new_config['General']['sort_article'] = int(SORT_ARTICLE)
|
||||
new_config['General']['proxy_setting'] = PROXY_SETTING
|
||||
new_config['General']['proxy_indexers'] = int(PROXY_INDEXERS)
|
||||
new_config['General']['display_background'] = int(DISPLAY_BACKGROUND)
|
||||
new_config['General']['display_background_transparent'] = DISPLAY_BACKGROUND_TRANSPARENT
|
||||
new_config['General']['display_all_seasons'] = int(DISPLAY_ALL_SEASONS)
|
||||
|
||||
new_config['General']['metadata_xbmc'] = METADATA_XBMC
|
||||
new_config['General']['metadata_xbmc_12plus'] = METADATA_XBMC_12PLUS
|
||||
|
@ -1800,6 +1754,10 @@ def save_config():
|
|||
new_config['GUI']['date_preset'] = DATE_PRESET
|
||||
new_config['GUI']['time_preset'] = TIME_PRESET_W_SECONDS
|
||||
new_config['GUI']['timezone_display'] = TIMEZONE_DISPLAY
|
||||
|
||||
new_config['GUI']['show_tags'] = ','.join(SHOW_TAGS)
|
||||
new_config['GUI']['showlist_tagview'] = SHOWLIST_TAGVIEW
|
||||
|
||||
new_config['GUI']['home_layout'] = HOME_LAYOUT
|
||||
new_config['GUI']['history_layout'] = HISTORY_LAYOUT
|
||||
new_config['GUI']['display_show_specials'] = int(DISPLAY_SHOW_SPECIALS)
|
||||
|
@ -1811,7 +1769,7 @@ def save_config():
|
|||
new_config['GUI']['poster_sortdir'] = POSTER_SORTDIR
|
||||
new_config['GUI']['show_tags'] = ','.join(SHOW_TAGS)
|
||||
new_config['GUI']['showlist_tagview'] = SHOWLIST_TAGVIEW
|
||||
new_config['GUI']['default_show_tag'] = DEFAULT_SHOW_TAG
|
||||
new_config['GUI']['show_tag_default'] = SHOW_TAG_DEFAULT
|
||||
|
||||
new_config['Subtitles'] = {}
|
||||
new_config['Subtitles']['use_subtitles'] = int(USE_SUBTITLES)
|
||||
|
@ -1842,14 +1800,11 @@ def save_config():
|
|||
def launch_browser(start_port=None):
|
||||
if not start_port:
|
||||
start_port = WEB_PORT
|
||||
if ENABLE_HTTPS:
|
||||
browser_url = 'https://localhost:%d%s' % (start_port, WEB_ROOT)
|
||||
else:
|
||||
browser_url = 'http://localhost:%d%s' % (start_port, WEB_ROOT)
|
||||
browser_url = 'http%s://localhost:%d%s' % (('s' or '')[not ENABLE_HTTPS], start_port, WEB_ROOT)
|
||||
try:
|
||||
webbrowser.open(browser_url, 2, 1)
|
||||
except:
|
||||
except (StandardError, Exception):
|
||||
try:
|
||||
webbrowser.open(browser_url, 1, 1)
|
||||
except:
|
||||
logger.log(u'Unable to launch a browser', logger.ERROR)
|
||||
except (StandardError, Exception):
|
||||
logger.log('Unable to launch a browser', logger.ERROR)
|
||||
|
|
|
@ -740,7 +740,6 @@ class ConfigMigrator():
|
|||
def _migrate_v8(self):
|
||||
# removing settings from gui and making it a hidden debug option
|
||||
sickbeard.RECENTSEARCH_STARTUP = False
|
||||
sickbeard.BACKLOG_STARTUP = False
|
||||
|
||||
def _migrate_v9(self):
|
||||
sickbeard.PUSHBULLET_ACCESS_TOKEN = check_setting_str(self.config_obj, 'Pushbullet', 'pushbullet_api', '')
|
||||
|
|
|
@ -1106,12 +1106,12 @@ class Home(MainHandler):
|
|||
if str(pid) != str(sickbeard.PID):
|
||||
return self.redirect('/home/')
|
||||
|
||||
t = PageTemplate(headers=self.request.headers, file='restart.tmpl')
|
||||
t.shutdown = True
|
||||
|
||||
sickbeard.events.put(sickbeard.events.SystemEvent.SHUTDOWN)
|
||||
|
||||
title = 'Shutting down'
|
||||
message = 'SickGear is shutting down...'
|
||||
|
||||
return self._genericMessage(title, message)
|
||||
return t.respond()
|
||||
|
||||
def restart(self, pid=None):
|
||||
|
||||
|
@ -1119,8 +1119,8 @@ class Home(MainHandler):
|
|||
return self.redirect('/home/')
|
||||
|
||||
t = PageTemplate(headers=self.request.headers, file='restart.tmpl')
|
||||
t.shutdown = False
|
||||
|
||||
# restart
|
||||
sickbeard.events.put(sickbeard.events.SystemEvent.RESTART)
|
||||
|
||||
return t.respond()
|
||||
|
@ -4275,7 +4275,7 @@ class ConfigGeneral(Config):
|
|||
sickbeard.SCENE_DEFAULT = config.checkbox_to_value(default_scene)
|
||||
sickbeard.SUBTITLES_DEFAULT = config.checkbox_to_value(default_subtitles)
|
||||
sickbeard.ANIME_DEFAULT = config.checkbox_to_value(default_anime)
|
||||
sickbeard.DEFAULT_SHOW_TAG = default_tag
|
||||
sickbeard.SHOW_TAG_DEFAULT = default_tag
|
||||
|
||||
sickbeard.save_config()
|
||||
|
||||
|
@ -4311,7 +4311,6 @@ class ConfigGeneral(Config):
|
|||
proxy_setting=None, proxy_indexers=None, anon_redirect=None, git_path=None, git_remote=None, calendar_unprotected=None,
|
||||
fuzzy_dating=None, trim_zero=None, date_preset=None, date_preset_na=None, time_preset=None,
|
||||
indexer_timeout=None, rootDir=None, theme_name=None, default_home=None, use_imdb_info=None,
|
||||
display_background=None, display_background_transparent=None, display_all_seasons=None,
|
||||
show_tags=None, showlist_tagview=None):
|
||||
|
||||
results = []
|
||||
|
@ -4331,9 +4330,6 @@ class ConfigGeneral(Config):
|
|||
sickbeard.LAUNCH_BROWSER = config.checkbox_to_value(launch_browser)
|
||||
sickbeard.HOME_SEARCH_FOCUS = config.checkbox_to_value(home_search_focus)
|
||||
sickbeard.USE_IMDB_INFO = config.checkbox_to_value(use_imdb_info)
|
||||
sickbeard.DISPLAY_BACKGROUND = config.checkbox_to_value(display_background)
|
||||
sickbeard.DISPLAY_BACKGROUND_TRANSPARENT = display_background_transparent
|
||||
sickbeard.DISPLAY_ALL_SEASONS = config.checkbox_to_value(display_all_seasons)
|
||||
sickbeard.SORT_ARTICLE = config.checkbox_to_value(sort_article)
|
||||
sickbeard.CPU_PRESET = cpu_preset
|
||||
sickbeard.FILE_LOGGING_PRESET = file_logging_preset
|
||||
|
|
|
@ -35,7 +35,7 @@ from sickbeard.name_parser.parser import NameParser
|
|||
from sickbeard.tv import TVShow
|
||||
|
||||
class XEMBasicTests(test.SickbeardTestDBCase):
|
||||
def loadShowsFromDB(self):
|
||||
def load_shows_from_db(self):
|
||||
"""
|
||||
Populates the showList with shows from the database
|
||||
"""
|
||||
|
|
Loading…
Reference in a new issue