diff --git a/cps.py b/cps.py index 5bc1e854..055c0ffe 100755 --- a/cps.py +++ b/cps.py @@ -10,44 +10,12 @@ sys.path.append(base_path) sys.path.append(os.path.join(base_path, 'cps')) sys.path.append(os.path.join(base_path, 'vendor')) -from cps import web -try: - from gevent.pywsgi import WSGIServer - gevent_present = True -except ImportError: - from tornado.wsgi import WSGIContainer - from tornado.httpserver import HTTPServer - from tornado.ioloop import IOLoop - gevent_present = False +from cps.server import Server if __name__ == '__main__': - if gevent_present: - web.app.logger.info('Attempting to start gevent') - web.start_gevent() - else: - web.app.logger.info('Starting Tornado webserver') - # Max Buffersize set to 200MB - if web.ub.config.get_config_certfile() and web.ub.config.get_config_keyfile(): - ssl={"certfile": web.ub.config.get_config_certfile(), - "keyfile": web.ub.config.get_config_keyfile()} - else: - ssl=None - http_server = HTTPServer(WSGIContainer(web.app), - max_buffer_size = 209700000, - ssl_options=ssl) - http_server.listen(web.ub.config.config_port) - IOLoop.instance().start() - IOLoop.instance().close(True) - - if web.helper.global_task == 0: - web.app.logger.info("Performing restart of Calibre-web") - if os.name == 'nt': - arguments = ["\"" + sys.executable + "\""] - for e in sys.argv: - arguments.append("\"" + e + "\"") - os.execv(sys.executable, arguments) - else: - os.execl(sys.executable, sys.executable, *sys.argv) - else: - web.app.logger.info("Performing shutdown of Calibre-web") - sys.exit(0) + Server.startServer() + + + + + diff --git a/cps/helper.py b/cps/helper.py index 3cc93262..cdc836d5 100755 --- a/cps/helper.py +++ b/cps/helper.py @@ -36,12 +36,12 @@ import threading import shutil import requests import zipfile -from tornado.ioloop import IOLoop try: import gdriveutils as gd except ImportError: pass import web +import server try: import unidecode @@ -50,7 +50,6 @@ except ImportError: use_unidecode = False # Global variables -global_task = None updater_thread = None RET_SUCCESS = 1 @@ -388,7 +387,6 @@ class Updater(threading.Thread): self.status = 0 def run(self): - global global_task self.status = 1 r = requests.get('https://api.github.com/repos/janeczku/calibre-web/zipball/master', stream=True) fname = re.findall("filename=(.+)", r.headers['content-disposition'])[0] @@ -400,19 +398,13 @@ class Updater(threading.Thread): self.status = 4 self.update_source(os.path.join(tmp_dir, os.path.splitext(fname)[0]), ub.config.get_main_dir) self.status = 5 - global_task = 0 db.session.close() db.engine.dispose() ub.session.close() ub.engine.dispose() self.status = 6 - - if web.gevent_server: - web.gevent_server.stop() - else: - # stop tornado server - server = IOLoop.instance() - server.add_callback(server.stop) + server.Server.setRestartTyp(True) + server.Server.stopServer() self.status = 7 def get_update_status(self): diff --git a/cps/server.py b/cps/server.py new file mode 100644 index 00000000..b84c71dc --- /dev/null +++ b/cps/server.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + + +from socket import error as SocketError +import sys +import os +try: + from gevent.pywsgi import WSGIServer + from gevent import monkey + from gevent.pool import Pool + from gevent import __version__ as geventVersion + gevent_present = True +except ImportError: + from tornado.wsgi import WSGIContainer + from tornado.httpserver import HTTPServer + from tornado.ioloop import IOLoop + from tornado import version as tornadoVersion + gevent_present = False + +import web + + +class server: + + wsgiserver = None + restart= False + + def __init__(self): + pass + + def start_gevent(self): + try: + ssl_args = dict() + if web.ub.config.get_config_certfile() and web.ub.config.get_config_keyfile(): + ssl_args = {"certfile": web.ub.config.get_config_certfile(), + "keyfile": web.ub.config.get_config_keyfile()} + if os.name == 'nt': + self.wsgiserver= WSGIServer(('0.0.0.0', web.ub.config.config_port), web.app, spawn=Pool(), **ssl_args) + else: + self.wsgiserver = WSGIServer(('', web.ub.config.config_port), web.app, spawn=Pool(), **ssl_args) + self.wsgiserver.serve_forever() + + except SocketError: + web.app.logger.info('Unable to listen on \'\', trying on IPv4 only...') + self.wsgiserver = WSGIServer(('0.0.0.0', web.ub.config.config_port), web.app, spawn=Pool(), **ssl_args) + self.wsgiserver.serve_forever() + except: + pass + + def startServer(self): + if gevent_present: + web.app.logger.info('Starting Gevent server') + # leave subprocess out to allow forking for fetchers and processors + monkey.patch_all(subprocess=False) + self.start_gevent() + else: + web.app.logger.info('Starting Tornado server') + if web.ub.config.get_config_certfile() and web.ub.config.get_config_keyfile(): + ssl={"certfile": web.ub.config.get_config_certfile(), + "keyfile": web.ub.config.get_config_keyfile()} + else: + ssl=None + # Max Buffersize set to 200MB + http_server = HTTPServer(WSGIContainer(web.app), + max_buffer_size = 209700000, + ssl_options=ssl) + http_server.listen(web.ub.config.config_port) + self.wsgiserver=IOLoop.instance() + self.wsgiserver.start() # wait for stop signal + self.wsgiserver.close(True) + + if self.restart == True: + web.app.logger.info("Performing restart of Calibre-web") + if os.name == 'nt': + arguments = ["\"" + sys.executable + "\""] + for e in sys.argv: + arguments.append("\"" + e + "\"") + os.execv(sys.executable, arguments) + else: + os.execl(sys.executable, sys.executable, *sys.argv) + else: + web.app.logger.info("Performing shutdown of Calibre-web") + sys.exit(0) + + def setRestartTyp(self,starttyp): + self.restart=starttyp + + def stopServer(self): + if gevent_present: + self.wsgiserver.close() + else: + self.wsgiserver.add_callback(self.wsgiserver.stop) + + def getNameVersion(self): + if gevent_present: + return {'gevent':geventVersion} + else: + return {'tornado':tornadoVersion} + + +# Start Instance of Server +Server=server() diff --git a/cps/templates/stats.html b/cps/templates/stats.html index 7be8f613..4db0f3f2 100644 --- a/cps/templates/stats.html +++ b/cps/templates/stats.html @@ -38,6 +38,18 @@ Python {{versions['PythonVersion']}} + {% if 'tornado' in versions %} + + Tornado web server + v{{versions['tornado']}} + + {% endif %} + {% if 'gevent' in versions %} + + Gevent web server + v{{versions['gevent']}} + + {% endif %} Kindlegen {{versions['KindlegenVersion']}} @@ -70,10 +82,6 @@ Flask Principal v{{versions['flask_principal']}} - - Tornado web server - v{{versions['tornado']}} - ISO639 Languages v{{versions['iso639']}} diff --git a/cps/web.py b/cps/web.py index 802fa971..90a1e6fc 100755 --- a/cps/web.py +++ b/cps/web.py @@ -71,15 +71,12 @@ import subprocess import re import db from shutil import move, copyfile -from tornado.ioloop import IOLoop import shutil import gdriveutils import tempfile import hashlib from redirect import redirect_back, is_safe_url -from tornado import version as tornadoVersion -from socket import error as SocketError try: from urllib.parse import quote @@ -93,13 +90,13 @@ except ImportError: from flask_login.__about__ import __version__ as flask_loginVersion import time +import server current_milli_time = lambda: int(round(time.time() * 1000)) # Global variables gdrive_watch_callback_token = 'target=calibreweb-watch_files' -global_task = None ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'epub', 'mobi', 'azw', 'azw3', 'cbr', 'cbz', 'cbt', 'djvu', 'prc', 'doc', 'docx', 'fb2']) @@ -218,8 +215,6 @@ app = (Flask(__name__)) app.wsgi_app = ReverseProxied(app.wsgi_app) cache_buster.init_cache_busting(app) -gevent_server = None - formatter = logging.Formatter( "[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s") file_handler = RotatingFileHandler(config.get_config_logfile(), maxBytes=50000, backupCount=2) @@ -1471,7 +1466,8 @@ def stats(): versions['flask'] = flaskVersion versions['flasklogin'] = flask_loginVersion versions['flask_principal'] = flask_principalVersion - versions['tornado'] = tornadoVersion + versions.update(server.Server.getNameVersion()) + # versions['tornado'] = tornadoVersion versions['iso639'] = iso639Version versions['requests'] = requests.__version__ versions['pysqlite'] = db.engine.dialect.dbapi.version @@ -1640,9 +1636,7 @@ def on_received_watch_confirmation(): @login_required @admin_required def shutdown(): - # global global_task task = int(request.args.get("parameter").strip()) - helper.global_task = task if task == 1 or task == 0: # valid commandos received # close all database connections db.session.close() @@ -1650,15 +1644,15 @@ def shutdown(): ub.session.close() ub.engine.dispose() # stop gevent server - # gevent_server.stop() - # stop tornado server - server = IOLoop.instance() - server.add_callback(server.stop) + showtext = {} if task == 0: showtext['text'] = _(u'Server restarted, please reload page') + server.Server.setRestartTyp(True) else: showtext['text'] = _(u'Performing shutdown of server, please close window') + server.Server.setRestartTyp(False) + server.Server.stopServer() return json.dumps(showtext) else: if task == 2: @@ -2498,7 +2492,6 @@ def basic_configuration(): def configuration_helper(origin): - # global global_task reboot_required = False gdriveError=None db_change = False @@ -2705,10 +2698,9 @@ def configuration_helper(origin): # db.engine.dispose() # ToDo verify correct ub.session.close() ub.engine.dispose() - # stop tornado server - server = IOLoop.instance() - server.add_callback(server.stop) - helper.global_task = 0 + # stop Server + server.Server.setRestartTyp(True) + server.Server.stopServer() app.logger.info('Reboot required, restarting') if origin: success = True @@ -3386,22 +3378,3 @@ def upload(): else: return redirect(url_for("index")) -def start_gevent(): - from gevent.pywsgi import WSGIServer - global gevent_server - try: - ssl_args=dict() - if ub.config.get_config_certfile() and ub.config.get_config_keyfile(): - ssl_args = {"certfile": ub.config.get_config_certfile(), - "keyfile": ub.config.get_config_keyfile()} - if os.name == 'nt': - gevent_server = WSGIServer(('0.0.0.0', ub.config.config_port), app, **ssl_args) - else: - gevent_server = WSGIServer(('', ub.config.config_port), app, **ssl_args) - gevent_server.serve_forever() - except SocketError: - app.logger.info('Unable to listen on \'\', trying on IPv4 only...') - gevent_server = WSGIServer(('0.0.0.0', ub.config.config_port), app, **ssl_args) - gevent_server.serve_forever() - except: - pass