Current section

Files

Jump to
snowhite lib modules rss server.ex
Raw

lib/modules/rss/server.ex

defmodule Snowhite.Modules.Rss.Server do
use GenServer
import Snowhite.Helpers.Timing
require Logger
alias Snowhite.Modules.Rss.Poller
alias Snowhite.Modules.Rss.UrlShortener
@auto_sync_timer ~d(15m)
def start_link(args) do
GenServer.start_link(__MODULE__, args, name: __MODULE__)
end
def update do
GenServer.cast(__MODULE__, :update)
end
def news do
GenServer.call(__MODULE__, :news)
end
@spec init(keyword) :: {:ok, %{feeds: any, news: [], options: [{any, any}]}}
def init(options) do
feeds = Keyword.fetch!(options, :feeds)
Logger.info("[#{__MODULE__}] Started with #{length(feeds)} feeds")
update()
update_later(options)
{:ok, %{options: options, feeds: feeds, news: []}}
end
def handle_cast(:update, state) do
send(self(), :notify)
{:noreply, update(state)}
end
def handle_call(:news, _, %{news: news} = state) do
{:reply, news, state}
end
def handle_info(:auto_sync, %{options: options} = state) do
state = update(state)
update_later(options)
send(self(), :notify)
{:noreply, state}
end
def handle_info(:notify, state) do
Phoenix.PubSub.broadcast!(Snowhite.PubSub, "snowhite:modules:rss", :updated)
{:noreply, state}
end
defp update_later(options) do
Process.send_after(self(), :auto_sync, Keyword.get(options, :refresh, @auto_sync_timer))
end
defp update(%{feeds: feeds} = state) do
news =
feeds
|> Poller.poll()
|> Enum.map(fn
{name, %{entries: entries}} ->
entries = put_short_url(state, entries)
{name, entries}
{name, _} ->
{name, []}
end)
%{state | news: news}
end
defp put_short_url(%{options: options}, entries) when is_list(entries) do
Enum.map(entries, fn entry ->
value = if Keyword.get(options, :qr_codes, true), do: put_short_url(entry), else: nil
Map.put(entry, :short_link, value)
end)
end
defp put_short_url(entry) do
entry
|> get_entry_url()
|> UrlShortener.shorten()
end
defp get_entry_url(entry) do
Map.get(entry, :"rss2:link", nil)
end
end