eventcally/project/jsonld.py
2023-04-19 15:32:30 +02:00

184 lines
5.2 KiB
Python

import datetime
from flask import url_for
from flask.json.provider import DefaultJSONProvider
from project.dateutils import berlin_tz
from project.jinja_filters import url_for_image
from project.models import EventAttendanceMode, EventStatus
class CustomJsonProvider(DefaultJSONProvider):
@staticmethod
def default(obj):
if isinstance(obj, datetime.datetime):
return (obj.astimezone(berlin_tz)).isoformat()
elif isinstance(obj, datetime.date):
return obj.isoformat()
# pragma: no cover
return super(CustomJsonProvider, CustomJsonProvider).default(obj)
def get_sd_for_admin_unit(admin_unit):
result = {}
result["@type"] = "Organization"
result["identifier"] = str(admin_unit.id)
result["name"] = admin_unit.name
if admin_unit.url:
result["url"] = admin_unit.url
return result
def get_sd_for_organizer(organizer):
result = {}
result["@type"] = "Organization"
result["name"] = organizer.name
if organizer.email:
result["email"] = organizer.email
if organizer.phone:
result["phone"] = organizer.phone
if organizer.fax:
result["faxNumber"] = organizer.fax
if organizer.url:
result["url"] = organizer.url
return result
def get_sd_for_location(location):
result = {}
result["@type"] = "PostalAddress"
result["addressCountry"] = "DE"
if location.street:
result["streetAddress"] = location.street
if location.postalCode:
result["postalCode"] = location.postalCode
if location.city:
result["addressLocality"] = location.city
return result
def get_sd_for_geo(location):
result = {}
result["@type"] = "GeoCoordinates"
result["latitude"] = location.latitude
result["longitude"] = location.longitude
return result
def get_sd_for_place(place, use_ref=True):
result = {}
result["@type"] = "Place"
result["name"] = place.name
if place.location:
result["address"] = get_sd_for_location(place.location)
if place.location.coordinate:
result["geo"] = get_sd_for_geo(place.location)
if place.photo_id:
result["photo"] = url_for_image(place.photo)
if place.url:
result["url"] = place.url
return result
def get_date_from_datetime(value: datetime.datetime) -> datetime.date:
return value.astimezone(berlin_tz).date()
def get_sd_for_event_date(event_date):
event = event_date.event
result = {}
result["@context"] = "https://schema.org"
result["@type"] = "Event"
result["identifier"] = str(event_date.id)
result["name"] = event.name
result["description"] = event.description
result["startDate"] = event_date.start
if event_date.end:
result["endDate"] = event_date.end
if event.previous_start_date:
result["previousStartDate"] = event.previous_start_date
if event_date.allday:
result["startDate"] = get_date_from_datetime(result["startDate"])
if event_date.end:
result["endDate"] = get_date_from_datetime(result["endDate"])
url_list = list()
url_list.append(url_for("event_date", id=event_date.id))
if event.external_link:
url_list.append(event.external_link)
if event.ticket_link:
url_list.append(event.ticket_link)
result["url"] = url_list
result["location"] = get_sd_for_place(event.event_place)
organizer_list = list()
if event.organizer:
organizer_list.append(get_sd_for_organizer(event.organizer))
for co_organizer in event.co_organizers:
organizer_list.append(get_sd_for_organizer(co_organizer))
if event.admin_unit:
organizer_list.append(get_sd_for_admin_unit(event.admin_unit))
result["organizer"] = organizer_list
if event.accessible_for_free:
result["isAccessibleForFree"] = event.accessible_for_free
if event.age_from and event.age_to:
result["typicalAgeRange"] = "%d-%d" % (event.age_from, event.age_to)
elif event.age_from:
result["typicalAgeRange"] = "%d-" % event.age_from
elif event.age_to:
result["typicalAgeRange"] = "-%d" % event.age_to
if event.attendance_mode:
if event.attendance_mode == EventAttendanceMode.offline:
result["eventAttendanceMode"] = "OfflineEventAttendanceMode"
elif event.attendance_mode == EventAttendanceMode.online:
result["eventAttendanceMode"] = "OnlineEventAttendanceMode"
elif event.attendance_mode == EventAttendanceMode.mixed:
result["eventAttendanceMode"] = "MixedEventAttendanceMode"
if event.status:
if event.status == EventStatus.scheduled:
result["eventStatus"] = "EventScheduled"
elif event.status == EventStatus.cancelled:
result["eventStatus"] = "EventCancelled"
elif event.status == EventStatus.movedOnline:
result["eventStatus"] = "EventMovedOnline"
elif event.status == EventStatus.postponed:
result["eventStatus"] = "EventPostponed"
elif event.status == EventStatus.rescheduled:
result["eventStatus"] = "EventRescheduled"
if event.photo_id:
result["image"] = url_for_image(event.photo)
return result