mirror of
https://github.com/janeczku/calibre-web
synced 2024-12-25 09:30:31 +00:00
New restart routine for executable files
Fix log in updater New source option updater available
This commit is contained in:
parent
6137fdeb33
commit
e6fb460071
@ -48,6 +48,11 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
flask_danceVersion = None
|
flask_danceVersion = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
from greenlet import __version__ as greenlet_Version
|
||||||
|
except ImportError:
|
||||||
|
greenlet_Version = None
|
||||||
|
|
||||||
from . import services
|
from . import services
|
||||||
|
|
||||||
about = flask.Blueprint('about', __name__)
|
about = flask.Blueprint('about', __name__)
|
||||||
@ -77,7 +82,8 @@ _VERSIONS = OrderedDict(
|
|||||||
python_LDAP = services.ldapVersion if bool(services.ldapVersion) else None,
|
python_LDAP = services.ldapVersion if bool(services.ldapVersion) else None,
|
||||||
Goodreads = u'installed' if bool(services.goodreads_support) else None,
|
Goodreads = u'installed' if bool(services.goodreads_support) else None,
|
||||||
jsonschema = services.SyncToken.__version__ if bool(services.SyncToken) else None,
|
jsonschema = services.SyncToken.__version__ if bool(services.SyncToken) else None,
|
||||||
flask_dance = flask_danceVersion
|
flask_dance = flask_danceVersion,
|
||||||
|
greenlet = greenlet_Version
|
||||||
)
|
)
|
||||||
_VERSIONS.update(uploader.get_versions())
|
_VERSIONS.update(uploader.get_versions())
|
||||||
|
|
||||||
|
70
cps/admin.py
70
cps/admin.py
@ -56,7 +56,8 @@ log = logger.create()
|
|||||||
feature_support = {
|
feature_support = {
|
||||||
'ldap': bool(services.ldap),
|
'ldap': bool(services.ldap),
|
||||||
'goodreads': bool(services.goodreads_support),
|
'goodreads': bool(services.goodreads_support),
|
||||||
'kobo': bool(services.kobo)
|
'kobo': bool(services.kobo),
|
||||||
|
'updater': constants.UPDATER_AVAILABLE
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -1264,8 +1265,11 @@ def download_debug():
|
|||||||
@login_required
|
@login_required
|
||||||
@admin_required
|
@admin_required
|
||||||
def get_update_status():
|
def get_update_status():
|
||||||
log.info(u"Update status requested")
|
if feature_support['updater']:
|
||||||
return updater_thread.get_available_updates(request.method, locale=get_locale())
|
log.info(u"Update status requested")
|
||||||
|
return updater_thread.get_available_updates(request.method, locale=get_locale())
|
||||||
|
else:
|
||||||
|
return ''
|
||||||
|
|
||||||
|
|
||||||
@admi.route("/get_updater_status", methods=['GET', 'POST'])
|
@admi.route("/get_updater_status", methods=['GET', 'POST'])
|
||||||
@ -1273,35 +1277,37 @@ def get_update_status():
|
|||||||
@admin_required
|
@admin_required
|
||||||
def get_updater_status():
|
def get_updater_status():
|
||||||
status = {}
|
status = {}
|
||||||
if request.method == "POST":
|
if feature_support['updater']:
|
||||||
commit = request.form.to_dict()
|
if request.method == "POST":
|
||||||
if "start" in commit and commit['start'] == 'True':
|
commit = request.form.to_dict()
|
||||||
text = {
|
if "start" in commit and commit['start'] == 'True':
|
||||||
"1": _(u'Requesting update package'),
|
text = {
|
||||||
"2": _(u'Downloading update package'),
|
"1": _(u'Requesting update package'),
|
||||||
"3": _(u'Unzipping update package'),
|
"2": _(u'Downloading update package'),
|
||||||
"4": _(u'Replacing files'),
|
"3": _(u'Unzipping update package'),
|
||||||
"5": _(u'Database connections are closed'),
|
"4": _(u'Replacing files'),
|
||||||
"6": _(u'Stopping server'),
|
"5": _(u'Database connections are closed'),
|
||||||
"7": _(u'Update finished, please press okay and reload page'),
|
"6": _(u'Stopping server'),
|
||||||
"8": _(u'Update failed:') + u' ' + _(u'HTTP Error'),
|
"7": _(u'Update finished, please press okay and reload page'),
|
||||||
"9": _(u'Update failed:') + u' ' + _(u'Connection error'),
|
"8": _(u'Update failed:') + u' ' + _(u'HTTP Error'),
|
||||||
"10": _(u'Update failed:') + u' ' + _(u'Timeout while establishing connection'),
|
"9": _(u'Update failed:') + u' ' + _(u'Connection error'),
|
||||||
"11": _(u'Update failed:') + u' ' + _(u'General error'),
|
"10": _(u'Update failed:') + u' ' + _(u'Timeout while establishing connection'),
|
||||||
"12": _(u'Update failed:') + u' ' + _(u'Update File Could Not be Saved in Temp Dir')
|
"11": _(u'Update failed:') + u' ' + _(u'General error'),
|
||||||
}
|
"12": _(u'Update failed:') + u' ' + _(u'Update File Could Not be Saved in Temp Dir')
|
||||||
status['text'] = text
|
}
|
||||||
updater_thread.status = 0
|
status['text'] = text
|
||||||
updater_thread.resume()
|
updater_thread.status = 0
|
||||||
status['status'] = updater_thread.get_update_status()
|
updater_thread.resume()
|
||||||
elif request.method == "GET":
|
status['status'] = updater_thread.get_update_status()
|
||||||
try:
|
elif request.method == "GET":
|
||||||
status['status'] = updater_thread.get_update_status()
|
try:
|
||||||
if status['status'] == -1:
|
status['status'] = updater_thread.get_update_status()
|
||||||
status['status'] = 7
|
if status['status'] == -1:
|
||||||
except Exception:
|
status['status'] = 7
|
||||||
status['status'] = 11
|
except Exception:
|
||||||
return json.dumps(status)
|
status['status'] = 11
|
||||||
|
return json.dumps(status)
|
||||||
|
return ''
|
||||||
|
|
||||||
|
|
||||||
@admi.route('/import_ldap_users')
|
@admi.route('/import_ldap_users')
|
||||||
|
@ -23,6 +23,7 @@ from collections import namedtuple
|
|||||||
|
|
||||||
# if installed via pip this variable is set to true
|
# if installed via pip this variable is set to true
|
||||||
HOME_CONFIG = False
|
HOME_CONFIG = False
|
||||||
|
UPDATER_AVAILABLE = True
|
||||||
|
|
||||||
# Base dir is parent of current file, necessary if called from different folder
|
# Base dir is parent of current file, necessary if called from different folder
|
||||||
if sys.version_info < (3, 0):
|
if sys.version_info < (3, 0):
|
||||||
|
@ -22,6 +22,7 @@ import os
|
|||||||
import errno
|
import errno
|
||||||
import signal
|
import signal
|
||||||
import socket
|
import socket
|
||||||
|
import subprocess
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from gevent.pywsgi import WSGIServer
|
from gevent.pywsgi import WSGIServer
|
||||||
@ -136,6 +137,64 @@ class WebServer(object):
|
|||||||
|
|
||||||
return sock, _readable_listen_address(*address)
|
return sock, _readable_listen_address(*address)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_args_for_reloading(self):
|
||||||
|
"""Determine how the script was executed, and return the args needed
|
||||||
|
to execute it again in a new process.
|
||||||
|
Code from https://github.com/pyload/pyload. Author GammaC0de, voulter
|
||||||
|
"""
|
||||||
|
rv = [sys.executable]
|
||||||
|
py_script = sys.argv[0]
|
||||||
|
args = sys.argv[1:]
|
||||||
|
# Need to look at main module to determine how it was executed.
|
||||||
|
__main__ = sys.modules["__main__"]
|
||||||
|
|
||||||
|
# The value of __package__ indicates how Python was called. It may
|
||||||
|
# not exist if a setuptools script is installed as an egg. It may be
|
||||||
|
# set incorrectly for entry points created with pip on Windows.
|
||||||
|
if getattr(__main__, "__package__", None) is None or (
|
||||||
|
os.name == "nt"
|
||||||
|
and __main__.__package__ == ""
|
||||||
|
and not os.path.exists(py_script)
|
||||||
|
and os.path.exists(f"{py_script}.exe")
|
||||||
|
):
|
||||||
|
# Executed a file, like "python app.py".
|
||||||
|
py_script = os.path.abspath(py_script)
|
||||||
|
|
||||||
|
if os.name == "nt":
|
||||||
|
# Windows entry points have ".exe" extension and should be
|
||||||
|
# called directly.
|
||||||
|
if not os.path.exists(py_script) and os.path.exists(f"{py_script}.exe"):
|
||||||
|
py_script += ".exe"
|
||||||
|
|
||||||
|
if (
|
||||||
|
os.path.splitext(sys.executable)[1] == ".exe"
|
||||||
|
and os.path.splitext(py_script)[1] == ".exe"
|
||||||
|
):
|
||||||
|
rv.pop(0)
|
||||||
|
|
||||||
|
rv.append(py_script)
|
||||||
|
else:
|
||||||
|
# Executed a module, like "python -m module".
|
||||||
|
if sys.argv[0] == "-m":
|
||||||
|
args = sys.argv
|
||||||
|
else:
|
||||||
|
if os.path.isfile(py_script):
|
||||||
|
# Rewritten by Python from "-m script" to "/path/to/script.py".
|
||||||
|
py_module = __main__.__package__
|
||||||
|
name = os.path.splitext(os.path.basename(py_script))[0]
|
||||||
|
|
||||||
|
if name != "__main__":
|
||||||
|
py_module += f".{name}"
|
||||||
|
else:
|
||||||
|
# Incorrectly rewritten by pydevd debugger from "-m script" to "script".
|
||||||
|
py_module = py_script
|
||||||
|
|
||||||
|
rv.extend(("-m", py_module.lstrip(".")))
|
||||||
|
|
||||||
|
rv.extend(args)
|
||||||
|
return rv
|
||||||
|
|
||||||
def _start_gevent(self):
|
def _start_gevent(self):
|
||||||
ssl_args = self.ssl_args or {}
|
ssl_args = self.ssl_args or {}
|
||||||
|
|
||||||
@ -199,11 +258,8 @@ class WebServer(object):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
log.info("Performing restart of Calibre-Web")
|
log.info("Performing restart of Calibre-Web")
|
||||||
arguments = list(sys.argv)
|
args = self._get_args_for_reloading()
|
||||||
arguments.insert(0, sys.executable)
|
subprocess.call(args, close_fds=True)
|
||||||
if os.name == 'nt':
|
|
||||||
arguments = ["\"%s\"" % a for a in arguments]
|
|
||||||
os.execv(sys.executable, arguments)
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _killServer(self, __, ___):
|
def _killServer(self, __, ___):
|
||||||
|
@ -168,9 +168,11 @@
|
|||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
{% if feature_support['updater'] %}
|
||||||
<div class="hidden" id="update_error"> <span>{{update_error}}</span></div>
|
<div class="hidden" id="update_error"> <span>{{update_error}}</span></div>
|
||||||
<div class="btn btn-primary" id="check_for_update">{{_('Check for Update')}}</div>
|
<div class="btn btn-primary" id="check_for_update">{{_('Check for Update')}}</div>
|
||||||
<div class="btn btn-primary hidden" id="perform_update" data-toggle="modal" data-target="#StatusDialog">{{_('Perform Update')}}</div>
|
<div class="btn btn-primary hidden" id="perform_update" data-toggle="modal" data-target="#StatusDialog">{{_('Perform Update')}}</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -264,7 +264,7 @@ class Updater(threading.Thread):
|
|||||||
# log_from_thread("Delete file " + item_path)
|
# log_from_thread("Delete file " + item_path)
|
||||||
os.remove(item_path)
|
os.remove(item_path)
|
||||||
except OSError:
|
except OSError:
|
||||||
logger.debug("Could not remove: %s", item_path)
|
log.debug("Could not remove: %s", item_path)
|
||||||
shutil.rmtree(source, ignore_errors=True)
|
shutil.rmtree(source, ignore_errors=True)
|
||||||
|
|
||||||
def is_venv(self):
|
def is_venv(self):
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# GDrive Integration
|
# GDrive Integration
|
||||||
google-api-python-client>=1.7.11,<1.8.0
|
google-api-python-client>=1.7.11,<1.8.0
|
||||||
gevent>=1.2.1,<20.6.0
|
gevent>20.6.0,<21.2.0
|
||||||
greenlet>=0.4.12,<0.4.17
|
greenlet>=0.4.17,<1.1.0
|
||||||
httplib2>=0.9.2,<0.18.0
|
httplib2>=0.9.2,<0.18.0
|
||||||
oauth2client>=4.0.0,<4.1.4
|
oauth2client>=4.0.0,<4.1.4
|
||||||
uritemplate>=3.0.0,<3.1.0
|
uritemplate>=3.0.0,<3.1.0
|
||||||
|
Loading…
Reference in New Issue
Block a user