# Standard library imports. from pathlib import Path from urllib.parse import urlencode from functools import cmp_to_key # Django imports. from django.conf import settings # Project imports. from .utils import make_thumbnail, is_image_file ########################################################################################### # Constants. # ########################################################################################### SORT_OPTIONS = [ ("abc", "Alphabetical A-Z"), ("cba", "Alphabetical Z-A"), ("old", "Creation date old to new"), ("new", "Creation date new to old"), ("recent", "Modification date most recent"), ("tnecer", "Modification date least recent"), ] SORT_LABELS = dict(SORT_OPTIONS) def normalize_sort(sort_value): return sort_value if sort_value in SORT_LABELS else "abc" def normalize_theme(theme_value): return theme_value if theme_value in ("dark", "light") else "dark" def get_creation_timestamp(path_obj): try: stat_data = path_obj.stat() return getattr(stat_data, "st_birthtime", stat_data.st_ctime) except OSError: return 0 def get_modification_timestamp(path_obj): try: return path_obj.stat().st_mtime except OSError: return 0 def build_query(search_text, sort_key, theme): query = {"sort": sort_key, "theme": theme} if search_text != "": query["search"] = search_text return query def append_query(url, query_dict): if len(query_dict) == 0: return url return url + "?" + urlencode(query_dict) def gallery_url(path_obj=None, is_dir=False, query_dict=None): if query_dict is None: query_dict = {} if path_obj is None: base_url = "/gallery/" else: path_text = str(path_obj).replace("\\", "/") base_url = "/gallery/" + path_text if is_dir and not base_url.endswith("/"): base_url += "/" return append_query(base_url, query_dict) def sort_images(images, sort_key): def compare(img_a, img_b): name_a = img_a.name.lower() name_b = img_b.name.lower() rel_a = str(img_a.relative_to(settings.GALLERY_ROOT)).lower() rel_b = str(img_b.relative_to(settings.GALLERY_ROOT)).lower() if sort_key == "abc": if name_a < name_b: return -1 if name_a > name_b: return 1 elif sort_key == "cba": if name_a > name_b: return -1 if name_a < name_b: return 1 elif sort_key == "old": created_a = get_creation_timestamp(img_a) created_b = get_creation_timestamp(img_b) if created_a < created_b: return -1 if created_a > created_b: return 1 elif sort_key == "new": created_a = get_creation_timestamp(img_a) created_b = get_creation_timestamp(img_b) if created_a > created_b: return -1 if created_a < created_b: return 1 elif sort_key == "recent": modified_a = get_modification_timestamp(img_a) modified_b = get_modification_timestamp(img_b) if modified_a > modified_b: return -1 if modified_a < modified_b: return 1 elif sort_key == "tnecer": modified_a = get_modification_timestamp(img_a) modified_b = get_modification_timestamp(img_b) if modified_a < modified_b: return -1 if modified_a > modified_b: return 1 if name_a < name_b: return -1 if name_a > name_b: return 1 if rel_a < rel_b: return -1 if rel_a > rel_b: return 1 return 0 return sorted(images, key=cmp_to_key(compare)) def build_breadcrumbs(path_text, query_dict): breadcrumbs = [{"label": "Gallery", "path": gallery_url(None, True, query_dict)}] if path_text == "": return breadcrumbs segments = Path(path_text).parts current = Path("") for segment in segments: current = current.joinpath(segment) breadcrumbs.append( {"label": segment, "path": gallery_url(current, True, query_dict)} ) return breadcrumbs def build_sort_options(request, search_text, sort_key, theme): options = [] for option_key, label in SORT_OPTIONS: query = {"sort": option_key, "theme": theme} if search_text != "": query["search"] = search_text options.append( { "key": option_key, "label": label, "url": append_query(request.path, query), "is_active": option_key == sort_key, } ) return options def get_first_image_thumbnail_url(subdir): try: images = sorted( [ entry for entry in subdir.iterdir() if entry.is_file() and not entry.is_symlink() and is_image_file(entry) ], key=lambda item: ( item.name.lower(), str(item.relative_to(settings.GALLERY_ROOT)).lower(), ), ) except OSError: return None if len(images) == 0: return None first_image = images[0] try: make_thumbnail(first_image) rel_path = first_image.relative_to(settings.GALLERY_ROOT) thumb_path = settings.THUMBNAILS_ROOT.joinpath(rel_path) if thumb_path.exists(): return "/thumbs/" + str(rel_path).replace("\\", "/") except Exception: pass return None