removed distribusi git submodule

This commit is contained in:
crunk 2024-12-04 10:34:07 +01:00
parent 4d0d5bd767
commit c8862dfb59
11 changed files with 400 additions and 6 deletions

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "distribusi"]
path = distribusi
url = https://git.vvvvvvaria.org/crunk/distribusi

@ -1 +0,0 @@
Subproject commit e291e7497e40211c2ebd54ca32a1f4bdaed71230

0
distribusi/__init__.py Normal file
View File

89
distribusi/cli.py Normal file
View File

@ -0,0 +1,89 @@
import argparse
import os
from distribusi.distribusi import distribusify
def build_argparser():
parser = argparse.ArgumentParser(
"""
distribusi is a content management system for the web that produces static
index pages based on folders in the files system. It is inspired by the
automatic index functions featured in several popular web servers.
distribusi works by traversing the file system and directory hierarchy to
automatically list all the files in the directory, detect the file types
and providing them with relevant html classes and tags for easy styling.
"""
)
parser.add_argument(
"-d",
"--directory",
help="Select which directory to distribute",
default=".",
)
parser.add_argument(
"-s", "--style", help="Select a CSS style sheet to include"
)
parser.add_argument(
"-v",
"--verbose",
help="Print verbose debug output",
action="store_true",
)
parser.add_argument(
"-t",
"--thumbnail",
help="Generate 450x450 thumbnails for images",
action="store_true",
)
parser.add_argument(
"-a",
"--alttexts",
help="Adds file alttext based on same named files",
action="store_true",
)
parser.add_argument(
"-r",
"--remove-index",
help="Recursively removes all instances of index.html that have been previously made by distribusi",
action="store_true",
)
parser.add_argument(
"-e",
"--exclude-directory",
help="Exclude one or multiple directories from indexing",
nargs="*",
metavar="DIR",
)
parser.add_argument(
"-f",
"--force",
help="Force whether distribusi overwrites or removes instances of index.html not generated by distribusi, use at own risk!",
action="store_true",
)
parser.add_argument(
"--no-hidden", help="Exclude hidden directories", action="store_true"
)
parser.add_argument(
"--menu-with-index",
help="Append index.html to menu items to aid navigation",
action="store_true",
)
return parser
def cli_entrypoint():
parser = build_argparser()
args = parser.parse_args()
distribusify(args, args.directory)

275
distribusi/distribusi.py Normal file
View File

