Files
eventlens/backend/app/providers/ticketmaster.py
T
2026-04-09 19:00:12 +02:00

92 lines
2.9 KiB
Python

from datetime import datetime
import requests
from app.config import settings
from app.models import RegionScope, WatchType
class TicketmasterProvider:
base_url = "https://app.ticketmaster.com/discovery/v2/events.json"
source_name = "ticketmaster"
def is_configured(self) -> bool:
return bool(settings.ticketmaster_api_key)
def search_events(
self,
term: str,
watch_type: WatchType,
region_scope: RegionScope,
) -> list[dict]:
if not self.is_configured():
return []
params = {
"apikey": settings.ticketmaster_api_key,
"keyword": term,
"locale": "*",
"size": 50,
"sort": "date,asc",
"countryCode": "DE",
}
if region_scope == RegionScope.hamburg:
params["city"] = "Hamburg"
response = requests.get(self.base_url, params=params, timeout=30)
response.raise_for_status()
payload = response.json()
items = payload.get("_embedded", {}).get("events", [])
results: list[dict] = []
normalized_term = term.casefold()
for item in items:
title = item.get("name", "")
attractions = item.get("_embedded", {}).get("attractions", [])
attraction_names = [entry.get("name", "") for entry in attractions]
if watch_type == WatchType.artist:
haystack = " ".join(attraction_names + [title]).casefold()
if normalized_term not in haystack:
continue
elif normalized_term not in title.casefold():
continue
dates = item.get("dates", {}).get("start", {})
local_date = dates.get("localDate")
local_time = dates.get("localTime", "20:00:00")
event_date = None
if local_date:
try:
event_date = datetime.fromisoformat(f"{local_date}T{local_time}")
except ValueError:
event_date = datetime.fromisoformat(f"{local_date}T20:00:00")
venue = (
item.get("_embedded", {})
.get("venues", [{}])[0]
)
results.append(
{
"external_id": item.get("id"),
"title": title,
"matched_term": term,
"venue_name": venue.get("name"),
"city": venue.get("city", {}).get("name"),
"country_code": venue.get("country", {}).get("countryCode"),
"event_date": event_date,
"ticket_url": item.get("url"),
"image_url": next(
(image.get("url") for image in item.get("images", []) if image.get("url")),
None,
),
"raw_payload": item,
}
)
return results