Add multi-provider event discovery and improve sync UI
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
from datetime import datetime
|
||||
from urllib.parse import quote
|
||||
|
||||
import requests
|
||||
|
||||
from app.config import settings
|
||||
from app.models import RegionScope, WatchType
|
||||
|
||||
|
||||
class BandsintownProvider:
|
||||
base_url = "https://rest.bandsintown.com"
|
||||
source_name = "bandsintown"
|
||||
|
||||
def is_configured(self) -> bool:
|
||||
return bool(settings.bandsintown_app_id)
|
||||
|
||||
def search_events(
|
||||
self,
|
||||
term: str,
|
||||
watch_type: WatchType,
|
||||
region_scope: RegionScope,
|
||||
) -> list[dict]:
|
||||
if not self.is_configured():
|
||||
return []
|
||||
|
||||
if watch_type != WatchType.artist:
|
||||
return []
|
||||
|
||||
artist_name = quote(term, safe="")
|
||||
url = f"{self.base_url}/artists/{artist_name}/events"
|
||||
response = requests.get(
|
||||
url,
|
||||
params={"app_id": settings.bandsintown_app_id, "date": "upcoming"},
|
||||
timeout=30,
|
||||
)
|
||||
|
||||
if response.status_code == 404:
|
||||
return []
|
||||
|
||||
response.raise_for_status()
|
||||
payload = response.json()
|
||||
if not isinstance(payload, list):
|
||||
return []
|
||||
|
||||
results: list[dict] = []
|
||||
for item in payload:
|
||||
venue = item.get("venue") or {}
|
||||
city = venue.get("city")
|
||||
country = venue.get("country")
|
||||
|
||||
if region_scope == RegionScope.hamburg and (city or "").casefold() != "hamburg":
|
||||
continue
|
||||
if region_scope == RegionScope.germany and (country or "").casefold() != "germany":
|
||||
continue
|
||||
|
||||
datetime_value = item.get("datetime")
|
||||
event_date = None
|
||||
if datetime_value:
|
||||
try:
|
||||
event_date = datetime.fromisoformat(
|
||||
datetime_value.replace("Z", "+00:00")
|
||||
).replace(tzinfo=None)
|
||||
except ValueError:
|
||||
event_date = None
|
||||
|
||||
offers = item.get("offers") or []
|
||||
ticket_url = next((offer.get("url") for offer in offers if offer.get("url")), None)
|
||||
|
||||
results.append(
|
||||
{
|
||||
"external_id": str(item.get("id")),
|
||||
"title": item.get("title") or f"{term} live",
|
||||
"matched_term": term,
|
||||
"venue_name": venue.get("name"),
|
||||
"city": city,
|
||||
"country_code": "DE" if country == "Germany" else country,
|
||||
"event_date": event_date,
|
||||
"ticket_url": ticket_url or item.get("url"),
|
||||
"image_url": item.get("artist", {}).get("thumb_url"),
|
||||
"raw_payload": item,
|
||||
}
|
||||
)
|
||||
|
||||
return results
|
||||
|
||||
Reference in New Issue
Block a user