#!/usr/bin/env python3
# Copyright (c) 2021 Josh Brunty
# SPDX-License-Identifier: MIT
# Indexer v.1.0.1
# Author: Josh Brunty (josh dot brunty at marshall dot edu)
# DESCRIPTION: This script generates an .html index of files within a directory (recursive is OFF by default). Start from current dir or from folder passed as first positional argument. Optionally filter by file types with --filter "*.py".
# -handle symlinked files and folders: displayed with custom icons
# By default only the current folder is processed.
# Use -r or --recursive to process nested folders.
import argparse
import datetime
import os
import sys
from pathlib import Path
from urllib.parse import quote
DEFAULT_OUTPUT_FILE = "index.html"
def process_dir(top_dir, opts):
glob_patt_list = opts.filter or "*"
path_top_dir: Path
path_top_dir = Path(top_dir)
index_file = None
index_path = Path(path_top_dir, opts.output_file)
if opts.verbose:
print(f"Traversing dir {path_top_dir.absolute()}")
try:
index_file = open(index_path, "w", encoding="utf-8")
except Exception as e:
print("cannot create file %s %s" % (index_path, e))
return
index_file.write(
"""
"""
)
if index_file:
index_file.close()
# bytes pretty-printing
UNITS_MAPPING = [
(1024**5, " PB"),
(1024**4, " TB"),
(1024**3, " GB"),
(1024**2, " MB"),
(1024**1, " KB"),
(1024**0, (" byte", " bytes")),
]
def pretty_size(bytes, units=UNITS_MAPPING):
"""Human-readable file sizes.
ripped from https://pypi.python.org/pypi/hurry.filesize/
"""
for factor, suffix in units:
if bytes >= factor:
break
amount = int(bytes / factor)
if isinstance(suffix, tuple):
singular, multiple = suffix
if amount == 1:
suffix = singular
else:
suffix = multiple
return str(amount) + suffix
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="""DESCRIPTION: This script generates an .html index of files within a directory (recursive is OFF by default). Start from current dir or from folder passed as first positional argument. Optionally filter by file types with --filter "*.py"
Email josh dot brunty at marshall dot edu for additional help. """
)
parser.add_argument(
"top_dir",
nargs="?",
action="store",
help="top folder from which to start generating indexes, "
"use current folder if not specified",
default=os.getcwd(),
)
# NOTE: preferably specify nargs at end, after path if unnamed arg
parser.add_argument(
"--filter",
"-f",
nargs="*",
help="only include files matching glob",
required=False,
)
parser.add_argument(
"--output-file",
"-o",
metavar="filename",
default=DEFAULT_OUTPUT_FILE,
help=f'Custom output file, by default "{DEFAULT_OUTPUT_FILE}"',
)
parser.add_argument(
"--recursive",
"-r",
action="store_true",
help="recursively process nested dirs (FALSE by default)",
required=False,
)
parser.add_argument(
"--verbose",
"-v",
action="store_true",
help="***WARNING: can take longer time with complex file tree structures on slow terminals***"
" verbosely list every processed file",
required=False,
)
config = parser.parse_args(sys.argv[1:])
process_dir(config.top_dir, config)