Improve json-ld metadata on event live streams

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2021-11-15 12:11:29 +01:00
parent bcf17fe30b
commit 85ceb1de47
No known key found for this signature in database
GPG key ID: A061B9DDE0CA0773
2 changed files with 54 additions and 22 deletions

View file

@ -29,7 +29,7 @@ defmodule Mobilizon.Service.Metadata.Utils do
* Slices it to a limit and add an ellipsis character
* Returns a default description if text is empty
"""
@spec process_description(String.t(), String.t(), integer()) :: String.t()
@spec process_description(String.t(), String.t(), integer() | nil) :: String.t()
def process_description(description, locale \\ "en", limit \\ @slice_limit)
def process_description(nil, locale, limit), do: process_description("", locale, limit)
@ -56,6 +56,8 @@ defmodule Mobilizon.Service.Metadata.Utils do
defdelegate datetime_to_string(datetime, locale \\ "en", format \\ :medium), to: DateTime
defdelegate render_address(address), to: Address
defp maybe_slice(description, nil), do: description
defp maybe_slice(description, limit) do
if String.length(description) > limit do
description

View file

@ -9,6 +9,9 @@ defmodule Mobilizon.Web.JsonLD.ObjectView do
alias Mobilizon.Web.JsonLD.ObjectView
alias Mobilizon.Web.Router.Helpers, as: Routes
import Mobilizon.Service.Metadata.Utils,
only: [process_description: 3]
@spec render(String.t(), map()) :: map()
def render("group.json", %{group: %Actor{} = group}) do
res = %{
@ -54,12 +57,12 @@ defmodule Mobilizon.Web.JsonLD.ObjectView do
"@context" => "https://schema.org",
"@type" => "Event",
"name" => event.title,
"description" => event.description,
"description" => process_description(event.description, "en", nil),
# We assume for now performer == organizer
"performer" => organizer,
"organizer" => organizer,
"location" => render_location(event),
"eventAttendanceMode" => eventAttendanceMode(event),
"location" => render_all_locations(event),
"eventAttendanceMode" => event |> attendance_mode() |> event_attendance_mode(),
"eventStatus" =>
if(event.status == :cancelled,
do: "https://schema.org/EventCancelled",
@ -164,39 +167,66 @@ defmodule Mobilizon.Web.JsonLD.ObjectView do
defp reservation_status(:not_approved), do: "https://schema.org/ReservationHold"
defp reservation_status(_), do: "https://schema.org/ReservationConfirmed"
@spec render_location(map()) :: map() | nil
defp render_location(%{physical_address: %Address{} = address}),
do: render_one(address, ObjectView, "place.json", as: :address)
defp render_all_locations(%Event{} = event) do
[]
|> render_location(event)
|> render_virtual_location(event)
end
@spec render_location(list(), map()) :: list()
defp render_location(locations, %{physical_address: %Address{} = address}),
do: locations ++ [render_one(address, ObjectView, "place.json", as: :address)]
defp render_location(locations, _), do: locations
# For now the Virtual Location of an event is it's own URL,
# but in the future it will be a special field
defp render_location(%Event{url: event_url}) do
%{
defp render_virtual_location(locations, %Event{
url: event_url,
metadata: metadata,
options: %EventOptions{is_online: is_online}
}) do
links = virtual_location_links(metadata)
fallback_links = if is_online, do: [event_url], else: []
links = if length(links) > 0, do: Enum.map(links, & &1.value), else: fallback_links
locations ++
Enum.map(
links,
&%{
"@type" => "VirtualLocation",
"url" => event_url
"url" => &1
}
)
end
defp render_location(_), do: nil
defp render_virtual_location(locations, _), do: locations
defp render_address(%{physical_address: %Address{} = address}),
do: render_one(address, ObjectView, "address.json", as: :address)
defp render_address(_), do: nil
@livestream_keys ["mz:live", "mz:visio"]
defp event_attendance_mode(:online), do: "https://schema.org/OnlineEventAttendanceMode"
defp event_attendance_mode(:offline), do: "https://schema.org/OfflineEventAttendanceMode"
defp event_attendance_mode(:mixed), do: "https://schema.org/MixedEventAttendanceMode"
defp eventAttendanceMode(%Event{options: %EventOptions{is_online: true}}),
do: "https://schema.org/OnlineEventAttendanceMode"
defp attendance_mode(%Event{options: %EventOptions{is_online: true}}),
do: :online
defp eventAttendanceMode(%Event{physical_address: %Address{}, metadata: metadata}) do
if Enum.any?(metadata, &String.contains?(&1["key"], @livestream_keys)) do
"https://schema.org/MixedEventAttendanceMode"
defp attendance_mode(%Event{physical_address: %Address{}, metadata: metadata}) do
if metadata |> virtual_location_links() |> length() > 0 do
:mixed
else
"https://schema.org/OfflineEventAttendanceMode"
:offline
end
end
defp eventAttendanceMode(%Event{}),
do: "https://schema.org/OfflineEventAttendanceMode"
defp attendance_mode(%Event{}),
do: :offline
@livestream_keys ["mz:live", "mz:visio"]
@spec virtual_location_links(list()) :: list()
defp virtual_location_links(metadata),
do: Enum.filter(metadata, &String.contains?(&1.key, @livestream_keys))
end