@ -0,0 +1,275 @@
import os
import magic
from PIL import Image
from distribusi.templates.page_template import html_footer, html_head
from distribusi.templates.image_templates import (
image_no_description,
image_with_description,
image_with_alttext,
image_full_figure,
)
from distribusi.mappings import CODE_TYPES, FILE_TYPES, SUB_TYPES
MIME_TYPE = magic.Magic(mime=True)
def add_alttext(full_path_image):
try:
image_filename_no_ext = os.path.splitext(full_path_image)[0]
alttext_filename = f"{image_filename_no_ext}_alttext.txt"
return _read_matching_text_file(
image_filename_no_ext, alttext_filename
)
except Exception as e:
print(f"exception {e} raised while making alttext")
return
def add_description(full_path_image):
try:
image_filename_no_ext = os.path.splitext(full_path_image)[0]
description_filename = f"{image_filename_no_ext}_dv_description.txt"
return _read_matching_text_file(
image_filename_no_ext, description_filename
)
except Exception as e:
print(f"exception {e} raised while adding description")
return
def _read_matching_text_file(image_filename_no_ext, filename):
if not os.path.isfile(filename):
return
print(f"{image_filename_no_ext} has {filename}")
with open(filename, "r") as text_file:
return text_file.read()
def thumbnail(full_path_image, name, args):
if full_path_image.endswith("_thumbnail.jpg"):
return
try:
size = (450, 450)
thumbnail_image = Image.open(full_path_image)
thumbnail_image.thumbnail(size)
if thumbnail_image.mode == "RGBA":
bg = Image.new("RGBA", thumbnail_image.size, (255, 255, 255))
composite = Image.alpha_composite(bg, thumbnail_image)
thumbnail_image = composite.convert("RGB")
image_filename_no_ext = os.path.splitext(full_path_image)[0]
thumbnail_filename = f"{image_filename_no_ext}_thumbnail.jpg"
thumbnail_image.save(thumbnail_filename, format="JPEG")
return os.path.basename(thumbnail_filename)
except Exception as e:
print("Thumbnailer:", e)
return
def format_div(args, type_, subtype, tag, name):
id_name = name.split(".")[0].replace(" ", "_")
filename = f'<span class="filename">{name}</span>'
if "image" in type_:
html = '<div id="{}" class="{}">{}</div>'
elif "pdf" in subtype:
html = '<div id="{}" class="{}">{}' + filename + "</div>"
elif "dir" in type_ or "html" in subtype or "unkown-file" in subtype:
html = '<div id="{}" class="{}">{}</div>'
else:
html = '<div id="{}" class="{}">{}' + filename + "</div>"
return html.format(id_name, subtype, tag)
def check_distribusi_index(args, index):
"""
check whether a index.html file is generated by distribusi
"""
if not args.force:
with open(index, "r") as f:
if '<meta name="generator" content="distribusi" />' in f.read():
return True
else:
if args.verbose:
print(index, "not generated by distribusi, skipping")
return False
elif args.force:
return True
def write_index_html(args, index, html):
with open(index, "w") as index_file:
styled_html_head = html_head.format(cssfile=args.style)
index_file.write(styled_html_head)
for line in html:
index_file.write(line + "\n")
index_file.write(html_footer)
def handle_text_files(name, full_path, subtype):
if name.endswith(".html") or subtype == "html":
subtype = "html"
# what types of text files to expand
tag = '<section id="{}">{}</section>'.format(
name, open(full_path).read()
)
elif subtype in CODE_TYPES or name.endswith(".txt"):
# if the plain text is code,
# which types do we wrap in pre-tags?
tag = "<pre>" + open(full_path).read() + "</pre>"
else:
subtype = subtype + " unkown-file"
tag = "<a href='{}'>{}</a>"
# a = FILE_TYPES[type_]
return subtype, tag
def handle_image_files(name, full_path, args):
if args.thumbnail:
thumbnail_filename = thumbnail(full_path, name, args)
if thumbnail_filename is None:
return
image_alttext = add_alttext(full_path)
image_description = add_description(full_path)
if not image_alttext and not image_description:
return image_no_description.format(
name=name, thumbnail_filename=thumbnail_filename
)
if not image_alttext:
return image_with_description.format(
name=name,
thumbnail_filename=thumbnail_filename,
image_description=image_description,
)
if not image_description:
return image_with_alttext.format(
name=name,
thumbnail_filename=thumbnail_filename,
image_alttext=image_alttext,
)
return image_full_figure.format(
name=name,
thumbnail_filename=thumbnail_filename,
image_alttext=image_alttext,
image_description=image_description,
)
return FILE_TYPES["image"].format(name, image_alttext)
def remove_index_html(root, files, args):
index = os.path.join(root, "index.html")
if "index.html" in files:
try:
if check_distribusi_index(args, index):
if args.verbose:
print("Removing index.html from", root)
os.remove(index)
except Exception as e:
print(e)
return
def remove_hidden_files_and_folders(dirs, files):
dirs = list(filter(lambda d: not d.startswith("."), dirs))
files = list(filter(lambda f: not f.startswith("."), files))
return dirs, files
def is_skipped_file(name, args):
if "index.html" in name:
return True
if name.endswith("_thumbnail.jpg"):
return True
if name.endswith("_alttext.txt"):
return True
if name.endswith("_dv_description.txt"):
return True
if args.style in name:
return True
def distribusify(args, directory): # noqa
for root, dirs, files in os.walk(directory):
html = []
if args.exclude_directory:
if args.verbose:
print(
"Excluding directory:", ", ".join(args.exclude_directory)
)
dirs[:] = [d for d in dirs if d not in args.exclude_directory]
if args.no_hidden:
dirs, files = remove_hidden_files_and_folders(dirs, files)
if args.remove_index:
remove_index_html(root, files, args)
if args.verbose:
print("Generating directory listing for", root)
for name in sorted(files):
if is_skipped_file(name, args):
continue
full_path = os.path.join(root, name)
mime = MIME_TYPE.from_file(full_path)
type_, subtype = mime.split("/")
alttext = name
if args.verbose:
print("Found", name, "as", mime)
if type_ in FILE_TYPES:
match type_:
case "text":
subtype, tag = handle_text_files(
name, full_path, subtype
)
case "image":
tag = handle_image_files(name, full_path, args)
if tag is None:
continue
case _:
tag = FILE_TYPES[type_].format(name, alttext)
if subtype in SUB_TYPES:
tag = SUB_TYPES[subtype]
if type_ not in FILE_TYPES and subtype not in SUB_TYPES:
# catch exceptions not yet defined in FILE_TYPES or SUB_TYPES
tag = "<a href='{}'>{}</a>"
if args.verbose:
message = (
"not in list of file types, adding as plain href: \n"
)
print(type_, subtype, message, name)
subtype = subtype + " unkown-file"
tag = tag.replace("{}", name)
html.append(format_div(args, type_, subtype, tag, name))
if root != directory:
if args.menu_with_index:
html.append('<a href="../index.html">../</a>')
else:
html.append('<a href="../">../</a>')
for name in sorted(dirs):
if args.menu_with_index:
tag = "<a href='{}/index.html'>{}</a>".replace("{}", name)
else:
tag = "<a href='{}'>{}/</a>".replace("{}", name)
html.insert(0, format_div(args, "dir", "dir", tag, "folder"))
index = os.path.join(root, "index.html")
write_index_html(args, index, html)

