Files
docker-images/linkki-tiedotus/linkki_poster/scanner.py
T
ajp_anton 8ec3cde4f2
Build custom container images / build (map[base_image:php:8-fpm-alpine build_args:PHP_VERSION=8 context:php8-pgsql fingerprint_command:{ apk info -v | LC_ALL=C sort; find /usr/local/lib/php/extensions /usr/local/etc/php/conf.d -type f -exec sha256sum {} + | LC_ALL=C sort; } name:ph… (push) Successful in 48s
Build custom container images / build (map[base_image:postgres:18 build_args:PG_VERSION=18 POSTGIS_VERSION=3 VCHORD_VERSION=0.5.3 context:postgres fingerprint_command:{ dpkg-query -W -f='${binary:Package}=${Version}\n' | LC_ALL=C sort; find /usr/lib/postgresql -type f -exec sha256su… (push) Successful in 55s
Build custom container images / build (map[base_image:python:3 build_args:PYTHON_VERSION=3 context:python-tools fingerprint_command:{ dpkg-query -W -f='${binary:Package}=${Version}\n' | LC_ALL=C sort; pip freeze | LC_ALL=C sort; } name:python-tools oci_labels:org.opencontainers.ima… (push) Successful in 54s
Build custom container images / build (map[base_image:python:3.12-slim build_args:PYTHON_VERSION=3.12-slim context:linkki-tiedotus fingerprint_command:{ dpkg-query -W -f='${binary:Package}=${Version}\n' | LC_ALL=C sort; pip freeze | LC_ALL=C sort; } name:linkki-tiedotus oci_labels:… (push) Successful in 39s
Add Linkki broadcast image
2026-08-19 20:51:26 +00:00

111 lines
3.4 KiB
Python

import re
from pathlib import Path
from linkki_poster.models import Language, LanguageAssets, ScanResult
KNOWN_IMAGE_EXTENSIONS = {
"jpg",
"jpeg",
"png",
"webp",
"gif",
}
GLOBAL_IMAGE_PREFIXES = ["Kuva"]
LANGUAGE_TEXT_CANDIDATES: dict[Language, list[str]] = {
Language.FI: ["Suomi.md"],
Language.SV: ["Svenska.md"],
Language.EN: ["English.md"],
}
LANGUAGE_IMAGE_PREFIXES: dict[Language, list[str]] = {
Language.FI: ["Suomi"],
Language.SV: ["Svenska"],
Language.EN: ["English"],
}
def scan_directory(directory: Path) -> ScanResult:
files = sorted((entry for entry in directory.iterdir() if entry.is_file()), key=lambda path: path.name.lower())
casefold_name_index = _build_casefold_name_index(files)
global_images = select_first_matching_image_family(files, GLOBAL_IMAGE_PREFIXES)
language_assets: list[LanguageAssets] = []
for language in (Language.FI, Language.SV, Language.EN):
text_file = select_first_matching_text_file(casefold_name_index, LANGUAGE_TEXT_CANDIDATES[language])
if text_file is None:
continue
text_raw = text_file.read_text(encoding="utf-8")
if text_raw.strip() == "":
continue
language_images = select_first_matching_image_family(files, LANGUAGE_IMAGE_PREFIXES[language])
language_assets.append(
LanguageAssets(
language=language,
text_file=text_file,
text_raw=text_raw,
images=language_images,
)
)
return ScanResult(global_images=global_images, languages=language_assets)
def select_first_matching_text_file(casefold_name_index: dict[str, Path], candidate_names: list[str]) -> Path | None:
for candidate_name in candidate_names:
match = casefold_name_index.get(candidate_name.lower())
if match is not None:
return match
return None
def select_first_matching_image_family(files: list[Path], prefixes: list[str]) -> list[Path]:
for prefix in prefixes:
matches = collect_image_matches_for_prefix(files, prefix)
if matches:
return [match[0] for match in sorted(matches, key=image_sort_key)]
return []
def collect_image_matches_for_prefix(files: list[Path], prefix: str) -> list[tuple[Path, str, str]]:
pattern = re.compile(rf"^{re.escape(prefix)}(\d*)\.([^.]+)$", re.IGNORECASE)
matches: list[tuple[Path, str, str]] = []
for file_path in files:
match = pattern.match(file_path.name)
if match is None:
continue
extension = match.group(2).lower()
if extension not in KNOWN_IMAGE_EXTENSIONS:
continue
numeric_suffix = match.group(1)
matches.append((file_path, numeric_suffix, extension))
return matches
def image_sort_key(match_item: tuple[Path, str, str]) -> tuple[int, int, str, str]:
file_path, numeric_suffix, extension = match_item
has_numeric_suffix = numeric_suffix != ""
numeric_value = int(numeric_suffix) if has_numeric_suffix else -1
return (
1 if has_numeric_suffix else 0,
numeric_value,
extension.lower(),
file_path.name.lower(),
)
def _build_casefold_name_index(files: list[Path]) -> dict[str, Path]:
index: dict[str, Path] = {}
for file_path in files:
lowered = file_path.name.lower()
if lowered not in index:
index[lowered] = file_path
return index