Skip to content

Commit

Permalink
Finished new version of CWA Convert Library function and edited unive…
Browse files Browse the repository at this point in the history
…rsal-calibre-setup service to no longer produce a verbose otput that has confused users
  • Loading branch information
crocodilestick committed Dec 19, 2024
1 parent 254124e commit f06bc09
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 65 deletions.
75 changes: 57 additions & 18 deletions root/app/calibre-web/cps/cwa_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,22 +243,62 @@ def convert_library_start(queue):
cl_process = subprocess.Popen(['python3', '/app/calibre-web-automated/scripts/convert_library.py'])
queue.put(cl_process)

def get_tmp_conversion_dir() -> str:
dirs_json_path = "/app/calibre-web-automated/dirs.json"
dirs = {}
with open(dirs_json_path, 'r') as f:
dirs: dict[str, str] = json.load(f)
tmp_conversion_dir = f"{dirs['tmp_conversion_dir']}/"

return tmp_conversion_dir

def empty_tmp_con_dir(tmp_conversion_dir) -> None:
try:
files = os.listdir(tmp_conversion_dir)
for file in files:
file_path = os.path.join(tmp_conversion_dir, file)
if os.path.isfile(file_path):
os.remove(file_path)
except Exception as e:
print_and_log(f"[convert-library]: An error occurred while emptying {tmp_conversion_dir}. See the following error: {e}")

def kill_convert_library(queue):
trigger_file = Path("/config/.kill_convert_library_trigger")
while True:
sleep(0.1)
if trigger_file.exists():
# Kill the convert_library process
cl_process = queue.get()
cl_process.terminate()
os.remove(tempfile.gettempdir() + '/convert_library.lock')
os.remove(trigger_file)
# Remove any potentially left over lock files
try:
os.remove(tempfile.gettempdir() + '/convert_library.lock')
except FileNotFoundError:
...
# Empty tmp conversion dir of half finished files
empty_tmp_con_dir(get_tmp_conversion_dir())
# Remove the trigger file that triggered this block
try:
os.remove(trigger_file)
except FileNotFoundError:
...
with open("/config/convert-library.log", 'a') as f:
f.write("\nCONVERT LIBRARY PROCESS TERMINATED BY USER")
break

@convert_library.route('/cwa-library-convert', methods=['GET'])
@convert_library.route('/cwa-convert-library-overview', methods=["GET"])
def show_convert_library_page():
return render_title_template('cwa_convert_library.html', title=_("Calibre-Web Automated - Convert Library"), page="cwa-library-convert",
target_format=CWA_DB().cwa_settings['auto_convert_target_format'].upper())

@convert_library.route('/cwa-convert-library-start', methods=["GET"])
def start_conversion():
open('/config/convert-library.log', 'w').close() # Wipe conversion log from previous runs
# Wipe conversion log from previous runs
open('/config/convert-library.log', 'w').close()
# Remove any left over kill file
try:
os.remove("/config/.kill_convert_library_trigger")
except FileNotFoundError:
...
# Queue to share the subprocess reference
process_queue = queue.Queue()
# Create and start the subprocess thread
Expand All @@ -267,18 +307,17 @@ def start_conversion():
# Create and start the kill thread
cl_kill_thread = Thread(target=kill_convert_library, args=(process_queue,))
cl_kill_thread.start()
return render_title_template('cwa_convert_library.html', title=_("Calibre-Web Automated - Convert Library"), page="cwa-library-convert",
target_format=CWA_DB().cwa_settings['auto_convert_target_format'].upper())
return redirect(url_for('convert_library.show_convert_library_page'))

@convert_library.route('/convert-library-cancel', methods=["GET"])
def cancel_convert_library():
# Create kill trigger file
open("/config/.kill_convert_library_trigger", 'w').close()
return redirect(url_for('convert_library.show_convert_library_page'))

@convert_library.route('/convert-library-status', methods=['GET', 'POST'])
@convert_library.route('/convert-library-status', methods=["GET"])
def get_status():
if request.method == "POST" and request.form['cancel_button'] == "Cancel":
open("/config/.kill_convert_library_trigger", 'w').close()
return render_title_template('cwa_convert_library.html', title=_("Calibre-Web Automated - Convert Library"), page="cwa-library-convert",
target_format=CWA_DB().cwa_settings['auto_convert_target_format'].upper())

