rewrite jxl-restore -> jxl-convert

Signed-off-by: Martin Matous <m@matous.dev>
This commit is contained in:
Martin Matous 2023-09-24 02:45:15 +02:00
parent acd336e659
commit 70b69e1f8c
Signed by: mmatous
GPG key ID: 8BED4CD352953224
3 changed files with 75 additions and 46 deletions

View file

@ -90,17 +90,14 @@ Dependencies: openssl
Usage: ??? Usage: ???
## jxl-restore.py ## jxl-convert.py
Check whether JPEG version of .jxl exists, remove .jxl if does. Recursively convert jpgs to jxls with additional checks.
Attempt at rescuing collection where conversion got messed up.
Will fix one day. Maybe. Status: one-off
Status: ancient one-off, broken Dependencies: libjxl
Dependencies: None Usage: `./jxl-convert.py /path/to/pics`
Usage: None
## invoke-magic.bat ## invoke-magic.bat

70
jxl-convert.py Executable file
View file

@ -0,0 +1,70 @@
#!/usr/bin/env python3
# 3rd-party sw: cjxl (libjxl)
import itertools
import subprocess
import sys
from pathlib import Path
from typing import Final
source_dir: Final = Path(sys.argv[1])
if len(sys.argv) > 2:
backup_dir: Final = Path(sys.argv[2])
def check_source_against_convert(source_dir: Path) -> None:
for jxl in source_dir.rglob('*.jxl'):
has_original = jxl.with_suffix('.jpg').exists() or jxl.with_suffix('.JPG').exists()
if not has_original:
print(f'Source image for {jxl} has been lost')
def check_source_against_backup(source_dir: Path, backup_dir: Path) -> None:
pics_src = { p.relative_to(source_dir) for p in source_dir.rglob('*.JPG') }
pics_src |= { p.relative_to(source_dir) for p in source_dir.rglob('*.jpg') }
pics_bak = { p.relative_to(backup_dir) for p in backup_dir.rglob('*.JPG') }
pics_bak |= { p.relative_to(backup_dir) for p in backup_dir.rglob('*.jpg') }
diff = pics_src - pics_bak
if diff:
print('Source contains the following additional images:\n', '\n'.join(map(str, diff)))
diff = pics_bak - pics_src
if diff:
print('Backup contains the following additional images:\n', '\n'.join(map(str, diff)))
def check_successful_conversion(source_dir: Path) -> None:
pics_src = itertools.chain(source_dir.rglob('*.jpg'), source_dir.rglob('*.JPG'))
for jpg in pics_src:
jxl = jpg.with_suffix('.jxl')
if not jxl.exists():
print(f'Converted counterpart for {jpg} does not exist')
def convert(source_dir: Path) -> None:
pics_src_it = itertools.chain(source_dir.rglob('*.jpg'), source_dir.rglob('*.JPG'))
# set offset to start from image #offset (e.g. in case of a previous error)
# e.g. offset = 5 will start with converting 5th image
offset = 0
pics_src = list(sorted(pics_src_it))[offset:]
for i, jpg in enumerate(pics_src):
jxl = jpg.with_suffix('.jxl')
cmd = ['cjxl', '-v', '--lossless_jpeg=1', '--effort=9', '--brotli_effort=11', jpg, jxl]
try:
subprocess.run(cmd, check=True, capture_output=True, encoding='utf-8') # type: ignore[arg-type]
except subprocess.CalledProcessError as ex:
print(f'ERR processing file #{i + offset} {jpg}: {ex}')
print(f'cjxl says: {ex.stderr}\n{ex.stdout}')
sys.exit(ex.returncode)
except Exception as ex:
print(f'ERR unexpected: {ex}')
sys.exit(1)
print(f'Converted #{i + offset} {jpg}')
# check_source_against_convert(source_dir)
# check_source_against_backup(source_dir, second_dir)
convert(source_dir)
# check_successful_conversion(source_dir)

View file

@ -1,38 +0,0 @@
#!/usr/bin/env python
import os
import shutil
import subprocess
import sys
from pathlib import Path
from typing import Final
source: Final = Path(sys.argv[1])
dest: Final = Path(sys.argv[2])
def find_source_jpg(dest_name: Path) -> Path:
ext_list = ['.jpg', '.jpeg', '.JPG', '.JPEG']
for ext in ext_list:
res = (Path(source) / relative_path / (dest_name + ext))
if os.path.exists(dest_file_path):
return res
raise RuntimeError('No original found', dest_name)
for dest_root, dirs, files in os.walk(dest):
for name in files:
dest_name, dest_ext = os.path.splitext(name)
if dest_ext.lower() != '.jxl':
continue
dest_file_path = (Path(dest_root) / (dest_name + '.jpg'))
print('scanning for ', dest_file_path, '\n')
if os.path.exists(dest_file_path): # both .jxl and jpg exist
print(dest_file_path, ' already exists\n')
continue
relative_path = os.path.relpath(dest_root, dest)
print('relapath ', relative_path, '\n')
src_file_path = find_source_jpg(dest_name)
shutil.copy2(src_file_path, dest_file_path)
print('restored ', dest_file_path, ' from ', src_file_path, '\n')
#dest_jxl = (Path(dest_root) / (dest_name + '.jxl'))
#os.remove(dest_jxl)
#print('deleted ', dest_jxl, '\n')