""" Вспомогательные функции для работы со справочниками стран, городов и часовых поясов. Пока данные хранятся в JSON-файлах внутри приложения users. В будущем можно перенести это в модели БД. """ import json import os from functools import lru_cache from typing import List, Dict, Any, Optional BASE_DIR = os.path.dirname(os.path.abspath(__file__)) DATA_DIR = os.path.join(BASE_DIR, "geo_data") def _load_json(filename: str) -> Any: path = os.path.join(DATA_DIR, filename) if not os.path.exists(path): return [] with open(path, "r", encoding="utf-8") as f: return json.load(f) @lru_cache(maxsize=1) def get_countries() -> List[Dict[str, Any]]: """ Получить список стран. Формат элементов: { "code": "RU", "name": "Россия" } """ return _load_json("countries.json") @lru_cache(maxsize=1) def get_timezones() -> List[Dict[str, Any]]: """ Получить список часовых поясов. Формат элементов: { "name": "Europe/Moscow", "offset": "+03:00" } """ return _load_json("timezones.json") @lru_cache(maxsize=None) def get_cities_for_country(country_code: str) -> List[Dict[str, Any]]: """ Получить список городов для заданной страны. Пока реализовано только для России (RU). Формат элементов: { "country_code": "RU", "country_name": "Россия", "city": "Москва", "timezone": "Europe/Moscow" } """ code = country_code.upper() if code == "RU": return _load_json("cities_ru.json") # Для других стран можно добавить отдельные файлы и условия return [] def search_cities(country: Optional[str] = None, query: Optional[str] = None) -> List[Dict[str, Any]]: """ Поиск городов по стране и части названия. """ cities: List[Dict[str, Any]] = [] if country: # Предполагаем, что приходит код страны (RU) или название code = country.upper() if len(code) == 2: cities = get_cities_for_country(code) else: # Ищем по названию страны в списке стран и берём по коду for c in get_countries(): if c.get("name", "").lower().startswith(country.lower()): cities = get_cities_for_country(c.get("code", "")) break else: # Если страна не указана, возвращаем только базовый список популярных городов России cities = get_cities_for_country("RU") if query: q = query.lower() cities = [c for c in cities if q in c.get("city", "").lower()] return cities