myYouTube/backend/app/core/slugify.py

30 lines
938 B
Python
Raw Normal View History

import re
_CYRILLIC_MAP = {
"а": "a", "б": "b", "в": "v", "г": "g", "д": "d", "е": "e", "ё": "e",
"ж": "zh", "з": "z", "и": "i", "й": "y", "к": "k", "л": "l", "м": "m",
"н": "n", "о": "o", "п": "p", "р": "r", "с": "s", "т": "t", "у": "u",
"ф": "f", "х": "h", "ц": "ts", "ч": "ch", "ш": "sh", "щ": "sch", "ъ": "",
"ы": "y", "ь": "", "э": "e", "ю": "yu", "я": "ya",
}
def _transliterate(text: str) -> str:
return "".join(_CYRILLIC_MAP.get(ch, ch) for ch in text)
def slugify(text: str) -> str:
text = _transliterate(text.lower())
text = re.sub(r"[^a-z0-9]+", "-", text).strip("-")
return text or "category"
def unique_slugify(text: str, existing_slugs: set[str]) -> str:
base = slugify(text)
if base not in existing_slugs:
return base
suffix = 2
while f"{base}-{suffix}" in existing_slugs:
suffix += 1
return f"{base}-{suffix}"