Browse Source

Shutdown event

pull/51/merge
Ruud 14 years ago
parent
commit
4fd3f91a77
  1. 49
      couchpotato/cli.py
  2. 25
      couchpotato/core/_base/_core/main.py
  3. 13
      couchpotato/core/event.py
  4. 25
      couchpotato/core/plugins/base.py
  5. 4
      couchpotato/core/plugins/renamer/main.py
  6. 5
      couchpotato/core/plugins/searcher/main.py

49
couchpotato/cli.py

@ -2,7 +2,7 @@ from argparse import ArgumentParser
from couchpotato import web from couchpotato import web
from couchpotato.api import api from couchpotato.api import api
from couchpotato.core.event import fireEventAsync from couchpotato.core.event import fireEventAsync
from libs.daemon import createDaemon from daemon import createDaemon
from logging import handlers from logging import handlers
from werkzeug.contrib.cache import FileSystemCache from werkzeug.contrib.cache import FileSystemCache
import logging import logging
@ -67,36 +67,37 @@ def cmd_couchpotato(options, base_path, args):
debug = options.debug or Env.setting('debug', default = False) debug = options.debug or Env.setting('debug', default = False)
Env.set('debug', debug) Env.set('debug', debug)
# Only run once when debugging
if os.environ.get('WERKZEUG_RUN_MAIN') or not debug:
# Logger # Logger
logger = logging.getLogger() logger = logging.getLogger()
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s', '%H:%M:%S') formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s', '%H:%M:%S')
level = logging.DEBUG if debug else logging.INFO level = logging.DEBUG if debug else logging.INFO
logger.setLevel(level) logger.setLevel(level)
# To screen # To screen
if debug and not options.quiet and not options.daemonize: if debug and not options.quiet and not options.daemonize:
hdlr = logging.StreamHandler(sys.stderr) hdlr = logging.StreamHandler(sys.stderr)
hdlr.setFormatter(formatter) hdlr.setFormatter(formatter)
logger.addHandler(hdlr) logger.addHandler(hdlr)
# To file # To file
hdlr2 = handlers.RotatingFileHandler(Env.get('log_path'), 'a', 500000, 10) hdlr2 = handlers.RotatingFileHandler(Env.get('log_path'), 'a', 500000, 10)
hdlr2.setFormatter(formatter) hdlr2.setFormatter(formatter)
logger.addHandler(hdlr2) logger.addHandler(hdlr2)
# Disable server access log # Disable server access log
server_log = logging.getLogger('werkzeug') server_log = logging.getLogger('werkzeug')
server_log.disabled = True server_log.disabled = True
# Start logging # Start logging
from couchpotato.core.logger import CPLog from couchpotato.core.logger import CPLog
log = CPLog(__name__) log = CPLog(__name__)
log.debug('Started with options %s' % options) log.debug('Started with options %s' % options)
# Load configs & plugins (only run once when debugging) # Load configs & plugins
if os.environ.get('WERKZEUG_RUN_MAIN') or not debug:
loader = Env.get('loader') loader = Env.get('loader')
loader.preload(root = base_path) loader.preload(root = base_path)
loader.run() loader.run()

25
couchpotato/core/_base/_core/main.py

@ -5,6 +5,7 @@ from couchpotato.core.plugins.base import Plugin
from couchpotato.environment import Env from couchpotato.environment import Env
from flask import request from flask import request
import os import os
import time
log = CPLog(__name__) log = CPLog(__name__)
@ -29,12 +30,25 @@ class Core(Plugin):
fireEvent('app.shutdown') 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: 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') func = request.environ.get('werkzeug.server.shutdown')
if func is None: if func is None:
raise RuntimeError('Not running with the Werkzeug Server') log.error('Failed shutting down the server')
func() func()
def removeRestartFile(self): def removeRestartFile(self):
@ -43,12 +57,5 @@ class Core(Plugin):
except: except:
pass 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): def restartFilePath(self):
return os.path.join(Env.get('data_dir'), 'restart') return os.path.join(Env.get('data_dir'), 'restart')

