You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

203 lines
6.8 KiB

from argparse import ArgumentParser
from couchpotato import web
from couchpotato.api import api
from couchpotato.core.event import fireEventAsync, fireEvent
from couchpotato.core.helpers.variable import getDataDir, tryInt
from logging import handlers
from werkzeug.contrib.cache import FileSystemCache
import atexit
import locale
import logging
import os.path
import sys
import traceback
import time
def getOptions(base_path, args):
data_dir = getDataDir()
# Options
parser = ArgumentParser(prog = 'CouchPotato.py')
parser.add_argument('--config_file', default = os.path.join(data_dir, 'settings.conf'),
dest = 'config_file', help = 'Absolute or ~/ path of the settings file (default ./_data/settings.conf)')
parser.add_argument('--debug', action = 'store_true',
dest = 'debug', help = 'Debug mode')
parser.add_argument('--console_log', action = 'store_true',
dest = 'console_log', help = "Log to console")
parser.add_argument('--quiet', action = 'store_true',
dest = 'quiet', help = 'No console logging')
parser.add_argument('--nogit', action = 'store_true',
dest = 'nogit', help = 'No git available')
parser.add_argument('--daemon', action = 'store_true',
dest = 'daemon', help = 'Daemonize the app')
parser.add_argument('--pid_file', default = os.path.join(data_dir, 'couchpotato.pid'),
dest = 'pid_file', help = 'Path to pidfile needed for daemon')
options = parser.parse_args(args)
options.config_file = os.path.expanduser(options.config_file)
return options
def cleanup():
fireEvent('app.crappy_shutdown', single = True)
time.sleep(1)
def runCouchPotato(options, base_path, args, desktop = None):
# Load settings
from couchpotato.environment import Env
settings = Env.get('settings')
settings.setFile(options.config_file)
# Create data dir if needed
data_dir = os.path.expanduser(Env.setting('data_dir'))
if data_dir == '':
data_dir = getDataDir()
if not os.path.isdir(data_dir):
os.makedirs(data_dir)
# Create logging dir
log_dir = os.path.join(data_dir, 'logs');
if not os.path.isdir(log_dir):
os.mkdir(log_dir)
try:
locale.setlocale(locale.LC_ALL, "")
encoding = locale.getpreferredencoding()
except (locale.Error, IOError):
pass
# for OSes that are poorly configured I'll just force UTF-8
if not encoding or encoding in ('ANSI_X3.4-1968', 'US-ASCII', 'ASCII'):
encoding = 'UTF-8'
# Register environment settings
Env.set('encoding', encoding)
Env.set('uses_git', not options.nogit)
Env.set('app_dir', base_path)
Env.set('data_dir', data_dir)
Env.set('log_path', os.path.join(log_dir, 'CouchPotato.log'))
Env.set('db_path', 'sqlite:///' + os.path.join(data_dir, 'couchpotato.db'))
Env.set('cache_dir', os.path.join(data_dir, 'cache'))
Env.set('cache', FileSystemCache(os.path.join(Env.get('cache_dir'), 'python')))
Env.set('console_log', options.console_log)
Env.set('quiet', options.quiet)
Env.set('desktop', desktop)
Env.set('args', args)
Env.set('options', options)
# Determine debug
debug = options.debug or Env.setting('debug', default = False, type = 'bool')
Env.set('debug', debug)
if not Env.setting('development'):
atexit.register(cleanup)
# Disable server access log
server_log = logging.getLogger('werkzeug')
server_log.disabled = True
# Only run once when debugging
fire_load = False
if os.environ.get('WERKZEUG_RUN_MAIN') or not debug or Env.get('desktop') or options.daemon:
# 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 or options.console_log) and not options.quiet and not options.daemon:
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)
# Start logging & enable colors
import color_logs
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()
# Load migrations
from migrate.versioning.api import version_control, db_version, version, upgrade
db = Env.get('db_path')
repo = os.path.join(base_path, 'couchpotato', 'core', 'migration')
logging.getLogger('migrate').setLevel(logging.WARNING) # Disable logging for migration
latest_db_version = version(repo)
initialize = True
try:
current_db_version = db_version(db, repo)
initialize = False
except:
version_control(db, repo, version = latest_db_version)
current_db_version = db_version(db, repo)
if current_db_version < latest_db_version and not debug:
log.info('Doing database upgrade. From %d to %d' % (current_db_version, latest_db_version))
upgrade(db, repo)
# Configure Database
from couchpotato.core.settings.model import setup
setup()
if initialize:
fireEvent('app.initialize')
fire_load = True
# Create app
from couchpotato import app
api_key = Env.setting('api_key')
url_base = '/' + Env.setting('url_base').lstrip('/') if Env.setting('url_base') else ''
reloader = debug is True and not Env.get('desktop') and not options.daemon
# Basic config
app.secret_key = api_key
config = {
'use_reloader': reloader,
'host': Env.setting('host', default = '0.0.0.0'),
'port': tryInt(Env.setting('port', default = 5000))
}
# Static path
web.add_url_rule('static/<path:filename>',
endpoint = 'static',
view_func = app.send_static_file)
# Register modules
app.register_blueprint(web, url_prefix = '%s/' % url_base)
app.register_blueprint(api, url_prefix = '%s/%s/' % (url_base, api_key))
# Some logging and fire load event
try: log.info('Starting server on port %(port)s' % config)
except: pass
if fire_load: fireEventAsync('app.load')
# Go go go!
try:
app.run(**config)
except (KeyboardInterrupt, SystemExit):
raise
except:
log.error('Failed starting: %s' % traceback.format_exc())
raise