no more args, just run distribusi

This commit is contained in:
crunk 2024-12-21 12:35:00 +01:00
parent c8862dfb59
commit cc25eb73c1
6 changed files with 67 additions and 191 deletions

View File

@ -1,89 +0,0 @@
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)

View File

@ -46,7 +46,7 @@ def _read_matching_text_file(image_filename_no_ext, filename):
return text_file.read() return text_file.read()
def thumbnail(full_path_image, name, args): def make_thumbnail(full_path_image, name):
if full_path_image.endswith("_thumbnail.jpg"): if full_path_image.endswith("_thumbnail.jpg"):
return return
try: try:
@ -68,7 +68,7 @@ def thumbnail(full_path_image, name, args):
return return
def format_div(args, type_, subtype, tag, name): def format_div(type_, subtype, tag, name):
id_name = name.split(".")[0].replace(" ", "_") id_name = name.split(".")[0].replace(" ", "_")
filename = f'<span class="filename">{name}</span>' filename = f'<span class="filename">{name}</span>'
@ -84,25 +84,19 @@ def format_div(args, type_, subtype, tag, name):
return html.format(id_name, subtype, tag) return html.format(id_name, subtype, tag)
def check_distribusi_index(args, index): def check_distribusi_index(index):
""" """
check whether a index.html file is generated by distribusi check whether a index.html file is generated by distribusi
""" """
if not args.force: with open(index, "r") as f:
with open(index, "r") as f: if '<meta name="generator" content="distribusi" />' in f.read():
if '<meta name="generator" content="distribusi" />' in f.read(): return True
return True return False
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): def write_index_html(index, html, cssfile):
with open(index, "w") as index_file: with open(index, "w") as index_file:
styled_html_head = html_head.format(cssfile=args.style) styled_html_head = html_head.format(cssfile=cssfile)
index_file.write(styled_html_head) index_file.write(styled_html_head)
for line in html: for line in html:
index_file.write(line + "\n") index_file.write(line + "\n")
@ -127,47 +121,43 @@ def handle_text_files(name, full_path, subtype):
return subtype, tag return subtype, tag
def handle_image_files(name, full_path, args): def handle_image_files(name, full_path):
if args.thumbnail: thumbnail_filename = make_thumbnail(full_path, name)
thumbnail_filename = thumbnail(full_path, name, args) if thumbnail_filename is None:
if thumbnail_filename is None: return
return
image_alttext = add_alttext(full_path) image_alttext = add_alttext(full_path)
image_description = add_description(full_path) image_description = add_description(full_path)
if not image_alttext and not image_description: if not image_alttext and not image_description:
return image_no_description.format( return image_no_description.format(
name=name, thumbnail_filename=thumbnail_filename name=name, thumbnail_filename=thumbnail_filename
) )
if not image_alttext: if not image_alttext:
return image_with_description.format( return image_with_description.format(
name=name, name=name,
thumbnail_filename=thumbnail_filename, thumbnail_filename=thumbnail_filename,
image_description=image_description, image_description=image_description,
) )
if not image_description: if not image_description:
return image_with_alttext.format( return image_with_alttext.format(
name=name,
thumbnail_filename=thumbnail_filename,
image_alttext=image_alttext,
)
return image_full_figure.format(
name=name, name=name,
thumbnail_filename=thumbnail_filename, thumbnail_filename=thumbnail_filename,
image_alttext=image_alttext, image_alttext=image_alttext,
image_description=image_description,
) )
return FILE_TYPES["image"].format(name, image_alttext) return image_full_figure.format(
name=name,
thumbnail_filename=thumbnail_filename,
image_alttext=image_alttext,
image_description=image_description,
)
def remove_index_html(root, files, args): def remove_index_html(root, files):
index = os.path.join(root, "index.html") index = os.path.join(root, "index.html")
if "index.html" in files: if "index.html" in files:
try: try:
if check_distribusi_index(args, index): if check_distribusi_index(index):
if args.verbose:
print("Removing index.html from", root)
os.remove(index) os.remove(index)
except Exception as e: except Exception as e:
print(e) print(e)
@ -180,7 +170,7 @@ def remove_hidden_files_and_folders(dirs, files):
return dirs, files return dirs, files
def is_skipped_file(name, args): def is_skipped_file(name, cssfile):
if "index.html" in name: if "index.html" in name:
return True return True
@ -193,32 +183,18 @@ def is_skipped_file(name, args):
if name.endswith("_dv_description.txt"): if name.endswith("_dv_description.txt"):
return True return True
if args.style in name: if cssfile in name:
return True return True
def distribusify(args, directory): # noqa def distribusify(cssfile, directory):
for root, dirs, files in os.walk(directory): for root, dirs, files in os.walk(directory):
html = [] html = []
dirs, files = remove_hidden_files_and_folders(dirs, files)
if args.exclude_directory: remove_index_html(root, files)
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): for name in sorted(files):
if is_skipped_file(name, args): if is_skipped_file(name, cssfile):
continue continue
full_path = os.path.join(root, name) full_path = os.path.join(root, name)
@ -226,8 +202,6 @@ def distribusify(args, directory): # noqa
type_, subtype = mime.split("/") type_, subtype = mime.split("/")
alttext = name alttext = name
if args.verbose:
print("Found", name, "as", mime)
if type_ in FILE_TYPES: if type_ in FILE_TYPES:
match type_: match type_:
case "text": case "text":
@ -235,7 +209,7 @@ def distribusify(args, directory): # noqa
name, full_path, subtype name, full_path, subtype
) )
case "image": case "image":
tag = handle_image_files(name, full_path, args) tag = handle_image_files(name, full_path)
if tag is None: if tag is None:
continue continue
case _: case _:
@ -247,29 +221,16 @@ def distribusify(args, directory): # noqa
if type_ not in FILE_TYPES and subtype not in SUB_TYPES: if type_ not in FILE_TYPES and subtype not in SUB_TYPES:
# catch exceptions not yet defined in FILE_TYPES or SUB_TYPES # catch exceptions not yet defined in FILE_TYPES or SUB_TYPES
tag = "<a href='{}'>{}</a>" 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) tag = tag.replace("{}", name)
html.append(format_div(args, type_, subtype, tag, name)) html.append(format_div(type_, subtype, tag, name))
if root != directory: if root != directory:
if args.menu_with_index: html.append('<a href="../index.html">../</a>')
html.append('<a href="../index.html">../</a>')
else:
html.append('<a href="../">../</a>')
for name in sorted(dirs): for name in sorted(dirs):
if args.menu_with_index: tag = "<a href='{}/index.html'>{}</a>".replace("{}", name)
tag = "<a href='{}/index.html'>{}</a>".replace("{}", name) html.insert(0, format_div("dir", "dir", tag, "folder"))
else:
tag = "<a href='{}'>{}/</a>".replace("{}", name)
html.insert(0, format_div(args, "dir", "dir", tag, "folder"))
index = os.path.join(root, "index.html") index = os.path.join(root, "index.html")
write_index_html(args, index, html) write_index_html(index, html, cssfile)

