breaking code down
All checks were successful
Build Authoring Service / build (push) Successful in 8s
All checks were successful
Build Authoring Service / build (push) Successful in 8s
This commit is contained in:
57
src/authoring_service/utils.py
Normal file
57
src/authoring_service/utils.py
Normal file
@@ -0,0 +1,57 @@
|
||||
"""Small formatting and parsing helpers."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
def slugify(value: str) -> str:
|
||||
slug = re.sub(r"[^a-z0-9]+", "-", value.lower()).strip("-")
|
||||
return slug or "untitled"
|
||||
|
||||
|
||||
def normalise_tags(value: Any) -> list[str]:
|
||||
if isinstance(value, str):
|
||||
raw = re.split(r"[,:\s]+", value)
|
||||
elif isinstance(value, list):
|
||||
raw = [str(item) for item in value]
|
||||
else:
|
||||
raw = []
|
||||
tags = []
|
||||
for tag in raw:
|
||||
if not tag.strip():
|
||||
continue
|
||||
clean = slugify(tag)
|
||||
if clean and clean not in tags:
|
||||
tags.append(clean)
|
||||
return tags
|
||||
|
||||
|
||||
def org_date(dt: datetime) -> str:
|
||||
return dt.strftime("<%Y-%m-%d %a %H:%M>")
|
||||
|
||||
|
||||
def parse_org_datetime(value: str | None) -> datetime | None:
|
||||
if not value:
|
||||
return None
|
||||
match = re.search(r"<(\d{4})-(\d{2})-(\d{2})(?:\s+\w+)?(?:\s+(\d{2}):(\d{2}))?>", value)
|
||||
if not match:
|
||||
return None
|
||||
year, month, day, hour, minute = match.groups()
|
||||
return datetime(
|
||||
int(year),
|
||||
int(month),
|
||||
int(day),
|
||||
int(hour or 12),
|
||||
int(minute or 0),
|
||||
)
|
||||
|
||||
|
||||
def html_escape(value: str) -> str:
|
||||
return (
|
||||
value.replace("&", "&")
|
||||
.replace("<", "<")
|
||||
.replace(">", ">")
|
||||
.replace('"', """)
|
||||
)
|
||||
Reference in New Issue
Block a user