defmodule BazVenueAdapterOpenSea.FetchCollectionEventPageBySlug do
@moduledoc """
Implementation of the Baz.VenueAdapter.fetch_collection_event_page_by_slug/4 callback
"""
defmodule Input do
defstruct ~w[slug token_ids page_cursor page_limit]a
end
alias BazVenueAdapterOpenSea.Credentials
alias BazVenueAdapterOpenSea.ApiClient
@type venue :: Baz.VenueAdapter.venue()
@type slug :: Baz.VenueAdapter.collection_slug()
@type token_ids :: Baz.VenueAdapter.token_ids()
@type page_cursor :: Baz.Page.cursor()
@type result :: Baz.VenueAdapter.fetch_collection_event_page_by_slug_result()
@default_page_limit 300
@spec fetch_collection_event_page_by_slug(venue, slug, token_ids, page_cursor) :: result
def fetch_collection_event_page_by_slug(venue, slug, token_ids, page_cursor) do
input = %Input{
slug: slug,
token_ids: token_ids,
page_cursor: page_cursor,
page_limit: @default_page_limit
}
{venue, input}
|> with_api_key()
|> fetch()
|> write_to_raw_sinks()
|> build_changset()
end
defp with_api_key({venue, input}) do
case Credentials.get_api_key(venue.credentials) do
{:ok, api_key} -> {venue, input, api_key}
{:error, :not_found} -> {:error, :api_key_not_found}
end
end
defp fetch({venue, input, api_key}) do
params = build_params(input)
api_result = ApiClient.fetch_collection_event_page_by_slug(params, api_key)
{venue, input, api_key, api_result}
end
defp fetch({:error, _reason} = error), do: error
defp write_to_raw_sinks({venue, input, _api_key, api_result} = args) do
:ok = Baz.Sinks.write_raw(:collection_events, venue, input, api_result)
args
end
defp write_to_raw_sinks({:error, _reason} = error), do: error
defp build_changset({venue, input, _api_key, api_result}) do
case api_result do
{:ok, cursor, _} ->
events = build_events(venue, input.slug, cursor)
%Baz.Page{data: events, next_page_cursor: cursor.next}
{:error, reason, _} ->
{:error, reason}
end
end
defp build_changset({:error, _reason} = error), do: error
defp build_params(input) do
p = %{collection_slug: input.slug, limit: input.page_limit}
p = if input.token_ids != nil, do: Map.put(p, :token_ids, input.token_ids), else: p
if input.page_cursor != nil, do: Map.put(p, :cursor, input.page_cursor), else: p
end
defp build_events(venue, slug, cursor) do
cursor.asset_events
|> Enum.map(fn venue_event ->
{venue, slug, venue_event}
|> build_event_attrs()
|> Baz.CollectionEvents.collection_event_changeset()
end)
end
defp build_event_attrs({venue, slug, venue_event}) do
%{
venue: venue.name,
slug: slug,
token_id: venue_event.asset["token_id"],
source_id: "#{venue_event.id}",
event_type: venue_event.event_type,
event_timestamp: venue_event.event_timestamp
}
end
end