mirror of
https://github.com/janeczku/calibre-web
synced 2024-11-18 15:54:56 +00:00
Merge branch 'master' into Develop
This commit is contained in:
commit
a1d7dc5c28
@ -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
20
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__':
|
||||
|
@ -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')
|
||||
|
@ -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
|
||||
|
@ -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):
|
||||
|
@ -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)]
|
||||
|
@ -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'
|
||||
|
@ -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">×</span></button>
|
||||
</div>
|
||||
<div class="text-left pull-left">
|
||||
<pre class="text-left">Traceback (most recent call last):
|
||||
File "/home/ozzie/Development/calibre-web-test/test/test_kobo_sync.py", 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 'build_release'</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> </td>
|
||||
@ -5656,7 +5645,7 @@ ModuleNotFoundError: No module named 'build_release'</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 'build_release'</pre>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
drawCircle(485, 1, 2, 10);
|
||||
drawCircle(487, 0, 2, 10);
|
||||
showCase(5);
|
||||
</script>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user