2
0
mirror of https://github.com/janeczku/calibre-web synced 2024-11-10 01:13:33 +00:00

Merge branch 'master' into Develop

This commit is contained in:
Ozzie Isaacs 2024-07-20 14:01:36 +02:00
commit a1d7dc5c28
8 changed files with 59 additions and 65 deletions

View File

@ -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)

20
cps.py
View File

@ -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__':

View File

@ -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')

View File

@ -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

View File

@ -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):

View File

@ -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)]

View File

@ -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'

View File

@ -37,20 +37,20 @@
<div class="row">
<div class="col-xs-6 col-md-6 col-sm-offset-3" style="margin-top:50px;">
<p class='text-justify attribute'><strong>Start Time: </strong>2024-07-17 20:06:46</p>
<p class='text-justify attribute'><strong>Start Time: </strong>2024-07-18 20:53:44</p>
</div>
</div>
<div class="row">
<div class="col-xs-6 col-md-6 col-sm-offset-3">
<p class='text-justify attribute'><strong>Stop Time: </strong>2024-07-18 03:16:31</p>
<p class='text-justify attribute'><strong>Stop Time: </strong>2024-07-19 03:48:09</p>
</div>
</div>
<div class="row">
<div class="col-xs-6 col-md-6 col-sm-offset-3">
<p class='text-justify attribute'><strong>Duration: </strong>5h 58 min</p>
<p class='text-justify attribute'><strong>Duration: </strong>5h 43 min</p>
</div>
</div>
</div>
@ -1619,13 +1619,13 @@
<tr id="su" class="passClass">
<td>TestEditAuthors</td>
<td class="text-center">8</td>
<td class="text-center">8</td>
<td class="text-center">9</td>
<td class="text-center">9</td>
<td class="text-center">0</td>
<td class="text-center">0</td>
<td class="text-center">0</td>
<td class="text-center">
<a onclick="showClassDetail('c14', 8)">Detail</a>
<a onclick="showClassDetail('c14', 9)">Detail</a>
</td>
</tr>
@ -1687,7 +1687,7 @@
<tr id='pt14.7' class='hiddenRow bg-success'>
<td>
<div class='testcase'>TestEditAuthors - test_rename_author_accent_onupload</div>
<div class='testcase'>TestEditAuthors - test_rename_author_emphasis_mark_onupload</div>
</td>
<td colspan='6' align='center'>PASS</td>
</tr>
@ -1702,6 +1702,15 @@
</tr>
<tr id='pt14.9' class='hiddenRow bg-success'>
<td>
<div class='testcase'>TestEditAuthors - test_rename_tag_emphasis_mark_onupload</div>
</td>
<td colspan='6' align='center'>PASS</td>
</tr>
<tr id="su" class="passClass">
@ -2635,11 +2644,11 @@ IndexError: list index out of range</pre>
<tr id="su" class="failClass">
<tr id="su" class="passClass">
<td>TestKoboSync</td>
<td class="text-center">12</td>
<td class="text-center">11</td>
<td class="text-center">1</td>
<td class="text-center">12</td>
<td class="text-center">0</td>
<td class="text-center">0</td>
<td class="text-center">0</td>
<td class="text-center">
@ -2730,31 +2739,11 @@ IndexError: list index out of range</pre>
<tr id="ft29.10" class="none bg-danger">
<tr id='pt29.10' class='hiddenRow bg-success'>
<td>
<div class='testcase'>TestKoboSync - test_sync_shelf</div>
</td>
<td colspan='6'>
<div class="text-center">
<a class="popup_link text-center" onfocus='blur()' onclick="showTestDetail('div_ft29.10')">FAIL</a>
</div>
<!--css div popup start-->
<div id="div_ft29.10" class="popup_window test_output" style="display:block;">
<div class='close_button pull-right'>
<button type="button" class="close" aria-label="Close" onfocus="this.blur();"
onclick="document.getElementById('div_ft29.10').style.display='none'"><span
aria-hidden="true">&times;</span></button>
</div>
<div class="text-left pull-left">
<pre class="text-left">Traceback (most recent call last):
File &#34;/home/ozzie/Development/calibre-web-test/test/test_kobo_sync.py&#34;, line 368, in test_sync_shelf
self.assertEqual(1, len(data), data)
AssertionError: 1 != 0 : []</pre>
</div>
<div class="clearfix"></div>
</div>
<!--css div popup end-->
</td>
<td colspan='6' align='center'>PASS</td>
</tr>
@ -5624,9 +5613,9 @@ ModuleNotFoundError: No module named &#39;build_release&#39;</pre>
<tr id='total_row' class="text-center bg-grey">
<td>Total</td>
<td>498</td>
<td>485</td>
<td>1</td>
<td>499</td>
<td>487</td>
<td>0</td>
<td>2</td>
<td>10</td>
<td>&nbsp;</td>
@ -5656,7 +5645,7 @@ ModuleNotFoundError: No module named &#39;build_release&#39;</pre>
<tr>
<th>Platform</th>
<td>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</td>
<td>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</td>
<td>Basic</td>
</tr>
@ -6160,7 +6149,7 @@ ModuleNotFoundError: No module named &#39;build_release&#39;</pre>
</div>
<script>
drawCircle(485, 1, 2, 10);
drawCircle(487, 0, 2, 10);
showCase(5);
</script>