diff --git a/.version b/.version index fd06a92..3b26524 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -2.3.4 \ No newline at end of file +2.3.5 \ No newline at end of file diff --git a/README.md b/README.md index f34d4ec..63ab279 100644 --- a/README.md +++ b/README.md @@ -44,20 +44,20 @@ The script supports several command-line options to customize its behavior. Belo ### Options -- `-h, --help`: Show the help message and exit. -- `-p ROOT, --root-directory ROOT`: Specify the root folder where the images are stored. This option is required. -- `-w URL, --web-root-url URL`: Specify the base URL for the web root of the image hosting site. This option is required. -- `-t TITLE, --site-title TITLE`: Specify the title of the image hosting site. This option is required. -- `-r, --regenerate-thumbnails`: Regenerate thumbnails even if they already exist. -- `-n, --non-interactive-mode`: Run in non-interactive mode, disabling progress bars. -- `-l LICENSE, --license-type LICENSE`: Specify the license type for the images. Choices are `cc-zero`, `cc-by`, `cc-by-sa`, `cc-by-nd`, `cc-by-nc`, `cc-by-nc-sa`, and `cc-by-nc-nd`. - `-a AUTHOR, --author-name AUTHOR`: Specify the name of the author of the images. Default is "Author". - `-e EXTENSION, --file-extensions EXTENSION`: Specify the file extensions to include. This option can be specified multiple times. +- `-l LICENSE, --license-type LICENSE`: Specify the license type for the images. Choices are `cc-zero`, `cc-by`, `cc-by-sa`, `cc-by-nd`, `cc-by-nc`, `cc-by-nc-sa`, and `cc-by-nc-nd`. +- `-m, --web-manifest`: Generate a web manifest file. +- `-n, --non-interactive-mode`: Run in non-interactive mode, disabling progress bars. +- `-p ROOT, --root-directory ROOT`: Specify the root folder where the images are stored. **(This option is required)**. +- `-t TITLE, --site-title TITLE`: Specify the title of the image hosting site. **(This option is required)**. +- `-w URL, --web-root-url URL`: Specify the base URL for the web root of the image hosting site. **(This option is required)**. +- `--exclude-folder FOLDER`: Specify folders to exclude from processing. This option can be specified multiple times. +- `--ignore-other-files`: Ignore files that do not match the specified extensions. +- `--regenerate-thumbnails`: Regenerate thumbnails even if they already exist. +- `--reread-metadata`: Reread image metadata if it already exists. - `--theme-path PATH`: Specify the path to the CSS theme file. Default is the provided default theme. - `--use-fancy-folders`: Enable fancy folder view instead of the default Apache directory listing. -- `--ignore-other-files`: Ignore files that do not match the specified extensions. -- `--exclude-folder FOLDER`: Specify folders to exclude from processing. This option can be specified multiple times. -- `-m, --web-manifest`: Generate a web manifest file. ### Examples diff --git a/StaticGalleryBuilder.code-workspace b/StaticGalleryBuilder.code-workspace index 29ec569..09ea209 100644 --- a/StaticGalleryBuilder.code-workspace +++ b/StaticGalleryBuilder.code-workspace @@ -39,7 +39,8 @@ "cc-by-nc-sa", "-n", "-m", - "-r" + "--regenerate-thumbnails", + "--reread-metadata", ], "console": "integratedTerminal", "name": "Testfolder", @@ -62,7 +63,8 @@ "--web-manifest", "-n", "-m", - "-r", + "--regenerate-thumbnails", + "--reread-metadata", ], "console": "integratedTerminal", "name": "woek", diff --git a/builder.py b/builder.py index b6fe209..9457215 100755 --- a/builder.py +++ b/builder.py @@ -196,11 +196,13 @@ def main() -> None: lock_file = os.path.join(args.root_directory, ".lock") if os.path.exists(lock_file): print("Another instance of this program is running.") - logger.info("nother instance of this program is running") + logger.error("another instance of this program is running") exit() try: Path(lock_file).touch() + if args.reread_metadata: + logger.warning("reread metadata flag is set to true, all image metadata will be reread") if args.regenerate_thumbnails: logger.warning("regenerate thumbnails flag is set to true, all thumbnails will be regenerated") if os.path.exists(os.path.join(args.root_directory, ".thumbnails")): diff --git a/files/pswp/default-skin/default-skin.css b/files/pswp/default-skin/default-skin.css index f99db1b..a4676cc 100644 --- a/files/pswp/default-skin/default-skin.css +++ b/files/pswp/default-skin/default-skin.css @@ -272,13 +272,14 @@ a.pswp__share--download:hover { color: #BBB; } .pswp__caption__center { - text-align: left; + text-align: center; max-width: 420px; margin: 0 auto; font-size: 13px; padding: 10px; line-height: 20px; - color: #CCC; } + color: #CCC; + font-weight: bold; } .pswp__caption--empty { display: none; } diff --git a/modules/argumentparser.py b/modules/argumentparser.py index cd62c5a..18f8655 100644 --- a/modules/argumentparser.py +++ b/modules/argumentparser.py @@ -58,6 +58,7 @@ class Args: license_type: Optional[str] non_interactive_mode: bool regenerate_thumbnails: bool + reread_metadata: bool root_directory: str site_title: str theme_path: str @@ -75,6 +76,7 @@ class Args: result["license_type"] = self.license_type result["non_interactive_mode"] = self.non_interactive_mode result["regenerate_thumbnails"] = self.regenerate_thumbnails + result["reread_metadata"] = self.reread_metadata result["root_directory"] = self.root_directory result["site_title"] = self.site_title result["theme_path"] = self.theme_path @@ -105,12 +107,13 @@ def parse_arguments(version: str) -> Args: parser.add_argument("-m", "--web-manifest", help="Generate a web manifest file.", action="store_true", default=False, dest="generate_webmanifest") parser.add_argument("-n", "--non-interactive-mode", help="Run in non-interactive mode, disabling progress bars.", action="store_true", default=False, dest="non_interactive_mode") parser.add_argument("-p", "--root-directory", help="Root directory containing the images.", required=True, type=str, dest="root_directory", metavar="ROOT") - parser.add_argument("-r", "--regenerate-thumbnails", help="Regenerate thumbnails even if they already exist.", action="store_true", default=False, dest="regenerate_thumbnails") parser.add_argument("-t", "--site-title", help="Title of the image hosting site.", required=True, type=str, dest="site_title", metavar="TITLE") parser.add_argument("-w", "--web-root-url", help="Base URL of the web root for the image hosting site.", required=True, type=str, dest="web_root_url", metavar="URL") parser.add_argument("--exclude-folder", help="Folders to exclude from processing, globs supported (can be specified multiple times).", action="append", dest="exclude_folders", metavar="FOLDER") parser.add_argument("--generate-help-preview", action=HelpPreviewAction, path="help.svg", ) parser.add_argument("--ignore-other-files", help="Ignore files that do not match the specified extensions.", action="store_true", default=False, dest="ignore_other_files") + parser.add_argument("--regenerate-thumbnails", help="Regenerate thumbnails even if they already exist.", action="store_true", default=False, dest="regenerate_thumbnails") + parser.add_argument("--reread-metadata", help="Reread image metadata", action="store_true", default=False, dest="reread_metadata") parser.add_argument("--theme-path", help="Path to the CSS theme file.", default=DEFAULT_THEME_PATH, type=str, dest="theme_path", metavar="PATH") parser.add_argument("--use-fancy-folders", help="Enable fancy folder view instead of the default Apache directory listing.", action="store_true", default=False, dest="use_fancy_folders") parser.add_argument("--version", action="version", version=f"%(prog)s {version}") @@ -125,6 +128,7 @@ def parse_arguments(version: str) -> Args: license_type=parsed_args.license_type, non_interactive_mode=parsed_args.non_interactive_mode, regenerate_thumbnails=parsed_args.regenerate_thumbnails, + reread_metadata=parsed_args.reread_metadata, root_directory=parsed_args.root_directory, site_title=parsed_args.site_title, theme_path=parsed_args.theme_path, diff --git a/modules/generate_html.py b/modules/generate_html.py index 611fbd1..50c26e0 100644 --- a/modules/generate_html.py +++ b/modules/generate_html.py @@ -3,6 +3,7 @@ import urllib.parse import fnmatch import json from typing import Any, Dict, List, Tuple +from datetime import datetime import numpy as np from tqdm.auto import tqdm @@ -103,7 +104,7 @@ def get_image_info(item: str, folder: str) -> Dict[str, Any]: tag = ExifTags.TAGS.get(tag_id, tag_id) content = exifdatas.get(tag_id) if isinstance(content, bytes): - content = content.hex(" ") + content = "0x" + content.hex() if isinstance(content, TiffImagePlugin.IFDRational): content = content.limit_rational(1000000) if isinstance(content, tuple): @@ -113,6 +114,8 @@ def get_image_info(item: str, folder: str) -> Dict[str, Any]: newtuple = newtuple + (i.limit_rational(1000000),) if newtuple: content = newtuple + if tag in ["DateTime", "DateTimeOriginal", "DateTimeDigitized"]: + content = datetime.strptime(content, "%Y:%m:%d %H:%M:%S").strftime("%Y-%m-%d %H:%M:%S") exifdata[tag] = content if "Orientation" in exifdata and exifdata["Orientation"] in [6, 8]: logger.info("image is rotated", extra={"file": file}) @@ -122,7 +125,7 @@ def get_image_info(item: str, folder: str) -> Dict[str, Any]: del exifdata[key] return {"width": width, "height": height, "exifdata": exifdata} else: - return {"width": width, "height": height} + return {"width": width, "height": height, "exifdata": None} def process_image(item: str, folder: str, _args: Args, baseurl: str, sizelist: Dict[str, Dict[str, int]], raw: List[str]) -> Dict[str, Any]: @@ -141,7 +144,7 @@ def process_image(item: str, folder: str, _args: Args, baseurl: str, sizelist: D Dict[str, Any]: Dictionary containing image details for HTML rendering. """ extsplit = os.path.splitext(item) - if item not in sizelist or _args.regenerate_thumbnails: + if item not in sizelist or _args.reread_metadata: sizelist[item] = get_image_info(item, folder) image = { @@ -150,6 +153,7 @@ def process_image(item: str, folder: str, _args: Args, baseurl: str, sizelist: D "name": item, "width": sizelist[item]["width"], "height": sizelist[item]["height"], + "exifdata": sizelist[item]["exifdata"], } path = os.path.join(_args.root_directory, ".thumbnails", baseurl, item + ".jpg") if not os.path.exists(path) or _args.regenerate_thumbnails: diff --git a/templates/index.html.j2 b/templates/index.html.j2 index 65f158a..dd21ae7 100644 --- a/templates/index.html.j2 +++ b/templates/index.html.j2 @@ -147,7 +147,11 @@ var pswpElement = document.querySelectorAll('.pswp')[0]; var items = [ {%- for image in allimages %} + {%- if image.exifdata.DateTime %} + { src: "{{ image.url }}", w: {{ image.width }}, h: {{ image.height }}, msrc: "{{ image.thumbnail }}", title: "Captured: {{ image.exifdata.DateTime }}" }, + {%- else %} { src: "{{ image.url }}", w: {{ image.width }}, h: {{ image.height }}, msrc: "{{ image.thumbnail }}" }, + {%- endif %} {%- endfor %} ]; var re = /pid=(\d+)/;