mirror of
https://github.com/janeczku/calibre-web
synced 2024-10-31 23:26:20 +00:00
Update tornado to 6.2
Remove unneeded imports from jsonschema for synctoken Update optional requirements Remove invalid direction arrows in comic reader
This commit is contained in:
parent
caf69669cb
commit
885d914f18
@ -19,10 +19,8 @@
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
from base64 import b64decode, b64encode
|
from base64 import b64decode, b64encode
|
||||||
from jsonschema import validate, exceptions, __version__
|
from jsonschema import validate, exceptions
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime
|
||||||
|
|
||||||
from urllib.parse import unquote
|
|
||||||
|
|
||||||
from flask import json
|
from flask import json
|
||||||
from .. import logger
|
from .. import logger
|
||||||
|
@ -177,12 +177,31 @@ kthoom.ImageFile = function(file) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function updateDirectionButtons(){
|
||||||
|
$("#right").show();
|
||||||
|
$("#left").show();
|
||||||
|
if (currentImage == 0 ) {
|
||||||
|
if (settings.direction === 0) {
|
||||||
|
$("#left").hide();
|
||||||
|
} else {
|
||||||
|
$("#right").hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((currentImage + 1) >= Math.max(totalImages, imageFiles.length)) {
|
||||||
|
if (settings.direction === 0) {
|
||||||
|
$("#right").hide();
|
||||||
|
} else {
|
||||||
|
$("#left").hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
function initProgressClick() {
|
function initProgressClick() {
|
||||||
$("#progress").click(function(e) {
|
$("#progress").click(function(e) {
|
||||||
var offset = $(this).offset();
|
var offset = $(this).offset();
|
||||||
var x = e.pageX - offset.left;
|
var x = e.pageX - offset.left;
|
||||||
var rate = settings.direction === 0 ? x / $(this).width() : 1 - x / $(this).width();
|
var rate = settings.direction === 0 ? x / $(this).width() : 1 - x / $(this).width();
|
||||||
currentImage = Math.max(1, Math.ceil(rate * totalImages)) - 1;
|
currentImage = Math.max(1, Math.ceil(rate * totalImages)) - 1;
|
||||||
|
updateDirectionButtons();
|
||||||
updatePage();
|
updatePage();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -222,6 +241,11 @@ function loadFromArrayBuffer(ab) {
|
|||||||
|
|
||||||
// display first page if we haven't yet
|
// display first page if we haven't yet
|
||||||
if (imageFiles.length === currentImage + 1) {
|
if (imageFiles.length === currentImage + 1) {
|
||||||
|
if (settings.direction === 0) {
|
||||||
|
$("#right").show();
|
||||||
|
} else {
|
||||||
|
$("#left").show();
|
||||||
|
}
|
||||||
updatePage();
|
updatePage();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -427,6 +451,7 @@ function showPrevPage() {
|
|||||||
} else {
|
} else {
|
||||||
updatePage();
|
updatePage();
|
||||||
}
|
}
|
||||||
|
updateDirectionButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
function showNextPage() {
|
function showNextPage() {
|
||||||
@ -437,6 +462,7 @@ function showNextPage() {
|
|||||||
} else {
|
} else {
|
||||||
updatePage();
|
updatePage();
|
||||||
}
|
}
|
||||||
|
updateDirectionButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
function scrollCurrentImageIntoView() {
|
function scrollCurrentImageIntoView() {
|
||||||
@ -677,6 +703,7 @@ function init(filename) {
|
|||||||
if(["hflip", "vflip", "rotateTimes"].includes(this.name)) {
|
if(["hflip", "vflip", "rotateTimes"].includes(this.name)) {
|
||||||
reloadImages();
|
reloadImages();
|
||||||
} else if(this.name === "direction") {
|
} else if(this.name === "direction") {
|
||||||
|
updateDirectionButtons();
|
||||||
return updateProgress();
|
return updateProgress();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -726,7 +753,7 @@ function init(filename) {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
$(".mainImage").click(function(evt) {
|
$(".mainImage").click(function(evt) {
|
||||||
// Firefox does not support offsetX/Y so we have to manually calculate
|
// Firefox does not support offsetX/Y, so we have to manually calculate
|
||||||
// where the user clicked in the image.
|
// where the user clicked in the image.
|
||||||
var mainContentWidth = $("#mainContent").width();
|
var mainContentWidth = $("#mainContent").width();
|
||||||
var mainContentHeight = $("#mainContent").height();
|
var mainContentHeight = $("#mainContent").height();
|
||||||
|
@ -77,8 +77,8 @@
|
|||||||
<div id="mainContent" tabindex="-1">
|
<div id="mainContent" tabindex="-1">
|
||||||
<div id="mainText" style="display:none"></div>
|
<div id="mainText" style="display:none"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="left" class="arrow" onclick="showLeftPage()">‹</div>
|
<div id="left" class="arrow" style="display:none" onclick="showLeftPage()">‹</div>
|
||||||
<div id="right" class="arrow" onclick="showRightPage()">›</div>
|
<div id="right" class="arrow" style="display:none" onclick="showRightPage()">›</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal md-effect-1" id="settings-modal">
|
<div class="modal md-effect-1" id="settings-modal">
|
||||||
|
@ -16,15 +16,15 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
from tornado.wsgi import WSGIContainer
|
from tornado.wsgi import WSGIContainer
|
||||||
import tornado
|
import tornado
|
||||||
|
|
||||||
from tornado import escape
|
from tornado import escape
|
||||||
from tornado import httputil
|
from tornado import httputil
|
||||||
|
from tornado.ioloop import IOLoop
|
||||||
|
|
||||||
from typing import List, Tuple, Optional, Callable, Any, Dict, Text
|
from typing import List, Tuple, Optional, Callable, Any, Dict, Text
|
||||||
from types import TracebackType
|
from types import TracebackType, FunctionType
|
||||||
import typing
|
import typing
|
||||||
|
|
||||||
if typing.TYPE_CHECKING:
|
if typing.TYPE_CHECKING:
|
||||||
@ -34,61 +34,67 @@ if typing.TYPE_CHECKING:
|
|||||||
class MyWSGIContainer(WSGIContainer):
|
class MyWSGIContainer(WSGIContainer):
|
||||||
|
|
||||||
def __call__(self, request: httputil.HTTPServerRequest) -> None:
|
def __call__(self, request: httputil.HTTPServerRequest) -> None:
|
||||||
data = {} # type: Dict[str, Any]
|
if tornado.version_info > (6, 2, 0, 0):
|
||||||
response = [] # type: List[bytes]
|
data = {} # type: Dict[str, Any]
|
||||||
|
response = [] # type: List[bytes]
|
||||||
|
|
||||||
def start_response(
|
def start_response(
|
||||||
status: str,
|
status: str,
|
||||||
headers: List[Tuple[str, str]],
|
headers: List[Tuple[str, str]],
|
||||||
exc_info: Optional[
|
exc_info: Optional[
|
||||||
Tuple[
|
Tuple[
|
||||||
"Optional[Type[BaseException]]",
|
"Optional[Type[BaseException]]",
|
||||||
Optional[BaseException],
|
Optional[BaseException],
|
||||||
Optional[TracebackType],
|
Optional[TracebackType],
|
||||||
]
|
]
|
||||||
] = None,
|
] = None,
|
||||||
) -> Callable[[bytes], Any]:
|
) -> Callable[[bytes], Any]:
|
||||||
data["status"] = status
|
data["status"] = status
|
||||||
data["headers"] = headers
|
data["headers"] = headers
|
||||||
return response.append
|
return response.append
|
||||||
|
|
||||||
app_response = self.wsgi_application(
|
app_response = self.wsgi_application(
|
||||||
MyWSGIContainer.environ(request), start_response
|
MyWSGIContainer.environ(self, request), start_response
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
response.extend(app_response)
|
response.extend(app_response)
|
||||||
body = b"".join(response)
|
body = b"".join(response)
|
||||||
finally:
|
finally:
|
||||||
if hasattr(app_response, "close"):
|
if hasattr(app_response, "close"):
|
||||||
app_response.close() # type: ignore
|
app_response.close() # type: ignore
|
||||||
if not data:
|
if not data:
|
||||||
raise Exception("WSGI app did not call start_response")
|
raise Exception("WSGI app did not call start_response")
|
||||||
|
|
||||||
status_code_str, reason = data["status"].split(" ", 1)
|
status_code_str, reason = data["status"].split(" ", 1)
|
||||||
status_code = int(status_code_str)
|
status_code = int(status_code_str)
|
||||||
headers = data["headers"] # type: List[Tuple[str, str]]
|
headers = data["headers"] # type: List[Tuple[str, str]]
|
||||||
header_set = set(k.lower() for (k, v) in headers)
|
header_set = set(k.lower() for (k, v) in headers)
|
||||||
body = escape.utf8(body)
|
body = escape.utf8(body)
|
||||||
if status_code != 304:
|
if status_code != 304:
|
||||||
if "content-length" not in header_set:
|
if "content-length" not in header_set:
|
||||||
headers.append(("Content-Length", str(len(body))))
|
headers.append(("Content-Length", str(len(body))))
|
||||||
if "content-type" not in header_set:
|
if "content-type" not in header_set:
|
||||||
headers.append(("Content-Type", "text/html; charset=UTF-8"))
|
headers.append(("Content-Type", "text/html; charset=UTF-8"))
|
||||||
if "server" not in header_set:
|
if "server" not in header_set:
|
||||||
headers.append(("Server", "TornadoServer/%s" % tornado.version))
|
headers.append(("Server", "TornadoServer/%s" % tornado.version))
|
||||||
|
|
||||||
start_line = httputil.ResponseStartLine("HTTP/1.1", status_code, reason)
|
start_line = httputil.ResponseStartLine("HTTP/1.1", status_code, reason)
|
||||||
header_obj = httputil.HTTPHeaders()
|
header_obj = httputil.HTTPHeaders()
|
||||||
for key, value in headers:
|
for key, value in headers:
|
||||||
header_obj.add(key, value)
|
header_obj.add(key, value)
|
||||||
assert request.connection is not None
|
assert request.connection is not None
|
||||||
request.connection.write_headers(start_line, header_obj, chunk=body)
|
request.connection.write_headers(start_line, header_obj, chunk=body)
|
||||||
request.connection.finish()
|
request.connection.finish()
|
||||||
self._log(status_code, request)
|
self._log(status_code, request)
|
||||||
|
else:
|
||||||
|
IOLoop.current().spawn_callback(self.handle_request, request)
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def environ(request: httputil.HTTPServerRequest) -> Dict[Text, Any]:
|
def environ(self, request: httputil.HTTPServerRequest) -> Dict[Text, Any]:
|
||||||
environ = WSGIContainer.environ(request)
|
if isinstance(WSGIContainer.environ, FunctionType):
|
||||||
|
environ = WSGIContainer.environ(self, request)
|
||||||
|
else:
|
||||||
|
environ = WSGIContainer.environ(request)
|
||||||
environ['RAW_URI'] = request.path
|
environ['RAW_URI'] = request.path
|
||||||
return environ
|
return environ
|
||||||
|
|
||||||
|
@ -1,31 +1,31 @@
|
|||||||
# GDrive Integration
|
# GDrive Integration
|
||||||
google-api-python-client>=1.7.11,<2.90.0
|
google-api-python-client>=1.7.11,<2.98.0
|
||||||
gevent>20.6.0,<23.0.0
|
gevent>20.6.0,<24.0.0
|
||||||
greenlet>=0.4.17,<2.1.0
|
greenlet>=0.4.17,<2.1.0
|
||||||
httplib2>=0.9.2,<0.23.0
|
httplib2>=0.9.2,<0.23.0
|
||||||
oauth2client>=4.0.0,<4.1.4
|
oauth2client>=4.0.0,<4.1.4
|
||||||
uritemplate>=3.0.0,<4.2.0
|
uritemplate>=3.0.0,<4.2.0
|
||||||
pyasn1-modules>=0.0.8,<0.4.0
|
pyasn1-modules>=0.0.8,<0.4.0
|
||||||
pyasn1>=0.1.9,<0.6.0
|
pyasn1>=0.1.9,<0.6.0
|
||||||
PyDrive2>=1.3.1,<1.16.0
|
PyDrive2>=1.3.1,<1.18.0
|
||||||
PyYAML>=3.12
|
PyYAML>=3.12,<6.1
|
||||||
rsa>=3.4.2,<4.10.0
|
rsa>=3.4.2,<4.10.0
|
||||||
|
|
||||||
# Gmail
|
# Gmail
|
||||||
google-auth-oauthlib>=0.4.3,<0.9.0
|
google-auth-oauthlib>=0.4.3,<1.1.0
|
||||||
google-api-python-client>=1.7.11,<2.90.0
|
google-api-python-client>=1.7.11,<2.98.0
|
||||||
|
|
||||||
# goodreads
|
# goodreads
|
||||||
goodreads>=0.3.2,<0.4.0
|
goodreads>=0.3.2,<0.4.0
|
||||||
python-Levenshtein>=0.12.0,<0.21.0
|
python-Levenshtein>=0.12.0,<0.22.0
|
||||||
|
|
||||||
# ldap login
|
# ldap login
|
||||||
python-ldap>=3.0.0,<3.5.0
|
python-ldap>=3.0.0,<3.5.0
|
||||||
Flask-SimpleLDAP>=1.4.0,<1.5.0
|
Flask-SimpleLDAP>=1.4.0,<1.5.0
|
||||||
|
|
||||||
# oauth
|
# oauth
|
||||||
Flask-Dance>=2.0.0,<6.3.0
|
Flask-Dance>=2.0.0,<7.1.0
|
||||||
SQLAlchemy-Utils>=0.33.5,<0.40.0
|
SQLAlchemy-Utils>=0.33.5,<0.42.0
|
||||||
|
|
||||||
# metadata extraction
|
# metadata extraction
|
||||||
rarfile>=3.2
|
rarfile>=3.2
|
||||||
@ -33,12 +33,12 @@ scholarly>=1.2.0,<1.8
|
|||||||
markdown2>=2.0.0,<2.5.0
|
markdown2>=2.0.0,<2.5.0
|
||||||
html2text>=2020.1.16,<2022.1.1
|
html2text>=2020.1.16,<2022.1.1
|
||||||
python-dateutil>=2.1,<2.9.0
|
python-dateutil>=2.1,<2.9.0
|
||||||
beautifulsoup4>=4.0.1,<4.12.0
|
beautifulsoup4>=4.0.1,<4.13.0
|
||||||
faust-cchardet>=2.1.18
|
faust-cchardet>=2.1.18,<2.1.20
|
||||||
|
|
||||||
# Comics
|
# Comics
|
||||||
natsort>=2.2.0,<8.4.0
|
natsort>=2.2.0,<8.4.0
|
||||||
comicapi>=2.2.0,<3.3.0
|
comicapi>=2.2.0,<3.3.0
|
||||||
|
|
||||||
# Kobo integration
|
# Kobo integration
|
||||||
jsonschema>=3.2.0,<4.18.0
|
jsonschema>=3.2.0,<4.20.0
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
APScheduler>=3.6.3,<3.11.0
|
APScheduler>=3.6.3,<3.11.0
|
||||||
Babel>=1.3,<3.0
|
Babel>=1.3,<3.0
|
||||||
Flask-Babel>=0.11.1,<3.1.0
|
Flask-Babel>=0.11.1,<3.2.0
|
||||||
Flask-Login>=0.3.2,<0.6.3
|
Flask-Login>=0.3.2,<0.6.3
|
||||||
Flask-Principal>=0.3.2,<0.5.1
|
Flask-Principal>=0.3.2,<0.5.1
|
||||||
Flask>=1.0.2,<2.4.0
|
Flask>=1.0.2,<2.4.0
|
||||||
iso-639>=0.4.5,<0.5.0
|
iso-639>=0.4.5,<0.5.0
|
||||||
PyPDF>=3.0.0,<3.8.0
|
PyPDF>=3.0.0,<3.16.0
|
||||||
pytz>=2016.10
|
pytz>=2016.10
|
||||||
requests>=2.11.1,<2.29.0
|
requests>=2.28.0,<2.32.0
|
||||||
SQLAlchemy>=1.3.0,<2.0.0
|
SQLAlchemy>=1.3.0,<2.0.0
|
||||||
tornado>=4.1,<6.3
|
tornado>=6.3,<6.4
|
||||||
Wand>=0.4.4,<0.7.0
|
Wand>=0.4.4,<0.7.0
|
||||||
unidecode>=0.04.19,<1.4.0
|
unidecode>=0.04.19,<1.4.0
|
||||||
lxml>=3.8.0,<5.0.0
|
lxml>=3.8.0,<5.0.0
|
||||||
flask-wtf>=0.14.2,<1.2.0
|
flask-wtf>=0.14.2,<1.2.0
|
||||||
chardet>=3.0.0,<4.1.0
|
chardet>=3.0.0,<4.1.0
|
||||||
advocate>=1.0.0,<1.1.0
|
advocate>=1.0.0,<1.1.0
|
||||||
Flask-Limiter>=2.3.0,<3.4.0
|
Flask-Limiter>=2.3.0,<3.5.0
|
||||||
|
Loading…
Reference in New Issue
Block a user