mirror of
https://github.com/algora-io/tv.git
synced 2025-03-17 20:17:45 +02:00
220 lines
5.8 KiB
Elixir
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
|