elif request.method == "GET":
with open("/config/convert-library.log", 'r') as f:
status = f.read()
statusList = {'status':status}
return json.dumps(statusList)
with open("/config/convert-library.log", 'r') as f:
status = f.read()
statusList = {'status':status}
return json.dumps(statusList)
2 changes: 1 addition & 1 deletion root/app/calibre-web/cps/templates/admin.html
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ <h2>{{_('CWA Admin Functions⚡')}}</h2>
<a class="btn btn-default" id="check_mon_srvs" href="{{url_for('cwa_check_status.cwa_flash_status')}}">{{_('Check CWA Status')}}</a>
</div>
<div class="row form-group">
<a class="btn btn-default" id="library_convert" href="{{url_for('convert_library.start_conversion')}}">{{_('Convert Library to Target Format')}}</a>
<a class="btn btn-default" id="library_convert" href="{{url_for('convert_library.show_convert_library_page')}}">{{_('Convert Library to Target Format')}}</a>
<a class="btn btn-default" id="cwa_history" href="{{url_for('cwa_history.cwa_history_show')}}">{{_('Show CWA History')}}</a>
</div>
<div class="row form-group">
Expand Down
14 changes: 6 additions & 8 deletions root/app/calibre-web/cps/templates/cwa_convert_library.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,15 @@ <h3 style="color: whitesmoke;">CWA Library Convertor - Current Target Format - {
<div style="display: flex;
justify-content: space-between;
gap: 20px;">
<p style="font-size: xx-small;max-width: 80%;">
<p style="font-size: xx-small;max-width: 70%;">
The Library Conversion Process automatically starts upon loading this page and therefore has already started,
you can follow it's progress below. Leaving this page will not interrupt the process but you will be unable to
return to check on it's process here in the Web UI after leaving, you would then need to check it's progress
in the container's logs.</p>
<form action="{{ url_for('convert_library.get_status')}}" method="post">
<input class="btn btn-default" type="submit" name="cancel_button" value="Cancel"
style="vertical-align: top;
float: right;
width: 100px;">Cancel</button>
</form>
<div>
<a class="btn btn-default" href="{{ url_for('convert_library.cancel_convert_library') }}" style="vertical-align: top; float: right; width: 100px; margin-left: 10px;">{{_('Cancel')}}</a>
<a class="btn btn-default" href="{{ url_for('convert_library.start_conversion') }}" style="vertical-align: top; float: right; width: 100px;">{{_('Start')}}</a>
</div>
</div>
<div class="row">
<div class="logging_window" style="padding-left: 15px;
Expand Down Expand Up @@ -50,7 +48,7 @@ <h3 style="color: whitesmoke;">CWA Library Convertor - Current Target Format - {

document.getElementById("innerStatus").innerHTML = get.status.replace(/\n/g, "<br>"); // * 10 + "&percnt;"

if (get.status.includes("Done!")){
if (get.status.includes("Done!") || get.status.includes("CONVERT LIBRARY PROCESS TERMINATED BY USER")){
document.getElementById("innerStatus").innerHTML;
clearTimeout(timeout);
return false;
Expand Down
10 changes: 6 additions & 4 deletions root/etc/s6-overlay/s6-rc.d/universal-calibre-setup/run
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@ fi

export DEBIAN_FRONTEND="noninteractive"

if [[ "$(calibredb --version)" != "calibredb (calibre 7.16)" ]]; then
CALIBRE_INSTALLED_TEST="$(calibredb --version)"

if [[ $CALIBRE_INSTALLED_TEST != "calibredb (calibre 7.16)" ]]; then
echo "[universal-calibre-setup] Installing Calibre version $(cat /CALIBRE_RELEASE)..."
/app/calibre/calibre_postinstall
/app/calibre/calibre_postinstall &> /dev/null
if [[ $? == 0 ]]
then
echo "[universal-calibre-setup] Setup successful! Exiting now..."
echo "[universal-calibre-setup] Calibre setup completed successfully! Exiting now..."
else
echo "[universal-calibre-setup] Setup unsuccessful, 'calibre_postinstall' encountered an error. Exiting now..."
echo "[universal-calibre-setup] Calibre setup was unsuccessful, 'calibre_postinstall' encountered an error. Exiting now..."
fi
else
echo "[universal-calibre-setup] Skipping setup, Calibre already installed. Exiting now..."
Expand Down
67 changes: 33 additions & 34 deletions scripts/convert_library.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# import argparse
import argparse
import json
import logging
import os
Expand Down Expand Up @@ -39,7 +39,10 @@ def print_and_log(string) -> None:

# Defining function to delete the lock on script exit
def removeLock():
os.remove(tempfile.gettempdir() + '/convert_library.lock')
try:
os.remove(tempfile.gettempdir() + '/convert_library.lock')
except FileNotFoundError:
...

# Will automatically run when the script exits
atexit.register(removeLock)
Expand All @@ -59,8 +62,10 @@ def removeLock():


class LibraryConverter:
def __init__(self) -> None: #args
# self.args = args
def __init__(self, args) -> None:
self.args = args
self.verbose = args.verbose

self.db = CWA_DB()
self.cwa_settings = self.db.cwa_settings
self.target_format = self.cwa_settings['auto_convert_target_format']
Expand Down Expand Up @@ -149,7 +154,10 @@ def convert_library(self):
text=True
) as process:
for line in process.stdout: # Read from the combined stdout (which includes stderr)
print_and_log(line)
if self.verbose:
print_and_log(line)
else:
print(line)

if self.cwa_settings['auto_backup_conversions']:
shutil.copyfile(file, f"/config/processed_books/converted/{os.path.basename(file)}")
Expand Down Expand Up @@ -180,7 +188,10 @@ def convert_library(self):
text=True
) as process:
for line in process.stdout: # Read from the combined stdout (which includes stderr)
print_and_log(line)
if self.verbose:
print_and_log(line)
else:
print(line)

if self.cwa_settings['auto_backup_imports']:
shutil.copyfile(target_filepath, f"/config/processed_books/imported/{os.path.basename(target_filepath)}")
Expand Down Expand Up @@ -233,7 +244,10 @@ def convert_to_kepub(self, filepath:str ,import_format:str) -> tuple[bool, str]:
text=True
) as process:
for line in process.stdout: # Read from the combined stdout (which includes stderr)
print_and_log(line)
if self.verbose:
print_and_log(line)
else:
print(line)

if self.cwa_settings['auto_backup_conversions']:
shutil.copyfile(filepath, f"/config/processed_books/converted/{os.path.basename(filepath)}")
Expand All @@ -255,7 +269,10 @@ def convert_to_kepub(self, filepath:str ,import_format:str) -> tuple[bool, str]:
text=True
) as process:
for line in process.stdout: # Read from the combined stdout (which includes stderr)
print_and_log(line)
if self.verbose:
print_and_log(line)
else:
print(line)

