imgconv for lod

This commit is contained in:
gauthiier 2023-08-03 11:14:49 +02:00
parent 3e6c8aa179
commit 038b5a6bf1
5 changed files with 164 additions and 86 deletions

92
gen.py
View File

@ -1,50 +1,67 @@
#!/usr/bin/env python #!/usr/bin/env python
import argparse, json, sys, markdown, shutil, json, re, pathlib, shutil import argparse, json, sys, markdown, shutil, json, re, pathlib, shutil
import utils.imgconv
input_dir = None input_dir = None
output_dir = None output_dir = None
style = None style = None
(W, H, FMT) = (None, None, None)
codebase = pathlib.Path(__file__).parent.absolute() codebase = pathlib.Path(__file__).parent.absolute()
def translate_index_header(txt, dirname): def translate_index_header(txt, dirname):
href = None sections = txt.count('- - -')
sections = txt.count('- - -');
if sections == 0: if sections == 0:
# not following the normal template -> direct html # not following the normal template -> direct html
txt = txt.replace('data/', dirname + '/'); #<--- replace reference to data/ txt = txt.replace('data/', dirname + '/') #<--- replace reference to data/
return txt return txt
elif sections == 1: elif sections == 1:
[text, link] = txt.split('- - -'); [text, link] = txt.split('- - -')
elif sections == 2:
[text, link, href] = txt.split('- - -');
text_md = markdown.markdown(text); text_md = markdown.markdown(text)
link_md = markdown.markdown(link); link_info = json.loads(link)
# revise this - perhaps with a better
link_md = link_md.replace('data/', dirname + '/');
dirpath = pathlib.Path(dirname)
img_name = pathlib.Path(link_info['img']).name
img_path = dirpath / img_name
img_resize_path = dirpath / "img-resize" / img_name
picture_el = emit_picture(str(img_path), str(img_resize_path))
table = codebase / "templates/<table>" table = codebase / "templates/<table>"
with table.open(encoding="utf-8") as fp: with table.open(encoding="utf-8") as fp:
out = fp.read() out = fp.read()
out = out.replace('[[text_md]]', text_md); out = out.replace('[[text_md]]', text_md);
out = out.replace('[[link_md]]', link_md); out = out.replace('[[link_md]]', picture_el);
if href: if link_info['href']:
href = href.replace('data/', dirname + '/'); if link_info['href'] == "data":
out = "<a " + href + ">" + out + "</a>"; href = dirname + "/"
else:
href = link_info['href']
out = "<a href='" + href + "'>" + out + "</a>";
return out return out
def escape_date(dirname): def escape_date(dirname):
return re.sub('^20\d{2}?.', '', dirname) return re.sub('^20\d{2}?.', '', dirname)
def emit_picture(src_full, src_resize):
return f'''<picture>
<source media="(max-width: 799px)" srcset="{src_resize}" />
<source media="(min-width: 800px)" srcset="{src_full}" />
<img src="{src_full}" />
</picture>'''
def emit_img(file: pathlib.Path, data_dir: pathlib.Path): def emit_img(file: pathlib.Path, data_dir: pathlib.Path):
## this is where LOD can be applied ## this is where LOD can be applied
resize_dir = data_dir / "img-resize"
resize_dir.mkdir(parents=True, exist_ok=True)
filepath = data_dir / file
resize_file = utils.imgconv.convert(filepath, (W, H, FMT), resize_dir)
return f'<a href="{file}"><img src="{file}" /></a>' return f'<a href="{file}">' + emit_picture(str(file), "img-resize/" + resize_file.name) + '</a>'
def emit_video_mp4(file: pathlib.Path, data_dir: pathlib.Path): def emit_video_mp4(file: pathlib.Path, data_dir: pathlib.Path):
return f'<video controls><source src="{file}" type="video/mp4"</video>' return f'<video controls><source src="{file}" type="video/mp4"</video>'
@ -93,6 +110,7 @@ def default(file, data_dir):
content_map = { content_map = {
'.png': emit_img, '.png': emit_img,
'.jpg': emit_img, '.jpg': emit_img,
'.jpeg': emit_img,
'.m4v': emit_video_mp4, '.m4v': emit_video_mp4,
'.mov': emit_video_mp4, '.mov': emit_video_mp4,
'.mp4': emit_video_mp4, '.mp4': emit_video_mp4,
@ -134,20 +152,23 @@ def index_content(dir_name: str, data_dir: pathlib.Path, index_txt: pathlib.Path
for i in content_index: for i in content_index:
f = data_dir / i f = data_dir / i
if f.is_file(): if f.is_file():
files.append(i); files.append(data_dir / i);
else: else:
files += [pathlib.Path(a.name) for a in list(data_dir.glob(i))] files += [pathlib.Path(a.name) for a in list(data_dir.glob(i))]
# sort files? # sort files?
files.sort() files.sort()
for j in files: for j in files:
ext = j.suffix.lower() ext = j.suffix.lower()
if ext in content_map: if ext in content_map:
element = content_map[ext](j, data_dir); element = content_map[ext](j, data_dir);
if element: if element:
content += "<li>" + element + "</li>" + "\n"; content += "<li>" + element + "</li>" + "\n";
# check if there is an html file existing already. if so use that one.
html = template.replace('[[content]]', content).replace('[[dir]]', str(dir_name)); html = template.replace('[[content]]', content).replace('[[dir]]', str(dir_name));
try: try:
@ -180,6 +201,7 @@ if __name__ == '__main__':
p.add_argument('--output', "-o", help='output directory'); p.add_argument('--output', "-o", help='output directory');
p.add_argument('--style', "-y", default="+++", help='css style, ico, etc.'); p.add_argument('--style', "-y", default="+++", help='css style, ico, etc.');
p.add_argument("--settings", "-s", default=".static/settings.json", help="Settings file (default: .static/settings.json") p.add_argument("--settings", "-s", default=".static/settings.json", help="Settings file (default: .static/settings.json")
p.add_argument('--format', '-f', default="1000x1000", help='img output formats (ex. 1000x)');
p.add_argument('--clean', help='cleans the output directory'); p.add_argument('--clean', help='cleans the output directory');
args = p.parse_args(); args = p.parse_args();
@ -201,15 +223,20 @@ if __name__ == '__main__':
if inputdir is not None: if inputdir is not None:
input_dir = inputdir; input_dir = inputdir;
else: else:
print(f"Input directory {args.input} is not a directory... Aborting.") sys.exit(f"Input directory {args.input} is not a directory... Aborting.")
sys.exit(1)
if args.output: if args.output:
outputdir = check_dir_exists(args.output, create=True) outputdir = check_dir_exists(args.output, create=True)
if outputdir is not None: if outputdir is not None:
output_dir = outputdir; output_dir = outputdir;
else: else:
print(f"Output directory {args.output} is not a directory... Aborting.") sys.exit(f"Output directory {args.output} is not a directory... Aborting.")
sys.exit(1)
if args.format:
(W, H, FMT) = utils.imgconv.parse_format(args.format)
if not FMT:
sys.exit(f"Format {str(args.format)} is not valid. Aborting.")
if style is not None: if style is not None:
style_dir = codebase / f"styles/{style}" style_dir = codebase / f"styles/{style}"
@ -217,8 +244,7 @@ if __name__ == '__main__':
style = args.style style = args.style
if input_dir is None: if input_dir is None:
print(f"Error with input directory... Aborting.") sys.exit(f"Error with input directory... Aborting.")
sys.exit(1)
if output_dir is None: if output_dir is None:
print(f"No output directory.") print(f"No output directory.")
@ -236,7 +262,6 @@ if __name__ == '__main__':
except: except:
print(f"error erasing {output_dir}. Continuing.") print(f"error erasing {output_dir}. Continuing.")
print('1/3 - Configuring'); print('1/3 - Configuring');
# main index template # main index template
@ -273,11 +298,9 @@ if __name__ == '__main__':
section_indx_txt = datadir / "index.txt" section_indx_txt = datadir / "index.txt"
section_desc_txt = datadir / "desc.txt" section_desc_txt = datadir / "desc.txt"
out_index = None
if section_indx_txt.is_file() or section_desc_txt.is_file(): if section_indx_txt.is_file() or section_desc_txt.is_file():
out_index = index_content(dirname, d, section_indx_txt, section_desc_txt, section_indx_template_str); out_index = index_content(dirname, datadir, section_indx_txt, section_desc_txt, section_indx_template_str)
if out_index is None:
continue
if output_dir is not None: if output_dir is not None:
out_datadir = output_dir / dirname out_datadir = output_dir / dirname
@ -298,11 +321,12 @@ if __name__ == '__main__':
continue continue
# copy index after (since index.html might be lurking in content dirs) # copy index after (since index.html might be lurking in content dirs)
try: if out_index:
shutil.copy2(out_index, out_datadir) try:
except: shutil.copy2(out_index, out_datadir)
print(f"error copying {out_index} to {out_datadir}. Continuing.") except:
continue print(f"error copying {out_index} to {out_datadir}. Continuing.")
continue
print('3/3 - Generating ouput'); print('3/3 - Generating ouput');

View File

@ -21,7 +21,8 @@ case $1 in
;; ;;
run) run)
echo "running" echo "running"
# source venv/bin/activate source venv/bin/activate
export MAGICK_HOME=/opt/homebrew/Cellar/imagemagick/7.1.1-13
# exec python $2 "${@:3}" # exec python $2 "${@:3}"
esac esac

View File

@ -20,57 +20,19 @@
<pre> <pre>
-----BEGIN PGP PUBLIC KEY BLOCK----- -----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBFwRHKQBEACm4RTJEAvqrczYPNDtu08mB7PQ6mouSgWNLxPIY0QWNEhZJKLE mDMEZLoz/RYJKwYBBAHaRw8BAQdAsuOzLRb5SR4kJKpiFcP3XhPYyrcm8lqJQCzq
bPj8eE5sG6gSaNTePC0RVBZDhNC9YXHJiMPaa2Av4LBK+xQSi4oMxB3qaWzRpNm1 Kgq0cau0RURhdmlkIEdhdXRoaWVyICg3ZSBzw6lyaWUsIGRlcyBtb3RzIMOpc290
1iL7SKNwBcIVdBYOyhWl+AyOlMUIdOsDpC8Zo3qgTDaW45tn+DjvqY5yA+voNwln w6lyaXF1ZXMpIDxkQGdhdXRoaWllci5pbmZvPoiZBBMWCgBBFiEEdUjrpohoTnvh
tk1Fwftl0tPeP74SYXzVLNnED1+7QZGKoXmlkrXr5dKVa+OXardeI2dnIlAclibG RwQPqCZfthzndOcFAmS6M/0CGwMFCQWjmoAFCwkIBwICIgIGFQoJCAsCBBYCAwEC
ofadA4q9g2MXhngh09uXxAqWH9Wz1709zvA5tD8eGSBKmPdWo21F/De5Qj/dNwTt HgcCF4AACgkQqCZfthzndOex0gEAqZKLSpIX57S0EzVrpazSYbMtRppsnndvWACD
eAIZlnoNjrnL7TGyUhY3xy1hNOkhAI0gXWaWjZq7Ww1/GWZautQtFF8FpCPcxAMh w0TdFd4A/jKxS2FCCbUeMNwSz8iRjGRYiTZtJytQ6W3SKEQlyW8CuDgEZLoz/RIK
OIL1x1rBi5ontwsAwK1ntGV49ldAEEnR53MD4Kq/L65k9p6Wjiy38SsJAUvC/WRf KwYBBAGXVQEFAQEHQFI6QyMPtYSOXCbLaPxaR8jpzjg1tqJZA4vvpOVOfdZsAwEI
qjiNATJjgGn+Nex6QAZoNos8g5J2wR01ThlffrcW7d78iJZdkCH7AMbfu98J4j4p B4h+BBgWCgAmFiEEdUjrpohoTnvhRwQPqCZfthzndOcFAmS6M/0CGwwFCQWjmoAA
FXzCxCULRgFxS9K0yU+DndBHqjrhEum83JB6BTH3oUZRKAc/RYVKzS0ZtmIRrOCH CgkQqCZfthzndOdPrAD+NgSQRfndE2d9IiFAQDP7UNbqh0e731/ktyg2mwukudUB
Iz7oOKKBqze5mrPIaFkewfPu27sArirZGvXRoyIHoLFutRsD9UFFjuyF+rLns22K AM+9BMj8ZAV+2cDSlf7Muk+SCnYd/uCy1ulJ16vKYJAC
qaWWyZdNhh2qFT6JtgLCFV9r5bS9k3la/KN369hKmfkUcAm9a0xzP4ykuQARAQAB =QFke
tEdEYXZpZCBHYXV0aGllciAoMTRlIHPDqXJpZSwgZGUgbGEgZG91YmxlIGNhdXNh
bGl0w6kpIDxkQGdhdXRoaWllci5pbmZvPokCVAQTAQgAPhYhBO1mEGgZ+NT8QRfy -----END PGP PUBLIC KEY BLOCK-----</pre>
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
=rlRS
-----END PGP PUBLIC KEY BLOCK-----
</pre>
<br> <br>
</div> </div>
</body> </body>

View File

@ -31,12 +31,21 @@ table td h1 {
margin-bottom: 0.2em; margin-bottom: 0.2em;
} }
h1 a:hover, h1 a:active {
text-decoration: none;
}
table td p { table td p {
bborder: 1px red solid; bborder: 1px red solid;
margin-top: 0.1em; margin-top: 0.1em;
margin-bottom: 0.4em; margin-bottom: 0.4em;
} }
a:hover p, a:active p {
text-decoration: none;
}
table tr { table tr {
text-align: center; text-align: center;

82
utils/imgconv.py Normal file
View File

@ -0,0 +1,82 @@
import argparse, pathlib, subprocess, sys
from wand.image import Image
supported_glob = "[jpJP][npNP][egEG]"
def sanity_check_system():
r = subprocess.call("magick -version", shell=True) == 0
if not r:
sys.exit("ImageMagick not installed. Aborting...")
def parse_format(format_str):
fmt = format_str.lower()
if 'x' in fmt:
w_h = fmt.split('x')
w = int(w_h[0]) if w_h[0] != '' else 0
h = int(w_h[1]) if w_h[1] != '' else 0
return(w, h, fmt)
return (None, None, None)
def convert(filepath : pathlib.Path, fmt : tuple, output_dir: pathlib.Path):
(w, h, f) = fmt
# img exists?
output = output_dir / filepath.name
if output.exists() and output.is_file():
with Image(filename=str(output)) as img:
if w > 0 and img.width == w or h > 0 and img.height == h:
return output
with Image(filename=str(filepath)) as img:
print(f". converting {filepath}")
print(f" > {img.size}")
img.resolution = (72, 72)
if w > 0 and img.width > w or h > 0 and img.height > h:
img.transform(resize=f)
print(f" > {img.size}")
img.save(filename=str(output))
return output
def convert_all(input_dir: pathlib.Path, fmt : tuple, output_dir: pathlib.Path):
img_files = input_dir.glob("*." + supported_glob + "*")
for i in img_files:
convert(i, fmt, output_dir)
if __name__ == '__main__':
p = argparse.ArgumentParser(description='Converts images files to other formats (using wand/ImageMagick)');
p.add_argument('-i', '--input', help='input directory');
p.add_argument('-o', '--output', help='output directory');
p.add_argument('-f', '--format', help='output formats (ex. 1000x)');
sanity_check_system()
args = p.parse_args()
if not args.format:
sys.exit("No formats specified. Aborting.")
input_dir = pathlib.Path(".")
if args.input:
input_dir = pathlib.Path(args.input)
if not input_dir.exists() or not input_dir.is_dir():
sys.exit(f"Input {str(input_dir)} is not a directory. Aborting.")
output_dir = input_dir / "img-resize"
if args.output:
output_dir = pathlib.Path(args.output)
output_dir.mkdir(parents=True, exist_ok=True)
(w, h, fmt) = parse_format(args.format)
if not fmt:
sys.exit(f"Format {str(args.format)} is not valid. Aborting.")
img_files = input_dir.glob("*." + supported_glob + "*")
for i in img_files:
convert(i, (w, h, fmt), output_dir)