73 lines
2.1 KiB
Python
73 lines
2.1 KiB
Python
from typing import Any
|
|
|
|
import httpx
|
|
|
|
from app.config import get_settings
|
|
|
|
# wger language ids (https://wger.de/api/v2/language/)
|
|
_LANG_RU = 5
|
|
_LANG_EN = 2
|
|
|
|
|
|
class WgerClient:
|
|
def __init__(self) -> None:
|
|
settings = get_settings()
|
|
self.base_url = settings.wger_base_url.rstrip("/")
|
|
|
|
@staticmethod
|
|
def _pick_name(item: dict[str, Any]) -> str:
|
|
translations = item.get("translations") or []
|
|
for lang_id in (_LANG_RU, _LANG_EN):
|
|
for tr in translations:
|
|
if tr.get("language") == lang_id and tr.get("name"):
|
|
return str(tr["name"])
|
|
for tr in translations:
|
|
if tr.get("name"):
|
|
return str(tr["name"])
|
|
return f"#{item.get('id')}"
|
|
|
|
def _fetch_exerciseinfo(
|
|
self,
|
|
client: httpx.Client,
|
|
*,
|
|
query: str,
|
|
languagecode: str,
|
|
limit: int,
|
|
) -> list[dict[str, Any]]:
|
|
response = client.get(
|
|
f"{self.base_url}/exerciseinfo/",
|
|
params={
|
|
"name__search": query,
|
|
"languagecode": languagecode,
|
|
"limit": limit,
|
|
},
|
|
)
|
|
response.raise_for_status()
|
|
return response.json().get("results") or []
|
|
|
|
def search_exercises(self, query: str, limit: int = 8) -> list[dict[str, Any]]:
|
|
query = query.strip()
|
|
if not query:
|
|
return []
|
|
|
|
with httpx.Client(timeout=20.0) as client:
|
|
results = self._fetch_exerciseinfo(
|
|
client, query=query, languagecode="ru", limit=limit
|
|
)
|
|
if not results:
|
|
results = self._fetch_exerciseinfo(
|
|
client, query=query, languagecode="en", limit=limit
|
|
)
|
|
|
|
out: list[dict[str, Any]] = []
|
|
for item in results[:limit]:
|
|
category = item.get("category") or {}
|
|
out.append(
|
|
{
|
|
"id": item.get("id"),
|
|
"name": self._pick_name(item),
|
|
"category": category.get("name") if isinstance(category, dict) else category,
|
|
}
|
|
)
|
|
return out
|