Nova aplikacija "Namaz" (vaktija)
Vremena dnevnih namaza (sabah, podne, ikindija, akšam, jacija) sa api.vaktija.ba. - idriz/apps/vaktija/store.py: izbor lokacije + bundlana lista (lokacije.json, 118 lokacija; id=indeks). Sarajevo default. Bez openai/requests (uvozi ga admin). - client.py: dohvat vakat[] po (lokacija, datum) sa keširanjem; API vraća lokalna vremena (sam vodi DST). vakat[1] je izlazak sunca (nije namaz), preskočen. - manifest.py: alat namaz_vrijeme(koji): 'sljedeci' = prvi nadolazeći (ili sutra sabah ako su svi prošli); ili konkretan namaz (danas ako nadolazi, inače sutra). Bosanska gramatika za "za X sati/minuta" i rod (prošao/prošlo/prošla). - admin.py + templates/vaktija.html: dropdown svih lokacija, Sarajevo default. - Registrovano u load_apps() i ADMIN_APPS. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LzKpYaEsuWDevuNnvSjcFW
This commit is contained in:
61
idriz/apps/vaktija/store.py
Normal file
61
idriz/apps/vaktija/store.py
Normal file
@@ -0,0 +1,61 @@
|
||||
"""Skladište za app 'Namaz': izbor lokacije + bundlana lista lokacija.
|
||||
|
||||
Bez openai/requests (uvozi ga i admin). Lista lokacija je bundlana (lokacije.json);
|
||||
id lokacije = indeks u toj listi (kako radi api.vaktija.ba).
|
||||
"""
|
||||
import json
|
||||
import os
|
||||
import tempfile
|
||||
import threading
|
||||
from pathlib import Path
|
||||
|
||||
VAKTIJA_CONFIG_PATH = Path(os.environ.get(
|
||||
"IDRIZ_VAKTIJA_CONFIG_PATH", str(Path.home() / ".config/idriz/vaktija.json")))
|
||||
|
||||
DEFAULT_ID = 77 # Sarajevo
|
||||
_LOCATIONS_FILE = Path(__file__).with_name("lokacije.json")
|
||||
_lock = threading.Lock()
|
||||
|
||||
try:
|
||||
_LOCATIONS: list[str] = json.loads(_LOCATIONS_FILE.read_text(encoding="utf-8"))
|
||||
except (OSError, json.JSONDecodeError):
|
||||
_LOCATIONS = ["Sarajevo"]
|
||||
|
||||
|
||||
def locations() -> list[dict]:
|
||||
"""Sve lokacije kao [{'id': i, 'naziv': ...}], abecedno po nazivu."""
|
||||
return sorted(({"id": i, "naziv": n} for i, n in enumerate(_LOCATIONS)),
|
||||
key=lambda x: x["naziv"].lower())
|
||||
|
||||
|
||||
def valid_id(loc_id: int) -> bool:
|
||||
return isinstance(loc_id, int) and 0 <= loc_id < len(_LOCATIONS)
|
||||
|
||||
|
||||
def location_name(loc_id: int) -> str:
|
||||
return _LOCATIONS[loc_id] if valid_id(loc_id) else "Sarajevo"
|
||||
|
||||
|
||||
def get_location_id() -> int:
|
||||
try:
|
||||
data = json.loads(VAKTIJA_CONFIG_PATH.read_text(encoding="utf-8"))
|
||||
loc = int(data.get("lokacija_id", DEFAULT_ID))
|
||||
except (OSError, ValueError, json.JSONDecodeError):
|
||||
return DEFAULT_ID
|
||||
return loc if valid_id(loc) else DEFAULT_ID
|
||||
|
||||
|
||||
def set_location_id(loc_id: int) -> int:
|
||||
if not valid_id(loc_id):
|
||||
loc_id = DEFAULT_ID
|
||||
with _lock:
|
||||
VAKTIJA_CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
|
||||
fd, tmp = tempfile.mkstemp(dir=str(VAKTIJA_CONFIG_PATH.parent), suffix=".tmp")
|
||||
try:
|
||||
with os.fdopen(fd, "w", encoding="utf-8") as f:
|
||||
json.dump({"lokacija_id": loc_id}, f, ensure_ascii=False, indent=2)
|
||||
os.replace(tmp, VAKTIJA_CONFIG_PATH)
|
||||
finally:
|
||||
if os.path.exists(tmp):
|
||||
os.unlink(tmp)
|
||||
return loc_id
|
||||
Reference in New Issue
Block a user