1
0
mirror of https://github.com/algora-io/tv.git synced 2025-03-17 20:17:45 +02:00
algora-tv/lib/algora/events.ex
2024-06-09 13:30:44 +03:00

220 lines
5.8 KiB
Elixir

defmodule Algora.Events do
import Ecto.Query
alias Algora.{Repo}
alias Algora.Library.Video
alias Algora.Events.Event
alias Algora.Accounts.{User, Identity}
def unsubscribe(user, channel_id) do
%Event{
actor_id: "user_#{user.id}",
user_id: user.id,
channel_id: channel_id,
name: :unsubscribed
}
|> Event.changeset(%{})
|> Repo.insert()
end
def toggle_subscription_event(user, show) do
name = if subscribed?(user, show), do: :unsubscribed, else: :subscribed
%Event{
actor_id: "user_#{user.id}",
user_id: user.id,
show_id: show.id,
channel_id: show.user_id,
name: name
}
|> Event.changeset(%{})
|> Repo.insert()
end
def toggle_rsvp_event(user, show) do
name = if rsvpd?(user, show), do: :unrsvpd, else: :rsvpd
%Event{
actor_id: "user_#{user.id}",
user_id: user.id,
show_id: show.id,
channel_id: show.user_id,
name: name
}
|> Event.changeset(%{})
|> Repo.insert()
end
def subscribed?(nil, _show), do: false
def subscribed?(user, show) do
event =
from(
e in Event,
where:
e.channel_id == ^show.user_id and
e.user_id == ^user.id and
(e.name == :subscribed or
e.name == :unsubscribed),
order_by: [desc: e.inserted_at],
limit: 1
)
|> Repo.one()
event && event.name == :subscribed
end
def rsvpd?(nil, _show), do: false
def rsvpd?(user, show) do
event =
from(
e in Event,
where:
e.channel_id == ^show.user_id and
e.user_id == ^user.id and
(e.name == :rsvpd or
e.name == :unrsvpd),
order_by: [desc: e.inserted_at],
limit: 1
)
|> Repo.one()
event && event.name == :rsvpd
end
def fetch_attendees(show) do
# Get the latest relevant events (:rsvpd and :unrsvpd) for each user
latest_events_query =
from(e in Event,
where: e.channel_id == ^show.user_id and e.name in [:rsvpd, :unrsvpd],
order_by: [desc: e.inserted_at],
distinct: e.user_id
)
# Join user data and filter for :rsvpd events
from(e in subquery(latest_events_query),
join: u in User,
on: e.user_id == u.id,
join: i in Identity,
on: i.user_id == u.id and i.provider == "github",
select_merge: %{
user_handle: u.handle,
user_display_name: coalesce(u.name, u.handle),
user_email: u.email,
user_avatar_url: u.avatar_url,
user_github_handle: i.provider_login
},
where: e.name == :rsvpd,
order_by: [desc: e.inserted_at, desc: e.id]
)
|> Repo.all()
end
def fetch_unique_viewers(user) do
subquery_first_watched =
from(e in Event,
where: e.channel_id == ^user.id and e.name in [:watched, :subscribed],
order_by: [asc: e.inserted_at],
distinct: e.user_id
)
from(e in subquery(subquery_first_watched),
join: u in User,
on: e.user_id == u.id,
join: i in Identity,
on: i.user_id == u.id and i.provider == "github",
left_join: v in Video,
on: e.video_id == v.id,
select_merge: %{
user_handle: u.handle,
user_display_name: coalesce(u.name, u.handle),
user_email: u.email,
user_avatar_url: u.avatar_url,
user_github_handle: i.provider_login,
first_video_id: e.video_id,
first_video_title: v.title
},
distinct: e.user_id,
order_by: [desc: e.inserted_at, desc: e.id]
)
|> Repo.all()
end
def fetch_unique_subscribers(user) do
# Get the latest relevant events (:subscribed and :unsubscribed) for each user
latest_events_query =
from(e in Event,
where: e.channel_id == ^user.id and e.name in [:subscribed, :unsubscribed],
order_by: [desc: e.inserted_at],
distinct: e.user_id
)
# Join user data and filter for :subscribed events
from(e in subquery(latest_events_query),
join: u in User,
on: e.user_id == u.id,
join: i in Identity,
on: i.user_id == u.id and i.provider == "github",
left_join: v in Video,
on: e.video_id == v.id,
select_merge: %{
user_handle: u.handle,
user_display_name: coalesce(u.name, u.handle),
user_email: u.email,
user_avatar_url: u.avatar_url,
user_github_handle: i.provider_login,
first_video_id: e.video_id,
first_video_title: v.title
},
where: e.name == :subscribed,
order_by: [desc: e.inserted_at, desc: e.id]
)
|> Repo.all()
end
def fetch_subscriptions(user) do
# Get the latest relevant events (:subscribed and :unsubscribed) for each user
latest_events_query =
from(e in Event,
where: e.user_id == ^user.id and e.name in [:subscribed, :unsubscribed],
order_by: [desc: e.inserted_at],
distinct: e.channel_id
)
# Join user data and filter for :subscribed events
from(e in subquery(latest_events_query),
join: u in User,
on: e.channel_id == u.id,
join: i in Identity,
on: i.user_id == u.id and i.provider == "github",
select_merge: %{
user_handle: u.handle,
user_display_name: coalesce(u.name, u.handle),
user_avatar_url: u.avatar_url,
user_meta: i.provider_meta
},
where: e.name == :subscribed,
order_by: [desc: e.inserted_at, desc: e.id]
)
|> Repo.all()
end
def log_watched(user, video) do
actor_id = if user, do: "user_#{user.id}", else: "guest_#{hash_actor_id()}"
%Event{
actor_id: actor_id,
user_id: user && user.id,
video_id: video.id,
channel_id: video.user_id,
name: :watched
}
|> Event.changeset(%{})
|> Repo.insert()
end
# TODO:
defp hash_actor_id, do: ""
end