15
distribusi/mappings.py Normal file
View File

@ -0,0 +1,15 @@
CODE_TYPES = ["x-c", "x-shellscript", "x-python"]
FILE_TYPES = {
"image": '<img class="image" src="{}" alt="{}">',
"text": '<a href="{}" class="text">{}</a>',
"video": ("<video controls>" '<source src="{}"></video>'),
"audio": ('<audio controls class="audio">' '<source src="{}"></audio>'),
}
SUB_TYPES = {
"pdf": (
'<object data="{}" class="pdf" type="application/pdf">'
'<embed src="{}" type="application/pdf" /></object>'
)
}

View File

View File

@ -0,0 +1,4 @@
image_no_description = '<a href="{name}"><img class="thumbnail" src="{thumbnail_filename}" alt="{name}"></a>'
image_with_description = '<figure><a href="{name}"><img class="thumbnail" src="{thumbnail_filename}"></a><figcaption>{image_description}</figcaption></figure>'
image_with_alttext = '<a href="{name}"><img class="thumbnail" src="{thumbnail_filename}" alt="{image_alttext}"></a>'
image_full_figure = '<figure><a href="{name}"><img class="thumbnail" src="{thumbnail_filename}" alt="{image_alttext}"></a><figcaption>{image_description}</figcaption></figure>'

View File

@ -0,0 +1,16 @@
html_head = '''\
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Generated with distribusi https://git.vvvvvvaria.org/crunk/distribusi -->
<meta name="generator" content="distribusi" />
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="stylesheet" href="{cssfile}" crossorigin="anonymous">
</head>
<body>
'''
html_footer ='''\
</body>
</html>
'''

View File

@ -8,7 +8,6 @@ bleach-allowlist==1.0.3
blinker==1.7.0
cffi
click==8.1.7
distribusi @ git+https://git.vvvvvvaria.org/crunk/distribusi@4654ced5e8dfe803b62bc6163fa3d88a73a9010a
dnspython==2.1.0
email-validator==1.1.3
Flask==3.0.3

View File

@ -1,3 +1,3 @@
from setuptools import find_packages, setup
setup(name="library", version="1.0", packages=find_packages())
setup(name="dsitribusi-verse", version="1.0", packages=find_packages())