Improved displaying of username and task title in tasks

This commit is contained in:
Ozzie Isaacs 2021-08-27 14:27:35 +02:00
parent e615073893
commit 91e6d94c83
9 changed files with 62 additions and 40 deletions

1
cps.py
View File

@ -70,7 +70,6 @@ def main():
app.register_blueprint(shelf) app.register_blueprint(shelf)
app.register_blueprint(admi) app.register_blueprint(admi)
app.register_blueprint(remotelogin) app.register_blueprint(remotelogin)
# if config.config_use_google_drive:
app.register_blueprint(gdrive) app.register_blueprint(gdrive)
app.register_blueprint(editbook) app.register_blueprint(editbook)
if kobo_available: if kobo_available:

View File

@ -37,6 +37,11 @@ from . import config_sql, logger, cache_buster, cli, ub, db
from .reverseproxy import ReverseProxied from .reverseproxy import ReverseProxied
from .server import WebServer from .server import WebServer
try:
import lxml
lxml_present = True
except ImportError:
lxml_present = False
mimetypes.init() mimetypes.init()
mimetypes.add_type('application/xhtml+xml', '.xhtml') mimetypes.add_type('application/xhtml+xml', '.xhtml')
@ -90,6 +95,16 @@ db.CalibreDB.setup_db(config.config_calibre_dir, cli.settingspath)
calibre_db = db.CalibreDB() calibre_db = db.CalibreDB()
def create_app(): def create_app():
if sys.version_info < (3, 0):
log.info(
'*** Python2 is EOL since end of 2019, this version of Calibre-Web is no longer supporting Python2, please update your installation to Python3 ***')
print(
'*** Python2 is EOL since end of 2019, this version of Calibre-Web is no longer supporting Python2, please update your installation to Python3 ***')
sys.exit(5)
if not lxml_present:
log.info('*** "lxml" is needed for calibre-web to run. Please install it using pip: "pip install lxml" ***')
print('*** "lxml" is needed for calibre-web to run. Please install it using pip: "pip install lxml" ***')
sys.exit(6)
app.wsgi_app = ReverseProxied(app.wsgi_app) app.wsgi_app = ReverseProxied(app.wsgi_app)
# For python2 convert path to unicode # For python2 convert path to unicode
if sys.version_info < (3, 0): if sys.version_info < (3, 0):
@ -99,12 +114,8 @@ def create_app():
if os.environ.get('FLASK_DEBUG'): if os.environ.get('FLASK_DEBUG'):
cache_buster.init_cache_busting(app) cache_buster.init_cache_busting(app)
log.info('Starting Calibre Web...') log.info('Starting Calibre Web...')
if sys.version_info < (3, 0):
log.info('*** Python2 is EOL since end of 2019, this version of Calibre-Web is no longer supporting Python2, please update your installation to Python3 ***')
print('*** Python2 is EOL since end of 2019, this version of Calibre-Web is no longer supporting Python2, please update your installation to Python3 ***')
sys.exit(5)
Principal(app) Principal(app)
lm.init_app(app) lm.init_app(app)
app.secret_key = os.getenv('SECRET_KEY', config_sql.get_flask_session_key(ub.session)) app.secret_key = os.getenv('SECRET_KEY', config_sql.get_flask_session_key(ub.session))

View File

@ -26,7 +26,11 @@ from datetime import datetime
import json import json
from shutil import copyfile from shutil import copyfile
from uuid import uuid4 from uuid import uuid4
from lxml.html.clean import clean_html try:
from lxml.html.clean import clean_html
except ImportError:
pass
# Improve this to check if scholarly is available in a global way, like other pythonic libraries # Improve this to check if scholarly is available in a global way, like other pythonic libraries
try: try:

View File

