diff --git a/README.md b/README.md index 2d6efaf5..a400b3b2 100755 --- a/README.md +++ b/README.md @@ -89,8 +89,9 @@ Refer to the Wiki for additional installation examples: [manual installation](ht ## Requirements -- Python 3.5+ +- Python 3.7+ - [Imagemagick](https://imagemagick.org/script/download.php) for cover extraction from EPUBs (Windows users may need to install [Ghostscript](https://ghostscript.com/releases/gsdnld.html) for PDF cover extraction) +- Windows users need to install [libmagic for 32bit python](https://gnuwin32.sourceforge.net/downlinks/file.php) or [libmagic for 64bit python](https://github.com/nscaife/file-windows/releases/tag/20170108), depending on the python version; The files need to be installed in path (e.g. script folder of your Calibre-Web venv, or in the root folder of Calibre-Web - Optional: [Calibre desktop program](https://calibre-ebook.com/download) for on-the-fly conversion and metadata editing (set "calibre's converter tool" path on the setup page) - Optional: [Kepubify tool](https://github.com/pgaskin/kepubify/releases/latest) for Kobo device support (place the binary in `/opt/kepubify` on Linux or `C:\Program Files\kepubify` on Windows) diff --git a/cps.py b/cps.py index 8af6cef1..039c2a5e 100755 --- a/cps.py +++ b/cps.py @@ -30,19 +30,15 @@ from cps.main import main def hide_console_windows(): import ctypes - import os - hwnd = ctypes.windll.kernel32.GetConsoleWindow() - if hwnd != 0: - try: - import win32process - except ImportError: - print("To hide console window install 'pywin32' using 'pip install pywin32'") - return - ctypes.windll.user32.ShowWindow(hwnd, 0) - ctypes.windll.kernel32.CloseHandle(hwnd) - _, pid = win32process.GetWindowThreadProcessId(hwnd) - os.system('taskkill /PID ' + str(pid) + ' /f') + kernel32 = ctypes.WinDLL('kernel32') + user32 = ctypes.WinDLL('user32') + + SW_HIDE = 0 + + hWnd = kernel32.GetConsoleWindow() + if hWnd: + user32.ShowWindow(hWnd, SW_HIDE) if __name__ == '__main__': diff --git a/cps/__init__.py b/cps/__init__.py index 57832f79..157dd14e 100755 --- a/cps/__init__.py +++ b/cps/__init__.py @@ -70,8 +70,8 @@ mimetypes.add_type('image/vnd.djv', '.djv') mimetypes.add_type('image/vnd.djv', '.djvu') mimetypes.add_type('application/mpeg', '.mpeg') mimetypes.add_type('audio/mpeg', '.mp3') -mimetypes.add_type('application/mp4', '.m4a') -mimetypes.add_type('application/mp4', '.m4b') +mimetypes.add_type('audio/x-m4a', '.m4a') +mimetypes.add_type('audio/x-m4a', '.m4b') mimetypes.add_type('audio/ogg', '.ogg') mimetypes.add_type('application/ogg', '.oga') mimetypes.add_type('text/css', '.css') diff --git a/cps/file_helper.py b/cps/file_helper.py index 095b5ee0..9d5406d3 100644 --- a/cps/file_helper.py +++ b/cps/file_helper.py @@ -29,8 +29,9 @@ log = logger.create() try: import magic + error = None except ImportError as e: - log.error("Cannot import python-magic, checking uploaded file metadata will not work: %s", e) + error = "Cannot import python-magic, checking uploaded file metadata will not work: {}".format(e) def get_temp_dir(): @@ -46,12 +47,15 @@ def del_temp_dir(): def validate_mime_type(file_buffer, allowed_extensions): + if error: + log.error(error) + return False mime = magic.Magic(mime=True) - allowed_mimetypes =list() + allowed_mimetypes = list() for x in allowed_extensions: try: allowed_mimetypes.append(mimetypes.types_map["." + x]) - except KeyError as e: + except KeyError: log.error("Unkown mimetype for Extension: {}".format(x)) tmp_mime_type = mime.from_buffer(file_buffer.read()) file_buffer.seek(0) @@ -66,6 +70,5 @@ def validate_mime_type(file_buffer, allowed_extensions): return True except: file_buffer.seek(0) - pass - + log.error("Mimetype '{}' not found in allowed types".format(tmp_mime_type)) return False diff --git a/cps/helper.py b/cps/helper.py index 2d39895e..08fa1387 100644 --- a/cps/helper.py +++ b/cps/helper.py @@ -562,7 +562,7 @@ def move_files_on_change(calibre_path, new_author_dir, new_titledir, localbook, if not os.path.isdir(new_path): os.makedirs(new_path) shutil.move(original_filepath, os.path.join(new_path, db_filename)) - log.debug("Moving title: %s to %s/%s", original_filepath, new_path) + log.debug("Moving title: %s to %s", original_filepath, new_path) else: # Check new path is not valid path if not os.path.exists(new_path): diff --git a/cps/tasks/convert.py b/cps/tasks/convert.py index 5354dce2..e6af356f 100644 --- a/cps/tasks/convert.py +++ b/cps/tasks/convert.py @@ -269,10 +269,18 @@ class TaskConvert(CalibreTask): '--with-library', library_path] p = process_open(opf_command, quotes, my_env) p.wait() - path_tmp_opf = os.path.join(tmp_dir, "metadata_" + str(uuid4()) + ".opf") - with open(path_tmp_opf, 'w') as fd: - copyfileobj(p.stdout, fd) - + check = p.returncode + calibre_traceback = p.stderr.readlines() + if check == 0: + path_tmp_opf = os.path.join(tmp_dir, "metadata_" + str(uuid4()) + ".opf") + with open(path_tmp_opf, 'w') as fd: + copyfileobj(p.stdout, fd) + else: + error_message = "" + for ele in calibre_traceback: + if not ele.startswith('Traceback') and not ele.startswith(' File'): + error_message = N_("Calibre failed with error: %(error)s", error=ele) + return check, error_message quotes = [1, 2, 4, 6] command = [config.config_converterpath, (file_path + format_old_ext), (file_path + format_new_ext)] diff --git a/optional-requirements.txt b/optional-requirements.txt index 3f6b6e37..d63bc41c 100644 --- a/optional-requirements.txt +++ b/optional-requirements.txt @@ -43,6 +43,3 @@ comicapi>=2.2.0,<3.3.0 # Kobo integration jsonschema>=3.2.0,<4.24.0 - -# Hide console Window on Windows -pywin32>=220,<310 ; sys_platform == 'win32' diff --git a/test/Calibre-Web TestSummary_Linux.html b/test/Calibre-Web TestSummary_Linux.html index bb2ba3d2..288c7443 100644 --- a/test/Calibre-Web TestSummary_Linux.html +++ b/test/Calibre-Web TestSummary_Linux.html @@ -37,20 +37,20 @@
-

Start Time: 2024-07-17 20:06:46

+

Start Time: 2024-07-18 20:53:44

-

Stop Time: 2024-07-18 03:16:31

+

Stop Time: 2024-07-19 03:48:09

-

Duration: 5h 58 min

+

Duration: 5h 43 min

@@ -1619,13 +1619,13 @@ TestEditAuthors - 8 - 8 + 9 + 9 0 0 0 - Detail + Detail @@ -1687,7 +1687,7 @@ -
TestEditAuthors - test_rename_author_accent_onupload
+
TestEditAuthors - test_rename_author_emphasis_mark_onupload
PASS @@ -1702,6 +1702,15 @@ + + + +
TestEditAuthors - test_rename_tag_emphasis_mark_onupload
+ + PASS + + + @@ -2635,11 +2644,11 @@ IndexError: list index out of range - + TestKoboSync 12 - 11 - 1 + 12 + 0 0 0 @@ -2730,31 +2739,11 @@ IndexError: list index out of range - +
TestKoboSync - test_sync_shelf
- -
- FAIL -
- - - - + PASS @@ -5624,9 +5613,9 @@ ModuleNotFoundError: No module named 'build_release' Total - 498 - 485 - 1 + 499 + 487 + 0 2 10   @@ -5656,7 +5645,7 @@ ModuleNotFoundError: No module named 'build_release' Platform - Linux 6.5.0-41-generic #41~22.04.2-Ubuntu SMP PREEMPT_DYNAMIC Mon Jun 3 11:32:55 UTC 2 x86_64 x86_64 + Linux 6.5.0-44-generic #44~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue Jun 18 14:36:16 UTC 2 x86_64 x86_64 Basic @@ -6160,7 +6149,7 @@ ModuleNotFoundError: No module named 'build_release'