Shutdown event
This commit is contained in:
+31
-30
@@ -2,7 +2,7 @@ from argparse import ArgumentParser
|
||||
from couchpotato import web
|
||||
from couchpotato.api import api
|
||||
from couchpotato.core.event import fireEventAsync
|
||||
from libs.daemon import createDaemon
|
||||
from daemon import createDaemon
|
||||
from logging import handlers
|
||||
from werkzeug.contrib.cache import FileSystemCache
|
||||
import logging
|
||||
@@ -67,36 +67,37 @@ def cmd_couchpotato(options, base_path, args):
|
||||
debug = options.debug or Env.setting('debug', default = False)
|
||||
Env.set('debug', debug)
|
||||
|
||||
|
||||
# Logger
|
||||
logger = logging.getLogger()
|
||||
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s', '%H:%M:%S')
|
||||
level = logging.DEBUG if debug else logging.INFO
|
||||
logger.setLevel(level)
|
||||
|
||||
# To screen
|
||||
if debug and not options.quiet and not options.daemonize:
|
||||
hdlr = logging.StreamHandler(sys.stderr)
|
||||
hdlr.setFormatter(formatter)
|
||||
logger.addHandler(hdlr)
|
||||
|
||||
# To file
|
||||
hdlr2 = handlers.RotatingFileHandler(Env.get('log_path'), 'a', 500000, 10)
|
||||
hdlr2.setFormatter(formatter)
|
||||
logger.addHandler(hdlr2)
|
||||
|
||||
# Disable server access log
|
||||
server_log = logging.getLogger('werkzeug')
|
||||
server_log.disabled = True
|
||||
|
||||
# Start logging
|
||||
from couchpotato.core.logger import CPLog
|
||||
log = CPLog(__name__)
|
||||
log.debug('Started with options %s' % options)
|
||||
|
||||
|
||||
# Load configs & plugins (only run once when debugging)
|
||||
# Only run once when debugging
|
||||
if os.environ.get('WERKZEUG_RUN_MAIN') or not debug:
|
||||
|
||||
# Logger
|
||||
logger = logging.getLogger()
|
||||
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s', '%H:%M:%S')
|
||||
level = logging.DEBUG if debug else logging.INFO
|
||||
logger.setLevel(level)
|
||||
|
||||
# To screen
|
||||
if debug and not options.quiet and not options.daemonize:
|
||||
hdlr = logging.StreamHandler(sys.stderr)
|
||||
hdlr.setFormatter(formatter)
|
||||
logger.addHandler(hdlr)
|
||||
|
||||
# To file
|
||||
hdlr2 = handlers.RotatingFileHandler(Env.get('log_path'), 'a', 500000, 10)
|
||||
hdlr2.setFormatter(formatter)
|
||||
logger.addHandler(hdlr2)
|
||||
|
||||
# Disable server access log
|
||||
server_log = logging.getLogger('werkzeug')
|
||||
server_log.disabled = True
|
||||
|
||||
# Start logging
|
||||
from couchpotato.core.logger import CPLog
|
||||
log = CPLog(__name__)
|
||||
log.debug('Started with options %s' % options)
|
||||
|
||||
|
||||
# Load configs & plugins
|
||||
loader = Env.get('loader')
|
||||
loader.preload(root = base_path)
|
||||
loader.run()
|
||||
|
||||
@@ -5,6 +5,7 @@ from couchpotato.core.plugins.base import Plugin
|
||||
from couchpotato.environment import Env
|
||||
from flask import request
|
||||
import os
|
||||
import time
|
||||
|
||||
|
||||
log = CPLog(__name__)
|
||||
@@ -29,12 +30,25 @@ class Core(Plugin):
|
||||
|
||||
fireEvent('app.shutdown')
|
||||
|
||||
while 1:
|
||||
still_running = fireEvent('plugin.running')
|
||||
|
||||
brk = True
|
||||
for running in still_running:
|
||||
if running > 0:
|
||||
brk = False
|
||||
|
||||
if brk: break
|
||||
|
||||
time.sleep(1)
|
||||
|
||||
|
||||
if restart:
|
||||
self.writeRestartFile()
|
||||
self.createFile(self.restartFilePath(), 'This is the most suckiest way to register if CP is restarted. Ever...')
|
||||
|
||||
func = request.environ.get('werkzeug.server.shutdown')
|
||||
if func is None:
|
||||
raise RuntimeError('Not running with the Werkzeug Server')
|
||||
log.error('Failed shutting down the server')
|
||||
func()
|
||||
|
||||
def removeRestartFile(self):
|
||||
@@ -43,12 +57,5 @@ class Core(Plugin):
|
||||
except:
|
||||
pass
|
||||
|
||||
def writeRestartFile(self):
|
||||
try:
|
||||
with open(self.restartFilePath(), 'w') as f:
|
||||
f.write('This is the most suckiest way to register if CP is restarted. Ever...')
|
||||
except Exception, e:
|
||||
log.error('Could not write shutdown file: %s' % e)
|
||||
|
||||
def restartFilePath(self):
|
||||
return os.path.join(Env.get('data_dir'), 'restart')
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
from axl.axel import Event
|
||||
from couchpotato.core.helpers.variable import mergeDicts
|
||||
from couchpotato.core.logger import CPLog
|
||||
import inspect
|
||||
import threading
|
||||
import traceback
|
||||
|
||||
log = CPLog(__name__)
|
||||
events = {}
|
||||
|
||||
|
||||
|
||||
|
||||
def addEvent(name, handler):
|
||||
|
||||
if events.get(name):
|
||||
@@ -14,7 +18,14 @@ def addEvent(name, handler):
|
||||
else:
|
||||
e = events[name] = Event(threads = 20, exc_info = True, traceback = True, lock = threading.RLock())
|
||||
|
||||
e += handler
|
||||
def createHandle(handler, *args, **kwargs):
|
||||
handler.im_self.isRunning(True)
|
||||
h = handler(*args, **kwargs)
|
||||
handler.im_self.isRunning(True)
|
||||
|
||||
return h
|
||||
|
||||
e += createHandle(handler)
|
||||
|
||||
def removeEvent(name, handler):
|
||||
e = events[name]
|
||||
|
||||
@@ -17,9 +17,11 @@ class Plugin(object):
|
||||
auto_register_static = True
|
||||
|
||||
needs_shutdown = False
|
||||
running = 0
|
||||
|
||||
def registerPlugin(self):
|
||||
addEvent('app.shutdown', self.doShutdown)
|
||||
addEvent('plugin.running', self.isRunning)
|
||||
|
||||
def conf(self, attr, default = None):
|
||||
return Env.setting(attr, self.getName().lower(), default = default)
|
||||
@@ -40,21 +42,21 @@ class Plugin(object):
|
||||
addView(path + '<path:file>', self.showStatic, static = True)
|
||||
|
||||
if add_to_head:
|
||||
for file in glob.glob(os.path.join(self.plugin_path, 'static', '*')):
|
||||
fireEvent('register_%s' % ('script' if getExt(file) in 'js' else 'style'), path + os.path.basename(file))
|
||||
for f in glob.glob(os.path.join(self.plugin_path, 'static', '*')):
|
||||
fireEvent('register_%s' % ('script' if getExt(f) in 'js' else 'style'), path + os.path.basename(f))
|
||||
|
||||
def showStatic(self, file = ''):
|
||||
dir = os.path.join(self.plugin_path, 'static')
|
||||
return send_from_directory(dir, file)
|
||||
def showStatic(self, f = ''):
|
||||
d = os.path.join(self.plugin_path, 'static')
|
||||
return send_from_directory(d, f)
|
||||
|
||||
def createFile(self, path, content):
|
||||
|
||||
self.makeDir(os.path.dirname(path))
|
||||
|
||||
try:
|
||||
file = open(path, 'w')
|
||||
file.write(content)
|
||||
file.close()
|
||||
f = open(path, 'w')
|
||||
f.write(content)
|
||||
f.close()
|
||||
except Exception, e:
|
||||
log.error('Unable writing to file "%s": %s' % (path, e))
|
||||
|
||||
@@ -75,6 +77,13 @@ class Plugin(object):
|
||||
|
||||
self.needs_shutdown = value
|
||||
|
||||
def isRunning(self, value = None):
|
||||
if value is None:
|
||||
return self.running
|
||||
|
||||
log.debug('Running %s: %s' % (value, self.getName()))
|
||||
self.running += 1 if value else -1
|
||||
|
||||
def isDisabled(self):
|
||||
return not self.isEnabled()
|
||||
|
||||
|
||||
@@ -216,6 +216,10 @@ class Renamer(Plugin):
|
||||
# Search for trailers etc
|
||||
fireEvent('renamer.after', group)
|
||||
|
||||
# Break if CP wants to shut down
|
||||
if self.shuttingDown():
|
||||
break
|
||||
|
||||
def moveFile(self, old, dest, suppress = True):
|
||||
try:
|
||||
shutil.move(old, dest)
|
||||
|
||||
@@ -30,6 +30,7 @@ class Searcher(Plugin):
|
||||
).all()
|
||||
|
||||
for movie in movies:
|
||||
|
||||
self.single(movie.to_dict(deep = {
|
||||
'profile': {'types': {'quality': {}}},
|
||||
'releases': {'status': {}, 'quality': {}},
|
||||
@@ -37,6 +38,10 @@ class Searcher(Plugin):
|
||||
'files': {}
|
||||
}))
|
||||
|
||||
# Break if CP wants to shut down
|
||||
if self.shuttingDown():
|
||||
break
|
||||
|
||||
def single(self, movie):
|
||||
|
||||
downloaded_status = fireEvent('status.get', 'downloaded', single = True)
|
||||
|
||||
Reference in New Issue
Block a user