if self.cwa_settings['auto_backup_conversions']:
shutil.copy2(filepath, f"/config/processed_books/converted")
Expand Down Expand Up @@ -293,35 +310,17 @@ def set_library_permissions(self):
except subprocess.CalledProcessError as e:
print_and_log(f"[convert-library]: ({self.current_book}/{len(self.to_convert)}) An error occurred while attempting to recursively set ownership of {self.library_dir} to abc:abc. See the following error:\n{e}")

# def process(self):
# """ Allows LibraryConverter to be ran from an import """
# if len(self.to_convert) > 0:
# self.convert_library()
# else:
# print_and_log("[convert-library]: No books found in library without a copy in the target format. Exiting now...")
# logging.info("FIN")
# sys.exit(0)

# print_and_log(f"\n[convert-library]: Library conversion complete! {len(self.to_convert)} books converted! Exiting now...")
# logging.info("FIN")
# sys.exit(0)
def main():
parser = argparse.ArgumentParser(
prog='convert-library',
description='Made for the purpose of converting ebooks in a calibre library to the users specified target format (default epub)'
)

parser.add_argument('--verbose', '-v', action='store_true', required=False, dest='verbose', help='When passed, the output from the ebook-convert command will be included in what is shown to the user in the Web UI', default=False)
args = parser.parse_args()

def main():
# parser = argparse.ArgumentParser(
# prog='convert-library',
# description='Made for the purpose of converting ebooks in a calibre library not in epub format, to epub format'
# )

# 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/processed_books', default=False)
# args = parser.parse_args()

# if not args.replace and not args.keep:
# print("[convert-library]: You must specify either the --replace/-r or --keep/-k flag")
# sys.exit(0)
# else:
converter = LibraryConverter() # args
converter = LibraryConverter(args)
if len(converter.to_convert) > 0:
converter.convert_library()
else:
Expand Down

0 comments on commit f06bc09

Please sign in to comment.