13
couchpotato/core/event.py

@ -1,12 +1,16 @@
from axl.axel import Event from axl.axel import Event
from couchpotato.core.helpers.variable import mergeDicts from couchpotato.core.helpers.variable import mergeDicts
from couchpotato.core.logger import CPLog from couchpotato.core.logger import CPLog
import inspect
import threading import threading
import traceback import traceback
log = CPLog(__name__) log = CPLog(__name__)
events = {} events = {}
def addEvent(name, handler): def addEvent(name, handler):
if events.get(name): if events.get(name):
@ -14,7 +18,14 @@ def addEvent(name, handler):
else: else:
e = events[name] = Event(threads = 20, exc_info = True, traceback = True, lock = threading.RLock()) 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): def removeEvent(name, handler):
e = events[name] e = events[name]

25
couchpotato/core/plugins/base.py

@ -17,9 +17,11 @@ class Plugin(object):
auto_register_static = True auto_register_static = True
needs_shutdown = False needs_shutdown = False
running = 0
def registerPlugin(self): def registerPlugin(self):
addEvent('app.shutdown', self.doShutdown) addEvent('app.shutdown', self.doShutdown)
addEvent('plugin.running', self.isRunning)
def conf(self, attr, default = None): def conf(self, attr, default = None):
return Env.setting(attr, self.getName().lower(), default = default) return Env.setting(attr, self.getName().lower(), default = default)
@ -40,21 +42,21 @@ class Plugin(object):
addView(path + '<path:file>', self.showStatic, static = True) addView(path + '<path:file>', self.showStatic, static = True)
if add_to_head: if add_to_head:
for file in glob.glob(os.path.join(self.plugin_path, 'static', '*')): for f 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)) fireEvent('register_%s' % ('script' if getExt(f) in 'js' else 'style'), path + os.path.basename(f))
def showStatic(self, file = ''): def showStatic(self, f = ''):
dir = os.path.join(self.plugin_path, 'static') d = os.path.join(self.plugin_path, 'static')
return send_from_directory(dir, file) return send_from_directory(d, f)
def createFile(self, path, content): def createFile(self, path, content):
self.makeDir(os.path.dirname(path)) self.makeDir(os.path.dirname(path))
try: try:
file = open(path, 'w') f = open(path, 'w')
file.write(content) f.write(content)
file.close() f.close()
except Exception, e: except Exception, e:
log.error('Unable writing to file "%s": %s' % (path, e)) log.error('Unable writing to file "%s": %s' % (path, e))
@ -75,6 +77,13 @@ class Plugin(object):
self.needs_shutdown = value 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): def isDisabled(self):
return not self.isEnabled() return not self.isEnabled()

4
couchpotato/core/plugins/renamer/main.py

@ -216,6 +216,10 @@ class Renamer(Plugin):
# Search for trailers etc # Search for trailers etc
fireEvent('renamer.after', group) fireEvent('renamer.after', group)
# Break if CP wants to shut down
if self.shuttingDown():
break
def moveFile(self, old, dest, suppress = True): def moveFile(self, old, dest, suppress = True):
try: try:
shutil.move(old, dest) shutil.move(old, dest)

5
couchpotato/core/plugins/searcher/main.py

@ -30,6 +30,7 @@ class Searcher(Plugin):
).all() ).all()
for movie in movies: for movie in movies:
self.single(movie.to_dict(deep = { self.single(movie.to_dict(deep = {
'profile': {'types': {'quality': {}}}, 'profile': {'types': {'quality': {}}},
'releases': {'status': {}, 'quality': {}}, 'releases': {'status': {}, 'quality': {}},
@ -37,6 +38,10 @@ class Searcher(Plugin):
'files': {} 'files': {}
})) }))
# Break if CP wants to shut down
if self.shuttingDown():
break
def single(self, movie): def single(self, movie):
downloaded_status = fireEvent('status.get', 'downloaded', single = True) downloaded_status = fireEvent('status.get', 'downloaded', single = True)

Loading…
Cancel
Save