Skip to content

Commit

Permalink
# Version 2.1.0
Browse files Browse the repository at this point in the history
- Made it possible to shift click to select multiple books in the the Book List page. Courtesy of @jmarmstrong1207
- Added greater support for special characters in Book Titles and Author Names
- Improved error handling for files that are unable to be successfully processed
- Fix for bug where the Web UI could become unavailable due to not receiving a response for a API query to the project's GitHub page. Courtesy of @Buco7854
- Made it so CWA only checks for available updates once per day
- This and future builds now available for ARM based machines thanks to help from @driftywinds and @carlossgv
- Enabled Uploads to be on by default
- Added default path to included calibre & kepubify binaries
- Reworked the ingest process to solve issues for a number of users
- Deprecated new-book-detector and renamed scripts to make their function clearer
  • Loading branch information
crocodilestick committed Sep 20, 2024
1 parent afbb32a commit ae3d433
Show file tree
Hide file tree
Showing 28 changed files with 229 additions and 234 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ share/python-wheels/
.installed.cfg
*.egg
MANIFEST
.vscode

# PyInstaller
# Usually these files are written by a python script from a template
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ After discovering that using the DOCKER_MODS universal-calibre environment varia
- Calibre-Web Automated has always been designed with `.epub` libraries in mind due to many factors, chief among which being the fact they are **Compatible with the Widest Range of Devices**, **Ubiquitous** as well as being **Easy to Manage and Work with**
- Previously this meant that anyone with `non-epub` ebooks in their existing Calibre Libraries was unable to take advantage of all of `Calibre-Web Automated`'s features reliably
- So new to Version 1.2.0 is the ability for those users to quickly and easily convert their existing eBook Libraries, no matter the size, to `.epub Version 3` format using a one-step CLI Command from within the CWA Container
- This utility gives the user the option to either keep a copy of the original of all converted files in `/config/original-library` or to trust the process and have CWA simply convert and replace those files (not recommended)
- This utility gives the user the option to either keep a copy of the original of all converted files in `/config/processed_books` or to trust the process and have CWA simply convert and replace those files (not recommended)
- Full usage details can be found [here](#the-convert-library-tool)

- **Simple CLI Tools** for manual fixes, conversions, enforcements, history viewing ect. 👨‍💻
Expand Down Expand Up @@ -221,7 +221,7 @@ services:

- If your Calibre Library contains any ebooks not in the `.epub` format, from within the container run the `convert-library` command.
- Calibre-Web Automated's extra features only work with epubs and so **failure to complete this step could result in unforeseen errors and general unreliability**
- Full usage can be found below in the Usage Section however the following command will automatically convert any non-epubs to epubs and store the original files in `/config/original-library`:
- Full usage can be found below in the Usage Section however the following command will automatically convert any non-epubs to epubs and store the original files in `/config/processed_books`:

```
convert-library --keep
Expand Down Expand Up @@ -268,7 +268,7 @@ Made for the purpose of converting ebooks in a calibre library not in epub forma
options:
-h, --help show this help message and exit
--replace, -r Replaces the old library with the new one
--keep, -k Creates a new epub library with the old one but stores the old files in /config/original-library
--keep, -k Creates a new epub library with the old one but stores the old files in /config/processed_books
-setup Indicates to the function whether or not it's being ran from the setup script or manually (DO NOT USE MANUALLY)
```

Expand Down
Binary file modified empty_library/app.db
Binary file not shown.
26 changes: 13 additions & 13 deletions root/app/calibre-web/cps/cwa_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from .usermanagement import login_required_if_no_ano
from .admin import admin_required

import os
import subprocess

switch_theme = Blueprint('switch_theme', __name__)
library_refresh = Blueprint('library_refresh', __name__)
Expand Down Expand Up @@ -47,19 +47,19 @@ def cwa_switch_theme():
@login_required_if_no_ano
def cwa_library_refresh():
flash(_("Library Refresh: Initialising Book Ingest System, please wait..."), category="cwa_refresh")
return_code = os.system('python3 /app/calibre-web-automated/scripts/new-book-processor.py "/cwa-book-ingest"')
return_val = os.WEXITSTATUS(return_code)

if return_val > 100:
flash(_(f"Library Refresh: Ingest process complete. {return_val - 100} new books ingested."), category="cwa_refresh")
elif return_val == 2:
flash(_("Library Refersh: The book ingest service is already running, please wait until it has finished before trying again."), category="cwa_refresh")
# elif return_val == 0:
# flash(_("Manually starting ingest proces"), category="info")
elif return_val == 0:
result = subprocess.run('python3', '/app/calibre-web-automated/scripts/ingest-processor.py', '/cwa-book-ingest')
return_code = result.returncode

if return_code > 100:
flash(_(f"Library Refresh: Ingest process complete. {return_code - 100} new books ingested."), category="cwa_refresh")
elif return_code == 2:
flash(_("Library Refresh: The book ingest service is already running, please wait until it has finished before trying again."), category="cwa_refresh")
# elif return_code == 0:
# flash(_("Manually starting ingest process"), category="info")
elif return_code == 0:
flash(_("Library Refresh: Ingest process complete. No new books ingested."), category="cwa_refresh")
else:
flash(_("Library Refresh: An unexpected error occured, check the logs."), category="cwa_refresh")
flash(_("Library Refresh: An unexpected error occurred, check the logs."), category="cwa_refresh")

return redirect("/", code=302)

Expand All @@ -69,7 +69,7 @@ def cwa_library_refresh():
@admin_required
def cwa_library_convert():
flash(_("Library Convert: Running, please wait..."), category="refresh-cwa")
os.system('python3 /app/calibre-web-automated/scripts/convert-library.py -k')
subprocess.Popen('python3', '/app/calibre-web-automated/scripts/convert-library.py', '-k')
return redirect(url_for('admin.view_logfile'))

# Coming Soon
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,16 @@

# This script is used to automatically import downloaded ebooks into a Calibre database.
# Reference: https://manual.calibre-ebook.com/generated/en/calibredb.html#add
echo "========== STARTING BOOKS-TO-PROCESS DETECTOR =========="
echo "========== STARTING CWA-INGEST SERVICE =========="

# Folder to monitor, replace "/books/to_process" with the folder you want to monitor e.g. your download folder for books
WATCH_FOLDER=$(grep -o '"ingest_folder": "[^"]*' /app/calibre-web-automated/dirs.json | grep -o '[^"]*$')
echo "[books-to-process]: Watching folder: $WATCH_FOLDER"
echo "[cwa-ingest-service]: Watching folder: $WATCH_FOLDER"

# Monitor the folder for new files
s6-setuidgid abc inotifywait -m -r --format="%e %w%f" -e close_write -e moved_to "$WATCH_FOLDER" |
while read -r events filepath ; do
echo "[books-to-process]: New files detected - $filepath"
python3 /app/calibre-web-automated/scripts/new-book-processor.py "$filepath"
echo "[books-to-process]: New files successfully moved/converted, the Ingest Folder has been emptied and is ready to go again."
echo "[cwa-ingest-service]: New files detected - $filepath"
python3 /app/calibre-web-automated/scripts/ingest-processor.py "$filepath"
echo "[cwa-ingest-service]: New files successfully moved/converted, the Ingest Folder has been emptied and is ready to go again."
done

2 changes: 1 addition & 1 deletion root/etc/s6-overlay/s6-rc.d/cwa-init-remove-locks/run
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/bin/bash

declare -a lockFiles=("new-book-processor.lock")
declare -a lockFiles=("ingest-processor.lock")

echo "[cwa-init-remove-locks] Checking for leftover lock files from prvious instance..."

Expand Down
1 change: 1 addition & 0 deletions root/etc/s6-overlay/s6-rc.d/cwa-set-perms/type
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
oneshot
1 change: 1 addition & 0 deletions root/etc/s6-overlay/s6-rc.d/cwa-set-perms/up
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/etc/s6-overlay/s6-rc.d/cwa-set-perms/run
37 changes: 0 additions & 37 deletions root/etc/s6-overlay/s6-rc.d/new-book-detector/run

This file was deleted.

1 change: 0 additions & 1 deletion root/etc/s6-overlay/s6-rc.d/new-book-detector/type

This file was deleted.

1 change: 0 additions & 1 deletion root/etc/s6-overlay/s6-rc.d/new-book-detector/up

This file was deleted.

1 change: 0 additions & 1 deletion root/etc/s6-overlay/s6-rc.d/set-cwa-perms/type

This file was deleted.

1 change: 0 additions & 1 deletion root/etc/s6-overlay/s6-rc.d/set-cwa-perms/up

This file was deleted.

Empty file.
Empty file.
2 changes: 1 addition & 1 deletion scripts/auto-library.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def metadb_path(self, path):
self._metadb_path = path
self.lib_path = os.path.dirname(path)

# Checks config_dir for an exisiting app.db, if one doesn't already exist it copies an empty one from /app/calibre-web-automated/empty_library/app.db and sets the permissiosn
# Checks config_dir for an existing app.db, if one doesn't already exist it copies an empty one from /app/calibre-web-automated/empty_library/app.db and sets the permissions
def check_for_app_db(self):
files_in_config = [os.path.join(dirpath,f) for (dirpath, dirnames, filenames) in os.walk(self.config_dir) for f in filenames]
db_files = [f for f in files_in_config if "app.db" in f]
Expand Down
27 changes: 14 additions & 13 deletions scripts/check-cwa-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,20 @@ NC='\033[0m' # No Color
echo "====== Calibre-Web Automated -- Status of Monitoring Services ======"
echo ""

if s6-rc -a list | grep -q 'new-book-detector'; then
echo -e "- new-book-detector ${GREEN}is running${NC}"
nb=true
else
echo -e "- new-book-detector ${RED}is not running${NC}"
nb=false
fi
# if s6-rc -a list | grep -q 'new-book-detector'; then
# echo -e "- new-book-detector ${GREEN}is running${NC}"
# nb=true
# else
# echo -e "- new-book-detector ${RED}is not running${NC}"
# nb=false
# fi

if s6-rc -a list | grep -q 'books-to-process-detector'; then
echo -e "- books-to-process-detector ${GREEN}is running${NC}"
bp=true
if s6-rc -a list | grep -q 'cwa-ingest-service'; then
echo -e "- cwa-ingest-service ${GREEN}is running${NC}"
is=true
else
echo -e "- books-to-process-detector ${RED}is not running${NC}"
bp=false
echo -e "- cwa-ingest-service ${RED}is not running${NC}"
is=false
fi

if s6-rc -a list | grep -q 'metadata-change-detector'; then
Expand All @@ -32,9 +32,10 @@ else
mc=false
fi


echo ""

if $cs && $bs && $mc; then
if $is && $mc; then
echo -e "Calibre-Web-Automated was ${GREEN}successfully installed ${NC}and ${GREEN}is running properly!${NC}"
else
echo -e "Calibre-Web-Automated was ${RED}not installed successfully${NC}, please check the logs for more information."
Expand Down
12 changes: 6 additions & 6 deletions scripts/convert-library.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def __init__(self, args) -> None:
self.args = args

self.supported_book_formats = ['azw', 'azw3', 'azw4', 'cbz', 'cbr', 'cb7', 'cbc', 'chm', 'djvu', 'docx', 'epub', 'fb2', 'fbz', 'html', 'htmlz', 'lit', 'lrf', 'mobi', 'odt', 'pdf', 'prc', 'pdb', 'pml', 'rb', 'rtf', 'snb', 'tcr', 'txt', 'txtz']
self.hierarchy_of_succsess = ['lit', 'mobi', 'azw', 'azw3', 'fb2', 'fbz', 'azw4', 'prc', 'odt', 'lrf', 'pdb', 'cbz', 'pml', 'rb', 'cbr', 'cb7', 'cbc', 'chm', 'djvu', 'snb', 'tcr', 'pdf', 'docx', 'rtf', 'html', 'htmlz', 'txtz', 'txt']
self.hierarchy_of_success = ['lit', 'mobi', 'azw', 'azw3', 'fb2', 'fbz', 'azw4', 'prc', 'odt', 'lrf', 'pdb', 'cbz', 'pml', 'rb', 'cbr', 'cb7', 'cbc', 'chm', 'djvu', 'snb', 'tcr', 'pdf', 'docx', 'rtf', 'html', 'htmlz', 'txtz', 'txt']

self.dirs = self.get_dirs() # Dirs are assigned by user during setup
self.import_folder = f"{self.dirs['import_folder']}/"
Expand All @@ -28,7 +28,7 @@ def get_library_books(self):
epub_files = [f for f in library_files if f.endswith('.epub')]
dupe_list = []
to_convert = []
for format in self.hierarchy_of_succsess:
for format in self.hierarchy_of_success:
format_files = [f for f in library_files if f.endswith(f'.{format}')]
if len(format_files) > 0:
for file in format_files:
Expand All @@ -54,16 +54,16 @@ def convert_library(self):
filename, file_extension = os.path.splitext(file)
filename = filename.split('/')[-1]
book_id = (re.search(r'\(\d*\)', file).group(0))[1:-1]
os.system(f"cp '{file}' '/config/original-library/{filename}{file_extension}'")
os.system(f"cp '{file}' '/config/processed_books/{filename}{file_extension}'")
os.system(f"calibredb remove {book_id} --permanent --with-library '{self.library}'")
os.system(f"ebook-convert '/config/original-library/{filename}{file_extension}' '{self.import_folder}{filename}.epub'") # >>/config/calibre-web.log 2>&1
os.system(f"ebook-convert '/config/processed_books/{filename}{file_extension}' '{self.import_folder}{filename}.epub'") # >>/config/calibre-web.log 2>&1
# if self.args.setup == True:
# os.system(f"calibredb add --with-library '{self.library}' '{self.import_folder}{filename}.epub' >>/config/calibre-web.log 2>&1")
os.system(f"chown -R abc:abc '{self.library}'")
logging.info(f"[convert-library]: Conversion of {os.path.basename(file)} complete!")
self.current_book += 1
if not self.args.keep:
os.remove(f"/config/original-library/{filename}{file_extension}")
os.remove(f"/config/processed_books/{filename}{file_extension}")

def empty_import_folder(self):
os.system(f"chown -R abc:abc '{self.import_folder}'")
Expand All @@ -78,7 +78,7 @@ def main():
)

parser.add_argument('--replace', '-r', action='store_true', required=False, dest='replace', help='Replaces the old library with the new one', default=False)
parser.add_argument('--keep', '-k', action='store_true', required=False, dest='keep', help='Creates a new epub library with the old one but stores the old files in /config/original-library', default=False)
parser.add_argument('--keep', '-k', action='store_true', required=False, dest='keep', help='Creates a new epub library with the old one but stores the old files in /config/processed_books', default=False)
# parser.add_argument('-setup', action='store_true', required=False, dest='setup', help="Indicates to the function whether or not it's being ran from the setup script or manually (DO NOT USE MANUALLY)", default=False)
args = parser.parse_args()

Expand Down
Loading

0 comments on commit ae3d433

Please sign in to comment.