@ -38,6 +38,7 @@ from flask_login import current_user
from sqlalchemy.sql.expression import true, false, and_, text, func from sqlalchemy.sql.expression import true, false, and_, text, func
from werkzeug.datastructures import Headers from werkzeug.datastructures import Headers
from werkzeug.security import generate_password_hash from werkzeug.security import generate_password_hash
from markupsafe import escape
try: try:
from urllib.parse import quote from urllib.parse import quote
@ -97,10 +98,11 @@ def convert_book_format(book_id, calibrepath, old_book_format, new_book_format,
settings['body'] = _(u'This e-mail has been sent via Calibre-Web.') settings['body'] = _(u'This e-mail has been sent via Calibre-Web.')
else: else:
settings = dict() settings = dict()
txt = (u"%s -> %s: %s" % ( link = '<a href="{}">{}</a>"'.format(url_for('web.show_book', book_id=book.id), escape(book.title)) # prevent xss
txt = u"{} -> {}: {}".format(
old_book_format, old_book_format,
new_book_format, new_book_format,
"<a href=\"" + url_for('web.show_book', book_id=book.id) + "\">" + book.title + "</a>")) link)
settings['old_book_format'] = old_book_format settings['old_book_format'] = old_book_format
settings['new_book_format'] = new_book_format settings['new_book_format'] = new_book_format
WorkerThread.add(user_id, TaskConvert(file_path, book.id, txt, settings, kindle_mail, user_id)) WorkerThread.add(user_id, TaskConvert(file_path, book.id, txt, settings, kindle_mail, user_id))
@ -778,7 +780,7 @@ def render_task_status(tasklist):
ret['taskMessage'] = "{}: {}".format(_(task.name), task.message) ret['taskMessage'] = "{}: {}".format(_(task.name), task.message)
ret['progress'] = "{} %".format(int(task.progress * 100)) ret['progress'] = "{} %".format(int(task.progress * 100))
ret['user'] = user ret['user'] = escape(user) # prevent xss
renderedtasklist.append(ret) renderedtasklist.append(ret)
return renderedtasklist return renderedtasklist

View File

@ -28,7 +28,6 @@ import mimetypes
from uuid import uuid4 from uuid import uuid4
from babel.dates import format_date from babel.dates import format_date
from flask_babel import gettext as _
from flask import Blueprint, request, url_for from flask import Blueprint, request, url_for
from flask_babel import get_locale from flask_babel import get_locale
from flask_login import current_user from flask_login import current_user

View File

@ -20,6 +20,15 @@ function getPath() {
var jsFileLocation = $("script[src*=jquery]").attr("src"); // the js file path var jsFileLocation = $("script[src*=jquery]").attr("src"); // the js file path
return jsFileLocation.substr(0, jsFileLocation.search("/static/js/libs/jquery.min.js")); // the js folder path return jsFileLocation.substr(0, jsFileLocation.search("/static/js/libs/jquery.min.js")); // the js folder path
} }
function elementSorter(a, b) {
a = +a.slice(0, -2);
b = +b.slice(0, -2);
if (a > b) return 1;
if (a < b) return -1;
return 0;
}
// Generic control/related handler to show/hide fields based on a checkbox' value // Generic control/related handler to show/hide fields based on a checkbox' value
// e.g. // e.g.
// <input type="checkbox" data-control="stuff-to-show"> // <input type="checkbox" data-control="stuff-to-show">
@ -714,3 +723,4 @@ $(function() {
}); });
}); });
}); });

View File

@ -22,6 +22,26 @@ var selections = [];
var reload = false; var reload = false;
$(function() { $(function() {
$('#tasktable').bootstrapTable({
formatNoMatches: function () {
return '';
},
striped: true
});
if ($('#tasktable').length) {
setInterval(function () {
$.ajax({
method: "get",
url: getPath() + "/ajax/emailstat",
async: true,
timeout: 900,
success: function (data) {
$('#table').bootstrapTable("load", data);
}
});
}, 2000);
}
$("#books-table").on("check.bs.table check-all.bs.table uncheck.bs.table uncheck-all.bs.table", $("#books-table").on("check.bs.table check-all.bs.table uncheck.bs.table uncheck-all.bs.table",
function (e, rowsAfter, rowsBefore) { function (e, rowsAfter, rowsBefore) {
var rows = rowsAfter; var rows = rowsAfter;

View File

@ -5,7 +5,7 @@
{% block body %} {% block body %}
<div class="discover"> <div class="discover">
<h2>{{_('Tasks')}}</h2> <h2>{{_('Tasks')}}</h2>
<table class="table table-no-bordered" id="table" data-url="{{ url_for('web.get_email_status_json') }}" data-sort-name="starttime" data-sort-order="asc"> <table class="table table-no-bordered" id="tasktable" data-url="{{ url_for('web.get_email_status_json') }}" data-sort-name="starttime" data-sort-order="asc">
<thead> <thead>
<tr> <tr>
{% if g.user.role_admin() %} {% if g.user.role_admin() %}
@ -27,32 +27,9 @@
{% endblock %} {% endblock %}
{% block js %} {% block js %}
<script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table.min.js') }}"></script> <script src="{{ url_for('static', filename='js/libs/bootstrap-table/bootstrap-table.min.js') }}"></script>
<script> <script src="{{ url_for('static', filename='js/table.js') }}"></script>
// ToDo: Move to js file <script>
$('#table').bootstrapTable({ // ToDo: Move to js file
formatNoMatches: function () { </script>
return '';
},
striped: true
});
setInterval(function() {
$.ajax({
method:"get",
url: "{{ url_for('web.get_email_status_json')}}",
async: true,
timeout: 900,
success:function(data){
$('#table').bootstrapTable("load", data);
}
});
}, 1000);
function elementSorter(a, b) {
a = +a.slice(0, -2);
b = +b.slice(0, -2);
if (a > b) return 1;
if (a < b) return -1;
return 0;
}
</script>
{% endblock %} {% endblock %}

View File

@ -84,7 +84,7 @@ except ImportError:
@app.after_request @app.after_request
def add_security_headers(resp): def add_security_headers(resp):
# resp.headers['Content-Security-Policy']= "script-src 'self' https://www.googleapis.com https://api.douban.com https://comicvine.gamespot.com;" resp.headers['Content-Security-Policy']= "script-src 'self'" # https://www.googleapis.com https://api.douban.com https://comicvine.gamespot.com;"
resp.headers['X-Content-Type-Options'] = 'nosniff' resp.headers['X-Content-Type-Options'] = 'nosniff'
resp.headers['X-Frame-Options'] = 'SAMEORIGIN' resp.headers['X-Frame-Options'] = 'SAMEORIGIN'
resp.headers['X-XSS-Protection'] = '1; mode=block' resp.headers['X-XSS-Protection'] = '1; mode=block'