mirror of
				https://github.com/janeczku/calibre-web
				synced 2025-10-31 07:13: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 | ||||
| from base64 import b64decode, b64encode | ||||
| from jsonschema import validate, exceptions, __version__ | ||||
| from datetime import datetime, timezone | ||||
|  | ||||
| from urllib.parse import unquote | ||||
| from jsonschema import validate, exceptions | ||||
| from datetime import datetime | ||||
|  | ||||
| from flask import json | ||||
| 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() { | ||||
|     $("#progress").click(function(e) { | ||||
|         var offset = $(this).offset(); | ||||
|         var x = e.pageX - offset.left; | ||||
|         var rate = settings.direction === 0 ? x / $(this).width() : 1 - x / $(this).width(); | ||||
|         currentImage = Math.max(1, Math.ceil(rate * totalImages)) - 1; | ||||
|         updateDirectionButtons(); | ||||
|         updatePage(); | ||||
|     }); | ||||
| } | ||||
| @@ -222,6 +241,11 @@ function loadFromArrayBuffer(ab) { | ||||
|                                      | ||||
|                                     // display first page if we haven't yet | ||||
|                                     if (imageFiles.length === currentImage + 1) { | ||||
|                                         if (settings.direction === 0) { | ||||
|                                             $("#right").show(); | ||||
|                                         } else { | ||||
|                                             $("#left").show(); | ||||
|                                         } | ||||
|                                         updatePage(); | ||||
|                                     } | ||||
|                                 } else { | ||||
| @@ -427,6 +451,7 @@ function showPrevPage() { | ||||
|     } else { | ||||
|         updatePage(); | ||||
|     } | ||||
|     updateDirectionButtons(); | ||||
| } | ||||
|  | ||||
| function showNextPage() { | ||||
| @@ -437,6 +462,7 @@ function showNextPage() { | ||||
|     } else { | ||||
|         updatePage(); | ||||
|     } | ||||
|     updateDirectionButtons(); | ||||
| } | ||||
|  | ||||
| function scrollCurrentImageIntoView() { | ||||
| @@ -677,6 +703,7 @@ function init(filename) { | ||||
|         if(["hflip", "vflip", "rotateTimes"].includes(this.name)) { | ||||
|             reloadImages(); | ||||
|         } else if(this.name === "direction") { | ||||
|             updateDirectionButtons(); | ||||
|             return updateProgress(); | ||||
|         } | ||||
|          | ||||
| @@ -726,7 +753,7 @@ function init(filename) { | ||||
|         }, | ||||
|     }); | ||||
|     $(".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. | ||||
|         var mainContentWidth = $("#mainContent").width(); | ||||
|         var mainContentHeight = $("#mainContent").height(); | ||||
|   | ||||
| @@ -77,8 +77,8 @@ | ||||
|   <div id="mainContent" tabindex="-1"> | ||||
|     <div id="mainText" style="display:none"></div> | ||||
|   </div> | ||||
|   <div id="left" class="arrow" onclick="showLeftPage()">‹</div> | ||||
|   <div id="right" class="arrow" onclick="showRightPage()">›</div> | ||||
|   <div id="left" class="arrow" style="display:none" onclick="showLeftPage()">‹</div> | ||||
|   <div id="right" class="arrow" style="display:none" onclick="showRightPage()">›</div> | ||||
| </div> | ||||
|  | ||||
| <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 | ||||
| #  along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
|  | ||||
|  | ||||
| from tornado.wsgi import WSGIContainer | ||||
| import tornado | ||||
|  | ||||
| from tornado import escape | ||||
| from tornado import httputil | ||||
| from tornado.ioloop import IOLoop | ||||
|  | ||||
| from typing import List, Tuple, Optional, Callable, Any, Dict, Text | ||||
| from types import TracebackType | ||||
| from types import TracebackType, FunctionType | ||||
| import typing | ||||
|  | ||||
| if typing.TYPE_CHECKING: | ||||
| @@ -34,61 +34,67 @@ if typing.TYPE_CHECKING: | ||||
| class MyWSGIContainer(WSGIContainer): | ||||
|  | ||||
|     def __call__(self, request: httputil.HTTPServerRequest) -> None: | ||||
|         data = {}  # type: Dict[str, Any] | ||||
|         response = []  # type: List[bytes] | ||||
|         if tornado.version_info > (6, 2, 0, 0): | ||||
|             data = {}  # type: Dict[str, Any] | ||||
|             response = []  # type: List[bytes] | ||||
|  | ||||
|         def start_response( | ||||
|             status: str, | ||||
|             headers: List[Tuple[str, str]], | ||||
|             exc_info: Optional[ | ||||
|                 Tuple[ | ||||
|                     "Optional[Type[BaseException]]", | ||||
|                     Optional[BaseException], | ||||
|                     Optional[TracebackType], | ||||
|                 ] | ||||
|             ] = None, | ||||
|         ) -> Callable[[bytes], Any]: | ||||
|             data["status"] = status | ||||
|             data["headers"] = headers | ||||
|             return response.append | ||||
|             def start_response( | ||||
|                 status: str, | ||||
|                 headers: List[Tuple[str, str]], | ||||
|                 exc_info: Optional[ | ||||
|                     Tuple[ | ||||
|                         "Optional[Type[BaseException]]", | ||||
|                         Optional[BaseException], | ||||
|                         Optional[TracebackType], | ||||
|                     ] | ||||
|                 ] = None, | ||||
|             ) -> Callable[[bytes], Any]: | ||||
|                 data["status"] = status | ||||
|                 data["headers"] = headers | ||||
|                 return response.append | ||||
|  | ||||
|         app_response = self.wsgi_application( | ||||
|             MyWSGIContainer.environ(request), start_response | ||||
|         ) | ||||
|         try: | ||||
|             response.extend(app_response) | ||||
|             body = b"".join(response) | ||||
|         finally: | ||||
|             if hasattr(app_response, "close"): | ||||
|                 app_response.close()  # type: ignore | ||||
|         if not data: | ||||
|             raise Exception("WSGI app did not call start_response") | ||||
|             app_response = self.wsgi_application( | ||||
|                 MyWSGIContainer.environ(self, request), start_response | ||||
|             ) | ||||
|             try: | ||||
|                 response.extend(app_response) | ||||
|                 body = b"".join(response) | ||||
|             finally: | ||||
|                 if hasattr(app_response, "close"): | ||||
|                     app_response.close()  # type: ignore | ||||
|             if not data: | ||||
|                 raise Exception("WSGI app did not call start_response") | ||||
|  | ||||
|         status_code_str, reason = data["status"].split(" ", 1) | ||||
|         status_code = int(status_code_str) | ||||
|         headers = data["headers"]  # type: List[Tuple[str, str]] | ||||
|         header_set = set(k.lower() for (k, v) in headers) | ||||
|         body = escape.utf8(body) | ||||
|         if status_code != 304: | ||||
|             if "content-length" not in header_set: | ||||
|                 headers.append(("Content-Length", str(len(body)))) | ||||
|             if "content-type" not in header_set: | ||||
|                 headers.append(("Content-Type", "text/html; charset=UTF-8")) | ||||
|         if "server" not in header_set: | ||||
|             headers.append(("Server", "TornadoServer/%s" % tornado.version)) | ||||
|             status_code_str, reason = data["status"].split(" ", 1) | ||||
|             status_code = int(status_code_str) | ||||
|             headers = data["headers"]  # type: List[Tuple[str, str]] | ||||
|             header_set = set(k.lower() for (k, v) in headers) | ||||
|             body = escape.utf8(body) | ||||
|             if status_code != 304: | ||||
|                 if "content-length" not in header_set: | ||||
|                     headers.append(("Content-Length", str(len(body)))) | ||||
|                 if "content-type" not in header_set: | ||||
|                     headers.append(("Content-Type", "text/html; charset=UTF-8")) | ||||
|             if "server" not in header_set: | ||||
|                 headers.append(("Server", "TornadoServer/%s" % tornado.version)) | ||||
|  | ||||
|         start_line = httputil.ResponseStartLine("HTTP/1.1", status_code, reason) | ||||
|         header_obj = httputil.HTTPHeaders() | ||||
|         for key, value in headers: | ||||
|             header_obj.add(key, value) | ||||
|         assert request.connection is not None | ||||
|         request.connection.write_headers(start_line, header_obj, chunk=body) | ||||
|         request.connection.finish() | ||||
|         self._log(status_code, request) | ||||
|             start_line = httputil.ResponseStartLine("HTTP/1.1", status_code, reason) | ||||
|             header_obj = httputil.HTTPHeaders() | ||||
|             for key, value in headers: | ||||
|                 header_obj.add(key, value) | ||||
|             assert request.connection is not None | ||||
|             request.connection.write_headers(start_line, header_obj, chunk=body) | ||||
|             request.connection.finish() | ||||
|             self._log(status_code, request) | ||||
|         else: | ||||
|             IOLoop.current().spawn_callback(self.handle_request, request) | ||||
|  | ||||
|     @staticmethod | ||||
|     def environ(request: httputil.HTTPServerRequest) -> Dict[Text, Any]: | ||||
|         environ = WSGIContainer.environ(request) | ||||
|  | ||||
|     def environ(self, request: httputil.HTTPServerRequest) -> Dict[Text, Any]: | ||||
|         if isinstance(WSGIContainer.environ, FunctionType): | ||||
|             environ = WSGIContainer.environ(self, request) | ||||
|         else: | ||||
|             environ = WSGIContainer.environ(request) | ||||
|         environ['RAW_URI'] = request.path | ||||
|         return environ | ||||
|  | ||||
|   | ||||
| @@ -1,31 +1,31 @@ | ||||
| # GDrive Integration | ||||
| google-api-python-client>=1.7.11,<2.90.0 | ||||
| gevent>20.6.0,<23.0.0 | ||||
| google-api-python-client>=1.7.11,<2.98.0 | ||||
| gevent>20.6.0,<24.0.0 | ||||
| greenlet>=0.4.17,<2.1.0 | ||||
| httplib2>=0.9.2,<0.23.0 | ||||
| oauth2client>=4.0.0,<4.1.4 | ||||
| uritemplate>=3.0.0,<4.2.0 | ||||
| pyasn1-modules>=0.0.8,<0.4.0 | ||||
| pyasn1>=0.1.9,<0.6.0 | ||||
| PyDrive2>=1.3.1,<1.16.0 | ||||
| PyYAML>=3.12 | ||||
| PyDrive2>=1.3.1,<1.18.0 | ||||
| PyYAML>=3.12,<6.1 | ||||
| rsa>=3.4.2,<4.10.0 | ||||
|  | ||||
| # Gmail | ||||
| google-auth-oauthlib>=0.4.3,<0.9.0 | ||||
| google-api-python-client>=1.7.11,<2.90.0 | ||||
| google-auth-oauthlib>=0.4.3,<1.1.0 | ||||
| google-api-python-client>=1.7.11,<2.98.0 | ||||
|  | ||||
| # goodreads | ||||
| 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 | ||||
| python-ldap>=3.0.0,<3.5.0 | ||||
| Flask-SimpleLDAP>=1.4.0,<1.5.0 | ||||
|  | ||||
| # oauth | ||||
| Flask-Dance>=2.0.0,<6.3.0 | ||||
| SQLAlchemy-Utils>=0.33.5,<0.40.0 | ||||
| Flask-Dance>=2.0.0,<7.1.0 | ||||
| SQLAlchemy-Utils>=0.33.5,<0.42.0 | ||||
|  | ||||
| # metadata extraction | ||||
| rarfile>=3.2 | ||||
| @@ -33,12 +33,12 @@ scholarly>=1.2.0,<1.8 | ||||
| markdown2>=2.0.0,<2.5.0 | ||||
| html2text>=2020.1.16,<2022.1.1 | ||||
| python-dateutil>=2.1,<2.9.0 | ||||
| beautifulsoup4>=4.0.1,<4.12.0 | ||||
| faust-cchardet>=2.1.18 | ||||
| beautifulsoup4>=4.0.1,<4.13.0 | ||||
| faust-cchardet>=2.1.18,<2.1.20 | ||||
|  | ||||
| # Comics | ||||
| natsort>=2.2.0,<8.4.0 | ||||
| comicapi>=2.2.0,<3.3.0 | ||||
|  | ||||
| # 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 | ||||
| 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-Principal>=0.3.2,<0.5.1 | ||||
| Flask>=1.0.2,<2.4.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 | ||||
| requests>=2.11.1,<2.29.0 | ||||
| requests>=2.28.0,<2.32.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 | ||||
| unidecode>=0.04.19,<1.4.0 | ||||
| lxml>=3.8.0,<5.0.0 | ||||
| flask-wtf>=0.14.2,<1.2.0 | ||||
| chardet>=3.0.0,<4.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