View File

@ -1,4 +1,4 @@
html_head = '''\ html_head = """\
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
@ -8,9 +8,9 @@ html_head = '''\
<link rel="stylesheet" href="{cssfile}" crossorigin="anonymous"> <link rel="stylesheet" href="{cssfile}" crossorigin="anonymous">
</head> </head>
<body> <body>
''' """
html_footer ='''\ html_footer = """\
</body> </body>
</html> </html>
''' """

View File

@ -112,6 +112,10 @@ def _delete_distribusi_files(distribusiname):
cssfolder = os.path.join("themes/userthemes", distribusiname) cssfolder = os.path.join("themes/userthemes", distribusiname)
if os.path.exists(cssfolder): if os.path.exists(cssfolder):
shutil.rmtree(cssfolder) shutil.rmtree(cssfolder)
distribusi = Distribusis.query.filter_by(
distribusiname=distribusiname
).first()
if distribusi.publictheme is not None: if distribusi.publictheme is not None:
publicthemefolder = os.path.join("themes/publicthemes", distribusiname) publicthemefolder = os.path.join("themes/publicthemes", distribusiname)
if os.path.exists(publicthemefolder): if os.path.exists(publicthemefolder):

View File

@ -79,7 +79,9 @@ def upload_updates_files(uploadfolder):
db.session.commit() db.session.commit()
except (InvalidRequestError, DataError, InterfaceError, DatabaseError): except (InvalidRequestError, DataError, InterfaceError, DatabaseError):
db.session.rollback() db.session.rollback()
uploadform.sitename.errors.append("Something went wrong with the database!") uploadform.sitename.errors.append(
"Something went wrong with the database!"
)
zipfilename = "{}.zip".format(distribusi.distribusiname) zipfilename = "{}.zip".format(distribusi.distribusiname)
zipfile = uploadform.zipfile.data zipfile = uploadform.zipfile.data

View File

@ -14,19 +14,17 @@ config = context.config
# Interpret the config file for Python logging. # Interpret the config file for Python logging.
# This line sets up loggers basically. # This line sets up loggers basically.
fileConfig(config.config_file_name) fileConfig(config.config_file_name)
logger = logging.getLogger("alembic.env") logger = logging.getLogger('alembic.env')
# add your model's MetaData object here # add your model's MetaData object here
# for 'autogenerate' support # for 'autogenerate' support
# from myapp import mymodel # from myapp import mymodel
# target_metadata = mymodel.Base.metadata # target_metadata = mymodel.Base.metadata
config.set_main_option( config.set_main_option(
"sqlalchemy.url", 'sqlalchemy.url',
str(current_app.extensions["migrate"].db.get_engine().url).replace( str(current_app.extensions['migrate'].db.get_engine().url).replace(
"%", "%%" '%', '%%'))
), target_metadata = current_app.extensions['migrate'].db.metadata
)
target_metadata = current_app.extensions["migrate"].db.metadata
# other values from the config, defined by the needs of env.py, # other values from the config, defined by the needs of env.py,
# can be acquired: # can be acquired:
@ -67,20 +65,20 @@ def run_migrations_online():
# when there are no changes to the schema # when there are no changes to the schema
# reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html # reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html
def process_revision_directives(context, revision, directives): def process_revision_directives(context, revision, directives):
if getattr(config.cmd_opts, "autogenerate", False): if getattr(config.cmd_opts, 'autogenerate', False):
script = directives[0] script = directives[0]
if script.upgrade_ops.is_empty(): if script.upgrade_ops.is_empty():
directives[:] = [] directives[:] = []
logger.info("No changes in schema detected.") logger.info('No changes in schema detected.')
connectable = current_app.extensions["migrate"].db.get_engine() connectable = current_app.extensions['migrate'].db.get_engine()
with connectable.connect() as connection: with connectable.connect() as connection:
context.configure( context.configure(
connection=connection, connection=connection,
target_metadata=target_metadata, target_metadata=target_metadata,
process_revision_directives=process_revision_directives, process_revision_directives=process_revision_directives,
**current_app.extensions["migrate"].configure_args, **current_app.extensions['migrate'].configure_args
) )
with context.begin_transaction(): with context.begin_transaction():