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 _make_thumbnail(full_path_image, name): 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(type_, subtype, tag, name): id_name = name.split(".")[0].replace(" ", "_") filename = f'{name}' if "image" in type_: html = '
{}
' elif "pdf" in subtype: html = '
{}' + filename + "
" elif "dir" in type_ or "html" in subtype or "unkown-file" in subtype: html = '
{}
' else: html = '
{}' + filename + "
" return html.format(id_name, subtype, tag) def _check_distribusi_index(index): """ check whether a index.html file is generated by distribusi """ with open(index, "r") as f: if '' in f.read(): return True return False def _write_index_html(index, html, cssfile): with open(index, "w") as index_file: styled_html_head = html_head.format(cssfile=cssfile) 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 = '
{}
'.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 = "
" + open(full_path).read() + "
" else: subtype = subtype + " unkown-file" tag = "{}" # a = FILE_TYPES[type_] return subtype, tag def _handle_image_files(name, full_path): thumbnail_filename = _make_thumbnail(full_path, name) 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, ) def _remove_existing_index_html(root, files): index = os.path.join(root, "index.html") if "index.html" in files: try: if check_distribusi_index(index): 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_skippable_file(name, cssfile): 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 cssfile in name: return True def distribusify(directory, cssfile): for root, dirs, files in os.walk(directory): html = [] dirs, files = _remove_hidden_files_and_folders(dirs, files) _remove_existing_index_html(root, files) for name in sorted(files): if _is_skippable_file(name, cssfile): continue full_path = os.path.join(root, name) mime = MIME_TYPE.from_file(full_path) type_, subtype = mime.split("/") alttext = name 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) 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 = "{}" tag = tag.replace("{}", name) html.append(_format_div(type_, subtype, tag, name)) if root != directory: html.append('../') for name in sorted(dirs): tag = "{}".replace("{}", name) html.insert(0, format_div("dir", "dir", tag, "folder")) index = os.path.join(root, "index.html") _write_index_html(index, html, cssfile)