diff --git a/lib/philomena/application.ex b/lib/philomena/application.ex index cb59ae33..4c4ad8c7 100644 --- a/lib/philomena/application.ex +++ b/lib/philomena/application.ex @@ -16,6 +16,7 @@ defmodule Philomena.Application do # {Philomena.Worker, arg}, Philomena.Servers.ImageProcessor, Philomena.Servers.UserLinkUpdater, + Philomena.Servers.PicartoChannelUpdater, Pow.Store.Backend.MnesiaCache, {Redix, name: :redix, host: Application.get_env(:philomena, :redis_host)} ] diff --git a/lib/philomena/channels/channel.ex b/lib/philomena/channels/channel.ex index 1156c095..e27f7514 100644 --- a/lib/philomena/channels/channel.ex +++ b/lib/philomena/channels/channel.ex @@ -30,6 +30,8 @@ defmodule Philomena.Channels.Channel do field :channel_image, :string field :remote_stream_id, :integer field :thumbnail_url, :string, default: "" + + timestamps(inserted_at: :created_at) end @doc false diff --git a/lib/philomena/servers/picarto_channel_updater.ex b/lib/philomena/servers/picarto_channel_updater.ex new file mode 100644 index 00000000..c1798675 --- /dev/null +++ b/lib/philomena/servers/picarto_channel_updater.ex @@ -0,0 +1,69 @@ +defmodule Philomena.Servers.PicartoChannelUpdater do + alias Philomena.Channels.Channel + alias Philomena.Repo + import Ecto.Query + + @api_online "https://api.picarto.tv/v1/online?adult=true&gaming=true" + + def child_spec([]) do + %{ + id: Philomena.Servers.PicartoChannelUpdater, + start: {Philomena.Servers.PicartoChannelUpdater, :start_link, [[]]} + } + end + + def start_link([]) do + {:ok, spawn_link(&run/0)} + end + + defp run do + now = DateTime.utc_now() |> DateTime.truncate(:second) + + @api_online + |> Philomena.Http.get!() + |> handle_response(now) + + :timer.sleep(:timer.seconds(60)) + run() + end + + defp handle_response(%HTTPoison.Response{body: body, status_code: 200}, now) do + resp = + body + |> Jason.decode!() + |> Map.new(&{&1["name"], &1}) + + live_channel_names = Map.keys(resp) + + Channel + |> where([c], c.type == "PicartoChannel" and c.short_name not in ^live_channel_names) + |> Repo.update_all([set: [is_live: false, updated_at: now]], log: false) + + Channel + |> where([c], c.type == "PicartoChannel" and c.short_name in ^live_channel_names) + |> Repo.all(log: false) + |> Enum.map(&fetch(&1, resp[&1.short_name], now)) + end + + defp handle_response(_response, _now), do: nil + + defp fetch(channel, api_response, now) do + Channel + |> where(id: ^channel.id) + |> Repo.update_all( + [ + set: [ + title: api_response["title"], + is_live: true, + nsfw: api_response["adult"], + viewers: api_response["viewers"], + thumbnail_url: api_response["thumbnails"]["web"], + last_fetched_at: now, + last_live_at: now, + description: nil + ] + ], + log: false + ) + end +end diff --git a/lib/philomena/servers/piczel_channel_updater.ex b/lib/philomena/servers/piczel_channel_updater.ex new file mode 100644 index 00000000..b685f334 --- /dev/null +++ b/lib/philomena/servers/piczel_channel_updater.ex @@ -0,0 +1,69 @@ +defmodule Philomena.Servers.PiczelChannelUpdater do + alias Philomena.Channels.Channel + alias Philomena.Repo + import Ecto.Query + + @api_online "https://api.piczel.tv/api/streams" + + def child_spec([]) do + %{ + id: Philomena.Servers.PiczelChannelUpdater, + start: {Philomena.Servers.PiczelChannelUpdater, :start_link, [[]]} + } + end + + def start_link([]) do + {:ok, spawn_link(&run/0)} + end + + defp run do + now = DateTime.utc_now() |> DateTime.truncate(:second) + + @api_online + |> Philomena.Http.get!() + |> handle_response(now) + + :timer.sleep(:timer.seconds(60)) + run() + end + + defp handle_response(%HTTPoison.Response{body: body, status_code: 200}, now) do + resp = + body + |> Jason.decode!() + |> Map.new(&{&1["slug"], &1}) + + live_channel_names = Map.keys(resp) + + Channel + |> where([c], c.type == "PiczelChannel" and c.short_name not in ^live_channel_names) + |> Repo.update_all([set: [is_live: false, updated_at: now]], log: false) + + Channel + |> where([c], c.type == "PiczelChannel" and c.short_name in ^live_channel_names) + |> Repo.all(log: false) + |> Enum.map(&fetch(&1, resp[&1.short_name], now)) + end + + defp handle_response(_response, _now), do: nil + + defp fetch(channel, api_response, now) do + Channel + |> where(id: ^channel.id) + |> Repo.update_all( + [ + set: [ + title: api_response["title"], + is_live: api_response["live"], + nsfw: api_response["adult"], + viewers: api_response["viewers"], + thumbnail_url: api_response["user"]["avatar"]["avatar"]["url"], + last_fetched_at: now, + last_live_at: now, + description: nil + ] + ], + log: false + ) + end +end