forked from potsda.mn/mobilizon
Improve json-ld metadata on event live streams
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
parent
bcf17fe30b
commit
85ceb1de47
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue