mirror of
https://github.com/aaPanel/aaPanel.git
synced 2026-08-17 21:25:47 +02:00
2.The page is displayed when the adjustment panel is wrong 3.App store add common plug-in display 4.Adjust the sessionid name to a non-fixed name 5.Panel CSRF defense mechanism covers panel websocket communication 6.Adjust the font size of the panel list 7.Adjust the panel pop-up window (add a close button to cancel the automatic closing time) 8.Optimize the front/back end of the file manager 9.Add the entrance of the MailServer Rspamd 10.Refactor the debug module 11.Other known bug fixes
152 lines
4.9 KiB
Python
152 lines
4.9 KiB
Python
#!/www/server/panel/pyenv/bin/python
|
||
#coding: utf-8
|
||
# +-------------------------------------------------------------------
|
||
# | 宝塔Linux面板
|
||
# +-------------------------------------------------------------------
|
||
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
|
||
# +-------------------------------------------------------------------
|
||
# | Author: hwliang <hwl@bt.cn>
|
||
# +-------------------------------------------------------------------
|
||
from gevent import monkey
|
||
monkey.patch_all()
|
||
import os,sys,ssl
|
||
_PATH = '/www/server/panel'
|
||
os.chdir(_PATH)
|
||
if not 'class/' in sys.path:
|
||
sys.path.insert(0,'class/')
|
||
from BTPanel import app,sys,public
|
||
is_debug = os.path.exists('data/debug.pl')
|
||
|
||
if is_debug:
|
||
import pyinotify,time,logging,re
|
||
logging.basicConfig(level=logging.DEBUG,format="[%(asctime)s][%(levelname)s] - %(message)s")
|
||
logger = logging.getLogger()
|
||
|
||
class PanelEventHandler(pyinotify.ProcessEvent):
|
||
_exts = ['py','html','BT-Panel','so']
|
||
_explude_patts = [
|
||
re.compile('{}/plugin/.+'.format(_PATH)),
|
||
re.compile('{}/(tmp|temp)/.+'.format(_PATH))
|
||
]
|
||
_lsat_time = 0
|
||
|
||
|
||
def is_ext(self,filename):
|
||
fname = os.path.basename(filename)
|
||
result = fname.split('.')[-1] in self._exts
|
||
if not result: return False
|
||
for e in self._explude_patts:
|
||
if e.match(filename): return False
|
||
return True
|
||
|
||
def panel_reload(self,filename,in_type):
|
||
stime = time.time()
|
||
if stime - self._lsat_time < 2:
|
||
return
|
||
self._lsat_time = stime
|
||
logger.debug('File detected: {} -> {}'.format(filename,in_type))
|
||
|
||
fname = os.path.basename(filename)
|
||
if fname in ['task.py','BT-Task']:
|
||
logger.debug('Background task...')
|
||
public.ExecShell("{} {}/BT-Task".format(public.get_python_bin(),_PATH))
|
||
logger.debug('Background task started!')
|
||
else:
|
||
logger.debug('Restarting panel...')
|
||
public.ExecShell("bash {}/init.sh reload &>/dev/null &".format(_PATH))
|
||
|
||
def process_IN_CREATE(self, event):
|
||
if not self.is_ext(event.pathname): return
|
||
self.panel_reload(event.pathname,'[Create]')
|
||
|
||
def process_IN_DELETE(self,event):
|
||
if not self.is_ext(event.pathname): return
|
||
self.panel_reload(event.pathname,'[Delete]')
|
||
|
||
def process_IN_MODIFY(self,event):
|
||
|
||
if not self.is_ext(event.pathname): return
|
||
self.panel_reload(event.pathname,'[Modify]')
|
||
|
||
def debug_event():
|
||
logger.debug('Launch the panel in debug mode')
|
||
logger.debug('Listening port:0.0.0.0:{}'.format(public.readFile('data/port.pl')))
|
||
|
||
event = PanelEventHandler()
|
||
watchManager = pyinotify.WatchManager()
|
||
mode = pyinotify.IN_CREATE | pyinotify.IN_DELETE | pyinotify.IN_MODIFY
|
||
watchManager.add_watch(_PATH, mode, auto_add=True, rec=True)
|
||
notifier = pyinotify.Notifier(watchManager, event)
|
||
notifier.loop()
|
||
|
||
if __name__ == '__main__':
|
||
pid_file = "{}/logs/panel.pid".format(_PATH)
|
||
if os.path.exists(pid_file):
|
||
public.ExecShell("kill -9 {}".format(public.readFile(pid_file)))
|
||
pid = os.fork()
|
||
if pid: sys.exit(0)
|
||
|
||
os.setsid()
|
||
|
||
_pid = os.fork()
|
||
if _pid:
|
||
public.writeFile(pid_file,str(_pid))
|
||
sys.exit(0)
|
||
|
||
sys.stdout.flush()
|
||
sys.stderr.flush()
|
||
|
||
f = open('data/port.pl')
|
||
PORT = int(f.read())
|
||
HOST = '0.0.0.0'
|
||
if os.path.exists('data/ipv6.pl'):
|
||
HOST = "0:0:0:0:0:0:0:0"
|
||
f.close()
|
||
|
||
|
||
keyfile = 'ssl/privateKey.pem'
|
||
certfile = 'ssl/certificate.pem'
|
||
is_ssl = False
|
||
if os.path.exists('data/ssl.pl') and os.path.exists(keyfile) and os.path.exists(certfile):
|
||
is_ssl = True
|
||
|
||
if not is_ssl or is_debug:
|
||
err_f = open('logs/error.log','a+')
|
||
os.dup2(err_f.fileno(),sys.stderr.fileno())
|
||
err_f.close()
|
||
|
||
import threading
|
||
import jobs
|
||
|
||
job = threading.Thread(target=jobs.control_init)
|
||
job.setDaemon(True)
|
||
job.start()
|
||
|
||
|
||
if is_ssl:
|
||
ssl_context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
|
||
ssl_context.load_cert_chain(certfile=certfile,keyfile=keyfile)
|
||
ssl_context.options = (ssl.OP_NO_SSLv2 | ssl.OP_NO_SSLv3 | ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1)
|
||
ssl_context.set_ciphers("ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE")
|
||
|
||
|
||
from gevent.pywsgi import WSGIServer
|
||
from geventwebsocket.handler import WebSocketHandler
|
||
|
||
if is_ssl:
|
||
http_server = WSGIServer((HOST, PORT), app,handler_class=WebSocketHandler,ssl_context = ssl_context)
|
||
else:
|
||
http_server = WSGIServer((HOST, PORT), app,handler_class=WebSocketHandler)
|
||
|
||
if is_debug:
|
||
try:
|
||
dev = threading.Thread(target=debug_event)
|
||
dev.setDaemon(True)
|
||
dev.start()
|
||
except:
|
||
pass
|
||
|
||
http_server.serve_forever()
|
||
|
||
|