A last.fm clone written in Elixir
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

109 lines
2.6 KiB

defmodule Dagon.Listens.Workers.CoverartAlbumWorker do
use GenServer
require Logger
alias Dagon.Repo
alias Dagon.Listens.Albums
alias Dagon.Listens.Albums.Album
@name "Coverartarchive Album Worker"
@fetch_interval 30 * 1_000
def start_link(args) do
Logger.info("Starting #{@name}..")
GenServer.start_link(__MODULE__, args, name: __MODULE__)
end
def fetch() do
GenServer.call(__MODULE__, :fetch, 30000)
end
def update_fetch_interval(interval_in_seconds) do
GenServer.cast(__MODULE__, {:update_fetch_interval, interval_in_seconds})
end
def init(_state) do
state = %{
rate_limit: %{
total: -1,
remaining: -1
},
fetch_interval: @fetch_interval,
updated_at: DateTime.utc_now()
}
schedule_fetch(state, 10_000)
{:ok, state}
end
def get_state() do
GenServer.call(__MODULE__, :get_state)
end
def handle_call(:get_state, _from, state) do
{:reply, state, state}
end
def handle_call(:fetch, _from, state) do
new_state = do_fetch(state)
{:reply, :ok, new_state}
end
def handle_info(:fetch, state) do
new_state = do_fetch(state)
{:noreply, new_state}
end
def handle_info({:ssl_closed, _}, state) do
Logger.error("Temporary TLS error")
{:noreply, state}
end
def handle_cast({:update_fetch_interval, interval_in_seconds}, state) do
Logger.info("Updating fetch_interval to #{interval_in_seconds}s for #{@name}")
new_state = Map.replace!(state, :fetch_interval, interval_in_seconds * 1000)
{:noreply, new_state}
end
def schedule_fetch(state) do
Logger.info("Scheduling #{@name}")
Process.send_after(self(), :fetch, state.fetch_interval)
end
def schedule_fetch(_state, wait_time) do
Logger.info("Scheduling #{@name}")
Process.send_after(self(), :fetch, wait_time)
end
def do_fetch(state) do
albums = Albums.list_albums_without_cover_and_mbid(log: false)
state =
Enum.reduce(albums, state, fn album, state ->
fetch_album_cover(state, album)
end)
schedule_fetch(state)
state
end
def fetch_album_cover(state, album) do
url = "https://coverartarchive.org/release/#{album.mbid}/front"
state =
case HTTPoison.get!(url, [{"User-Agent", Dagon.user_agent()}],
hackney: [pool: :coverartarchive_pool]
) do
%HTTPoison.Response{status_code: 307} ->
{:ok, url}
Dagon.Listens.Albums.update_album(album, %{image: url})
state
_ ->
state
end
state = Map.put(state, :updated_at, DateTime.utc_now())
state
end
end