mirror of
https://github.com/greflm13/StaticGalleryBuilder.git
synced 2026-02-05 11:09:26 +00:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
bce51dc3d6
|
|||
| 57250b3adc | |||
| 08895902ec |
43
builder.py
43
builder.py
@@ -3,7 +3,6 @@ import os
|
|||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import shutil
|
import shutil
|
||||||
import fnmatch
|
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
import urllib.request
|
import urllib.request
|
||||||
from multiprocessing import Pool, freeze_support
|
from multiprocessing import Pool, freeze_support
|
||||||
@@ -161,37 +160,6 @@ def generate_thumbnail(arguments: tuple[str, str, str]) -> None:
|
|||||||
logger.debug("thumbnail already exists for %s", item, extra={"path": image})
|
logger.debug("thumbnail already exists for %s", item, extra={"path": image})
|
||||||
|
|
||||||
|
|
||||||
def get_total_folders(folder: str, _args: Args, _total: int = 0) -> int:
|
|
||||||
"""
|
|
||||||
Recursively count the total number of folders to be processed.
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
-----------
|
|
||||||
folder : str
|
|
||||||
The current folder being processed.
|
|
||||||
_args : Args
|
|
||||||
Parsed command-line arguments.
|
|
||||||
_total : int, optional
|
|
||||||
The running total of folders, default is 0.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
--------
|
|
||||||
int
|
|
||||||
The total number of folders.
|
|
||||||
"""
|
|
||||||
_total += 1
|
|
||||||
pbardict["traversingbar"].desc = f"Traversing filesystem - {folder}"
|
|
||||||
pbardict["traversingbar"].update(1)
|
|
||||||
|
|
||||||
items = sorted(os.listdir(folder))
|
|
||||||
for item in items:
|
|
||||||
if item not in EXCLUDES and os.path.isdir(os.path.join(folder, item)) and not item.startswith("."):
|
|
||||||
if item not in _args.exclude_folders and not any(fnmatch.fnmatchcase(os.path.join(folder, item), exclude) for exclude in _args.exclude_folders):
|
|
||||||
logger.debug("Found folder %s in %s", item, folder)
|
|
||||||
_total = get_total_folders(os.path.join(folder, item), _args, _total)
|
|
||||||
return _total
|
|
||||||
|
|
||||||
|
|
||||||
def main(args) -> None:
|
def main(args) -> None:
|
||||||
"""
|
"""
|
||||||
Main function to process images and generate a static image hosting website.
|
Main function to process images and generate a static image hosting website.
|
||||||
@@ -235,20 +203,13 @@ def main(args) -> None:
|
|||||||
if args.non_interactive_mode:
|
if args.non_interactive_mode:
|
||||||
logger.info("generating HTML files")
|
logger.info("generating HTML files")
|
||||||
print("Generating HTML files...")
|
print("Generating HTML files...")
|
||||||
thumbnails = list_folder(0, args.root_directory, args.site_title, args, raw, VERSION, logo)
|
thumbnails = list_folder(args.root_directory, args.site_title, args, raw, VERSION, logo)
|
||||||
with Pool(os.cpu_count()) as pool:
|
with Pool(os.cpu_count()) as pool:
|
||||||
logger.info("generating thumbnails")
|
logger.info("generating thumbnails")
|
||||||
print("Generating thumbnails...")
|
print("Generating thumbnails...")
|
||||||
pool.map(generate_thumbnail, thumbnails)
|
pool.map(generate_thumbnail, thumbnails)
|
||||||
else:
|
else:
|
||||||
pbardict["traversingbar"] = tqdm(desc="Traversing filesystem", unit="folders", ascii=True, dynamic_ncols=True)
|
thumbnails = list_folder(args.root_directory, args.site_title, args, raw, VERSION, logo)
|
||||||
logger.info("getting total number of folders to process")
|
|
||||||
total = get_total_folders(args.root_directory, args)
|
|
||||||
pbardict["traversingbar"].desc = "Traversing filesystem"
|
|
||||||
pbardict["traversingbar"].update(0)
|
|
||||||
pbardict["traversingbar"].close()
|
|
||||||
|
|
||||||
thumbnails = list_folder(total, args.root_directory, args.site_title, args, raw, VERSION, logo)
|
|
||||||
|
|
||||||
with Pool(os.cpu_count()) as pool:
|
with Pool(os.cpu_count()) as pool:
|
||||||
logger.info("generating thumbnails")
|
logger.info("generating thumbnails")
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ body {
|
|||||||
.folders figure {
|
.folders figure {
|
||||||
margin-bottom: 32px;
|
margin-bottom: 32px;
|
||||||
margin-top: 50px;
|
margin-top: 50px;
|
||||||
|
width: 180px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header h1 {
|
.header h1 {
|
||||||
@@ -42,11 +43,21 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.folders figcaption {
|
.folders figcaption {
|
||||||
width: 120px;
|
width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
font-size: smaller;
|
font-size: smaller;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.folderthumb {
|
||||||
|
height: 40px;
|
||||||
|
width: 70px !important;
|
||||||
|
overflow: hidden;
|
||||||
|
aspect-ratio: 1 / 1;
|
||||||
|
object-fit: contain;
|
||||||
|
margin: 20px 20px 0px -90px;
|
||||||
|
}
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
display: -ms-flexbox;
|
display: -ms-flexbox;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -206,15 +217,27 @@ figure {
|
|||||||
max-width: 25%;
|
max-width: 25%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.folders figure {
|
||||||
|
width: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
.folders img {
|
.folders img {
|
||||||
width: 80px;
|
width: 80px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.folders figcaption {
|
.folders figcaption {
|
||||||
width: 100px;
|
|
||||||
font-size: small;
|
font-size: small;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.folderthumb {
|
||||||
|
height: 30px;
|
||||||
|
width: 50px !important;
|
||||||
|
overflow: hidden;
|
||||||
|
aspect-ratio: 1 / 1;
|
||||||
|
object-fit: contain;
|
||||||
|
margin: 15px 20px 0px -70px;
|
||||||
|
}
|
||||||
|
|
||||||
.navbar {
|
.navbar {
|
||||||
font-size: medium;
|
font-size: medium;
|
||||||
}
|
}
|
||||||
@@ -227,15 +250,27 @@ figure {
|
|||||||
max-width: 50%;
|
max-width: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.folders figure {
|
||||||
|
width: 140px;
|
||||||
|
}
|
||||||
|
|
||||||
.folders img {
|
.folders img {
|
||||||
width: 60px;
|
width: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.folders figcaption {
|
.folders figcaption {
|
||||||
width: 80px;
|
|
||||||
font-size: x-small;
|
font-size: x-small;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.folderthumb {
|
||||||
|
height: 25px;
|
||||||
|
width: 30px !important;
|
||||||
|
overflow: hidden;
|
||||||
|
aspect-ratio: 1 / 1;
|
||||||
|
object-fit: contain;
|
||||||
|
margin: 10px 20px 0px -50px;
|
||||||
|
}
|
||||||
|
|
||||||
.navbar {
|
.navbar {
|
||||||
font-size: small;
|
font-size: small;
|
||||||
}
|
}
|
||||||
@@ -256,15 +291,27 @@ figure {
|
|||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.folders figure {
|
||||||
|
width: 120px;
|
||||||
|
}
|
||||||
|
|
||||||
.folders img {
|
.folders img {
|
||||||
width: 40px;
|
width: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.folders figcaption {
|
.folders figcaption {
|
||||||
width: 60px;
|
|
||||||
font-size: xx-small;
|
font-size: xx-small;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.folderthumb {
|
||||||
|
height: 15px;
|
||||||
|
width: 20px !important;
|
||||||
|
overflow: hidden;
|
||||||
|
aspect-ratio: 1 / 1;
|
||||||
|
object-fit: contain;
|
||||||
|
margin: 5px 10px 0px -35px;
|
||||||
|
}
|
||||||
|
|
||||||
.navbar {
|
.navbar {
|
||||||
font-size: xx-small;
|
font-size: xx-small;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ class Args:
|
|||||||
A list of folders to exclude from processing.
|
A list of folders to exclude from processing.
|
||||||
file_extensions : list[str]
|
file_extensions : list[str]
|
||||||
A list of file extensions to include.
|
A list of file extensions to include.
|
||||||
|
folder_thumbs : bool
|
||||||
|
Wether to generate subfolder thumbnails.
|
||||||
generate_webmanifest : bool
|
generate_webmanifest : bool
|
||||||
Whether to generate a web manifest file.
|
Whether to generate a web manifest file.
|
||||||
ignore_other_files : bool
|
ignore_other_files : bool
|
||||||
@@ -58,6 +60,7 @@ class Args:
|
|||||||
author_name: str
|
author_name: str
|
||||||
exclude_folders: list[str]
|
exclude_folders: list[str]
|
||||||
file_extensions: list[str]
|
file_extensions: list[str]
|
||||||
|
folder_thumbs: bool
|
||||||
generate_webmanifest: bool
|
generate_webmanifest: bool
|
||||||
ignore_other_files: bool
|
ignore_other_files: bool
|
||||||
license_type: Optional[str]
|
license_type: Optional[str]
|
||||||
@@ -76,14 +79,15 @@ class Args:
|
|||||||
result["author_name"] = self.author_name
|
result["author_name"] = self.author_name
|
||||||
result["exclude_folders"] = self.exclude_folders
|
result["exclude_folders"] = self.exclude_folders
|
||||||
result["file_extensions"] = self.file_extensions
|
result["file_extensions"] = self.file_extensions
|
||||||
|
result["folder_thumbs"] = self.folder_thumbs
|
||||||
result["generate_webmanifest"] = self.generate_webmanifest
|
result["generate_webmanifest"] = self.generate_webmanifest
|
||||||
result["ignore_other_files"] = self.ignore_other_files
|
result["ignore_other_files"] = self.ignore_other_files
|
||||||
if self.license_type is not None:
|
if self.license_type is not None:
|
||||||
result["license_type"] = self.license_type
|
result["license_type"] = self.license_type
|
||||||
result["non_interactive_mode"] = self.non_interactive_mode
|
result["non_interactive_mode"] = self.non_interactive_mode
|
||||||
result["regenerate_thumbnails"] = self.regenerate_thumbnails
|
result["regenerate_thumbnails"] = self.regenerate_thumbnails
|
||||||
result["reverse_sort"] = self.reverse_sort
|
|
||||||
result["reread_metadata"] = self.reread_metadata
|
result["reread_metadata"] = self.reread_metadata
|
||||||
|
result["reverse_sort"] = self.reverse_sort
|
||||||
result["root_directory"] = self.root_directory
|
result["root_directory"] = self.root_directory
|
||||||
result["site_title"] = self.site_title
|
result["site_title"] = self.site_title
|
||||||
result["theme_path"] = self.theme_path
|
result["theme_path"] = self.theme_path
|
||||||
@@ -120,6 +124,7 @@ def parse_arguments(version: str) -> Args:
|
|||||||
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("-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("-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("--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("--folderthumbnails", help="Generate subfolder thumbnails (first image in folder will be shown)", action="store_true", default=False, dest="folder_thumbs")
|
||||||
if RICH:
|
if RICH:
|
||||||
parser.add_argument("--generate-help-preview", action=HelpPreviewAction, path="help.svg", )
|
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("--ignore-other-files", help="Ignore files that do not match the specified extensions.", action="store_true", default=False, dest="ignore_other_files")
|
||||||
@@ -135,6 +140,7 @@ def parse_arguments(version: str) -> Args:
|
|||||||
author_name=parsed_args.author_name,
|
author_name=parsed_args.author_name,
|
||||||
exclude_folders=parsed_args.exclude_folders,
|
exclude_folders=parsed_args.exclude_folders,
|
||||||
file_extensions=parsed_args.file_extensions,
|
file_extensions=parsed_args.file_extensions,
|
||||||
|
folder_thumbs=parsed_args.folder_thumbs,
|
||||||
generate_webmanifest=parsed_args.generate_webmanifest,
|
generate_webmanifest=parsed_args.generate_webmanifest,
|
||||||
ignore_other_files=parsed_args.ignore_other_files,
|
ignore_other_files=parsed_args.ignore_other_files,
|
||||||
license_type=parsed_args.license_type,
|
license_type=parsed_args.license_type,
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ FAVICON_PATH = ".static/favicon.ico"
|
|||||||
GLOBAL_CSS_PATH = ".static/global.css"
|
GLOBAL_CSS_PATH = ".static/global.css"
|
||||||
EXCLUDES = ["index.html", "manifest.json", "robots.txt"]
|
EXCLUDES = ["index.html", "manifest.json", "robots.txt"]
|
||||||
|
|
||||||
# Set the maximum image pixels to prevent decompression bomb DOS attacks
|
# Set the maximum image pixels
|
||||||
Image.MAX_IMAGE_PIXELS = 933120000
|
Image.MAX_IMAGE_PIXELS = 933120000
|
||||||
|
|
||||||
# Initialize Jinja2 environment for template rendering
|
# Initialize Jinja2 environment for template rendering
|
||||||
@@ -209,28 +209,33 @@ def generate_html(folder: str, title: str, _args: Args, raw: list[str], version:
|
|||||||
|
|
||||||
create_thumbnail_folder(foldername, _args.root_directory)
|
create_thumbnail_folder(foldername, _args.root_directory)
|
||||||
|
|
||||||
if not _args.non_interactive_mode:
|
|
||||||
pbardict[folder] = tqdm(total=len(items), desc=f"Getting image infos - {folder}", unit="files", ascii=True, dynamic_ncols=True)
|
|
||||||
|
|
||||||
logger.info("processing contents", extra={"folder": folder})
|
logger.info("processing contents", extra={"folder": folder})
|
||||||
for item in items:
|
|
||||||
if item not in EXCLUDES and not item.startswith("."):
|
|
||||||
if os.path.isdir(os.path.join(folder, item)):
|
|
||||||
process_subfolder(item, folder, baseurl, subfolders, _args, raw, version, logo)
|
|
||||||
else:
|
|
||||||
contains_files = True
|
|
||||||
if os.path.splitext(item)[1].lower() in _args.file_extensions:
|
|
||||||
images.append(process_image(item, folder, _args, baseurl, sizelist, raw))
|
|
||||||
if item == "info":
|
|
||||||
process_info_file(folder, item)
|
|
||||||
if item == "LICENSE":
|
|
||||||
process_license(folder, item)
|
|
||||||
|
|
||||||
if not _args.non_interactive_mode:
|
|
||||||
pbardict[folder].update(1)
|
|
||||||
|
|
||||||
if not _args.non_interactive_mode:
|
if not _args.non_interactive_mode:
|
||||||
pbardict[folder].close()
|
for item in tqdm(items, total=len(items), desc=f"Getting image infos - {folder}", unit="files", ascii=True, dynamic_ncols=True):
|
||||||
|
if item not in EXCLUDES and not item.startswith("."):
|
||||||
|
if os.path.isdir(os.path.join(folder, item)):
|
||||||
|
process_subfolder(item, folder, baseurl, subfolders, _args, raw, version, logo)
|
||||||
|
else:
|
||||||
|
contains_files = True
|
||||||
|
if os.path.splitext(item)[1].lower() in _args.file_extensions:
|
||||||
|
images.append(process_image(item, folder, _args, baseurl, sizelist, raw))
|
||||||
|
if item == "info":
|
||||||
|
process_info_file(folder, item)
|
||||||
|
if item == "LICENSE":
|
||||||
|
process_license(folder, item)
|
||||||
|
else:
|
||||||
|
for item in items:
|
||||||
|
if item not in EXCLUDES and not item.startswith("."):
|
||||||
|
if os.path.isdir(os.path.join(folder, item)):
|
||||||
|
process_subfolder(item, folder, baseurl, subfolders, _args, raw, version, logo)
|
||||||
|
else:
|
||||||
|
contains_files = True
|
||||||
|
if os.path.splitext(item)[1].lower() in _args.file_extensions:
|
||||||
|
images.append(process_image(item, folder, _args, baseurl, sizelist, raw))
|
||||||
|
if item == "info":
|
||||||
|
process_info_file(folder, item)
|
||||||
|
if item == "LICENSE":
|
||||||
|
process_license(folder, item)
|
||||||
|
|
||||||
update_sizelist(sizelist, folder)
|
update_sizelist(sizelist, folder)
|
||||||
|
|
||||||
@@ -241,9 +246,6 @@ def generate_html(folder: str, title: str, _args: Args, raw: list[str], version:
|
|||||||
logger.info("removing existing index.html", extra={"folder": folder})
|
logger.info("removing existing index.html", extra={"folder": folder})
|
||||||
os.remove(os.path.join(folder, "index.html"))
|
os.remove(os.path.join(folder, "index.html"))
|
||||||
|
|
||||||
if not _args.non_interactive_mode:
|
|
||||||
pbardict["htmlbar"].update(1)
|
|
||||||
|
|
||||||
|
|
||||||
def create_thumbnail_folder(foldername: str, root_directory: str) -> None:
|
def create_thumbnail_folder(foldername: str, root_directory: str) -> None:
|
||||||
"""
|
"""
|
||||||
@@ -271,8 +273,21 @@ def process_subfolder(item: str, folder: str, baseurl: str, subfolders: list[dic
|
|||||||
_args (Args): Parsed command line arguments.
|
_args (Args): Parsed command line arguments.
|
||||||
raw (list[str]): Raw image file extensions.
|
raw (list[str]): Raw image file extensions.
|
||||||
"""
|
"""
|
||||||
subfolder_url = f"{_args.web_root_url}{baseurl}{urllib.parse.quote(item)}/index.html" if _args.web_root_url.startswith("file://") else f"{_args.web_root_url}{baseurl}{urllib.parse.quote(item)}"
|
subfolder_url = (
|
||||||
subfolders.append({"url": subfolder_url, "name": item})
|
f"{_args.web_root_url}{baseurl}{urllib.parse.quote(item)}/index.html"
|
||||||
|
if _args.web_root_url.startswith("file://")
|
||||||
|
else f"{_args.web_root_url}{baseurl}{urllib.parse.quote(item)}"
|
||||||
|
)
|
||||||
|
thumb = None
|
||||||
|
if _args.folder_thumbs:
|
||||||
|
thumbitems = [i for i in sorted(os.listdir(os.path.join(folder, item))) if os.path.splitext(i)[1].lower() in _args.file_extensions]
|
||||||
|
if len(thumbitems) > 0:
|
||||||
|
if _args.reverse_sort:
|
||||||
|
thumb = f"{_args.web_root_url}.thumbnails/{baseurl}{urllib.parse.quote(item)}/{urllib.parse.quote(thumbitems[-1])}.jpg"
|
||||||
|
else:
|
||||||
|
thumb = f"{_args.web_root_url}.thumbnails/{baseurl}{urllib.parse.quote(item)}/{urllib.parse.quote(thumbitems[0])}.jpg"
|
||||||
|
|
||||||
|
subfolders.append({"url": subfolder_url, "name": item, "thumb": thumb})
|
||||||
if item not in _args.exclude_folders:
|
if item not in _args.exclude_folders:
|
||||||
if not any(fnmatch.fnmatchcase(os.path.join(folder, item), exclude) for exclude in _args.exclude_folders):
|
if not any(fnmatch.fnmatchcase(os.path.join(folder, item), exclude) for exclude in _args.exclude_folders):
|
||||||
generate_html(os.path.join(folder, item), os.path.join(folder, item).removeprefix(_args.root_directory), _args, raw, version, logo)
|
generate_html(os.path.join(folder, item), os.path.join(folder, item).removeprefix(_args.root_directory), _args, raw, version, logo)
|
||||||
@@ -288,7 +303,9 @@ def process_license(folder: str, item: str) -> None:
|
|||||||
"""
|
"""
|
||||||
with open(os.path.join(folder, item), encoding="utf-8") as f:
|
with open(os.path.join(folder, item), encoding="utf-8") as f:
|
||||||
logger.info("processing LICENSE", extra={"path": os.path.join(folder, item)})
|
logger.info("processing LICENSE", extra={"path": os.path.join(folder, item)})
|
||||||
licens[urllib.parse.quote(folder)] = f.read().replace("\n", "</br>\n").replace(" ", " ").replace(" ", " ").replace("sp; ", "sp; ").replace("  ", " ")
|
licens[urllib.parse.quote(folder)] = (
|
||||||
|
f.read().replace("\n", "</br>\n").replace(" ", " ").replace(" ", " ").replace("sp; ", "sp; ").replace("  ", " ")
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def process_info_file(folder: str, item: str) -> None:
|
def process_info_file(folder: str, item: str) -> None:
|
||||||
@@ -360,7 +377,7 @@ def create_html_file(folder: str, title: str, foldername: str, images: list[dict
|
|||||||
|
|
||||||
if folder_license:
|
if folder_license:
|
||||||
license_html = os.path.join(folder, "license.html")
|
license_html = os.path.join(folder, "license.html")
|
||||||
license_url = _args.web_root_url + urllib.parse.quote(foldername) + "license"
|
license_url = _args.web_root_url + urllib.parse.quote(foldername) + "license.html"
|
||||||
with open(license_html, "w+", encoding="utf-8") as f:
|
with open(license_html, "w+", encoding="utf-8") as f:
|
||||||
logger.info("writing license html file", extra={"path": license_html})
|
logger.info("writing license html file", extra={"path": license_html})
|
||||||
gtml = env.get_template("license.html.j2")
|
gtml = env.get_template("license.html.j2")
|
||||||
@@ -404,7 +421,7 @@ def create_html_file(folder: str, title: str, foldername: str, images: list[dict
|
|||||||
f.write(content)
|
f.write(content)
|
||||||
|
|
||||||
|
|
||||||
def list_folder(total: int, folder: str, title: str, _args: Args, raw: list[str], version: str, logo: str) -> list[tuple[str, str]]:
|
def list_folder(folder: str, title: str, _args: Args, raw: list[str], version: str, logo: str) -> list[tuple[str, str]]:
|
||||||
"""
|
"""
|
||||||
lists and processes a folder, generating HTML files.
|
lists and processes a folder, generating HTML files.
|
||||||
|
|
||||||
@@ -418,7 +435,5 @@ def list_folder(total: int, folder: str, title: str, _args: Args, raw: list[str]
|
|||||||
Returns:
|
Returns:
|
||||||
list[tuple[str, str]]: list of thumbnails generated.
|
list[tuple[str, str]]: list of thumbnails generated.
|
||||||
"""
|
"""
|
||||||
if not _args.non_interactive_mode:
|
|
||||||
pbardict["htmlbar"] = tqdm(total=total, desc="Generating HTML files", unit="folders", ascii=True, dynamic_ncols=True)
|
|
||||||
generate_html(folder, title, _args, raw, version, logo)
|
generate_html(folder, title, _args, raw, version, logo)
|
||||||
return thumbnails
|
return thumbnails
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
CairoSVG==2.7.1
|
CairoSVG==2.7.1
|
||||||
Jinja2==3.1.4
|
Jinja2==3.1.5
|
||||||
pillow==10.4.0
|
Pillow==11.1.0
|
||||||
pyinstaller==6.11.1
|
pyinstaller==6.11.1
|
||||||
python-json-logger==2.0.7
|
python_json_logger==2.0.7
|
||||||
rich-argparse==1.5.2
|
rich_argparse==1.7.0
|
||||||
setuptools==70.3.0
|
selenium==4.28.1
|
||||||
tqdm==4.66.4
|
tqdm==4.66.4
|
||||||
@@ -57,6 +57,9 @@
|
|||||||
<a href="{{ subdirectory.url }}">
|
<a href="{{ subdirectory.url }}">
|
||||||
<figure>
|
<figure>
|
||||||
<img class="foldericon" />
|
<img class="foldericon" />
|
||||||
|
{%- if subdirectory.thumb %}
|
||||||
|
<img class="folderthumb" src="{{ subdirectory.thumb }}" />
|
||||||
|
{%- endif %}
|
||||||
<figcaption>{{ subdirectory.name }}</figcaption>
|
<figcaption>{{ subdirectory.name }}</figcaption>
|
||||||
</figure>
|
</figure>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
Reference in New Issue
Block a user