forked from CouchPotato/CouchPotatoServer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
CouchPotato.py
executable file
·162 lines (129 loc) · 4.55 KB
/
CouchPotato.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#!/usr/bin/env python
from __future__ import print_function
from logging import handlers
from os.path import dirname
import logging
import os
import select
import signal
import socket
import subprocess
import sys
import traceback
# Root path
base_path = dirname(os.path.abspath(__file__))
# Insert local directories into path
sys.path.insert(0, os.path.join(base_path, 'libs'))
from couchpotato.environment import Env
from couchpotato.core.helpers.variable import getDataDir, removePyc
# Remove pyc files before dynamic load (sees .pyc files regular .py modules)
removePyc(base_path)
class Loader(object):
do_restart = False
def __init__(self):
# Get options via arg
from couchpotato.runner import getOptions
self.options = getOptions(sys.argv[1:])
# Load settings
settings = Env.get('settings')
settings.setFile(self.options.config_file)
# Create data dir if needed
if self.options.data_dir:
self.data_dir = self.options.data_dir
else:
self.data_dir = os.path.expanduser(Env.setting('data_dir'))
if self.data_dir == '':
self.data_dir = getDataDir()
if not os.path.isdir(self.data_dir):
os.makedirs(self.data_dir)
# Create logging dir
self.log_dir = os.path.join(self.data_dir, 'logs')
if not os.path.isdir(self.log_dir):
os.makedirs(self.log_dir)
# Logging
from couchpotato.core.logger import CPLog
self.log = CPLog(__name__)
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s', '%H:%M:%S')
hdlr = handlers.RotatingFileHandler(os.path.join(self.log_dir, 'error.log'), 'a', 500000, 10)
hdlr.setLevel(logging.CRITICAL)
hdlr.setFormatter(formatter)
self.log.logger.addHandler(hdlr)
def addSignals(self):
signal.signal(signal.SIGINT, self.onExit)
signal.signal(signal.SIGTERM, lambda signum, stack_frame: sys.exit(1))
from couchpotato.core.event import addEvent
addEvent('app.do_shutdown', self.setRestart)
def setRestart(self, restart):
self.do_restart = restart
return True
def onExit(self, signal, frame):
from couchpotato.core.event import fireEvent
fireEvent('app.shutdown', single=True)
def run(self):
self.addSignals()
from couchpotato.runner import runCouchPotato
runCouchPotato(self.options, base_path, sys.argv[1:], data_dir = self.data_dir, log_dir = self.log_dir, Env = Env)
if self.do_restart:
self.restart()
def restart(self):
try:
# remove old pidfile first
try:
if self.runAsDaemon():
try:
self.daemon.stop()
except:
pass
except:
self.log.critical(traceback.format_exc())
# Release log files and shutdown logger
logging.shutdown()
args = [sys.executable] + [os.path.join(base_path, os.path.basename(__file__))] + sys.argv[1:]
subprocess.Popen(args)
except:
self.log.critical(traceback.format_exc())
def daemonize(self):
if self.runAsDaemon():
try:
from daemon import Daemon
self.daemon = Daemon(self.options.pid_file)
self.daemon.daemonize()
except SystemExit:
raise
except:
self.log.critical(traceback.format_exc())
def runAsDaemon(self):
return self.options.daemon and self.options.pid_file
if __name__ == '__main__':
l = None
try:
l = Loader()
l.daemonize()
l.run()
except KeyboardInterrupt:
pass
except select.error:
pass
except SystemExit:
raise
except socket.error as e:
# log when socket receives SIGINT, but continue.
# previous code would have skipped over other types of IO errors too.
nr, msg = e
if nr != 4:
try:
l.log.critical(traceback.format_exc())
except:
print(traceback.format_exc())
raise
except:
try:
# if this fails we will have two tracebacks
# one for failing to log, and one for the exception that got us here.
if l:
l.log.critical(traceback.format_exc())
else:
print(traceback.format_exc())
except:
print(traceback.format_exc())
raise