mirror of
				https://github.com/janeczku/calibre-web
				synced 2025-10-31 15:23:02 +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:
		| @@ -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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Ozzie Isaacs
					Ozzie Isaacs