Add types and specs for LastFm module

This commit is contained in:
Claudio Ortolina
2024-11-11 20:51:00 +00:00
parent 8e1916c22a
commit c7b9aadb70
6 changed files with 38 additions and 1 deletions
+5
View File
@@ -1,3 +1,8 @@
defmodule LastFm.Album do defmodule LastFm.Album do
defstruct [:musicbrainz_id, :title] defstruct [:musicbrainz_id, :title]
@type t :: %__MODULE__{
musicbrainz_id: String.t(),
title: String.t()
}
end end
+1 -1
View File
@@ -3,5 +3,5 @@ defmodule LastFm.APIBehaviour do
@type user :: String.t() @type user :: String.t()
@type api_key :: String.t() @type api_key :: String.t()
@callback get_recent_tracks(user, api_key) :: {:ok, [%Track{}]} | {:error, String.t()} @callback get_recent_tracks(user, api_key) :: {:ok, [Track.t()]} | {:error, String.t()}
end end
+5
View File
@@ -1,3 +1,8 @@
defmodule LastFm.Artist do defmodule LastFm.Artist do
defstruct [:musicbrainz_id, :name] defstruct [:musicbrainz_id, :name]
@type t :: %__MODULE__{
musicbrainz_id: String.t(),
name: String.t()
}
end end
+6
View File
@@ -6,11 +6,14 @@ defmodule LastFm.Feed do
is technically prone to collision, it's very unlikely for that to happen due to the is technically prone to collision, it's very unlikely for that to happen due to the
nature of the data. nature of the data.
""" """
@spec create_table!() :: :ok | no_return
def create_table! do def create_table! do
__MODULE__ = :ets.new(__MODULE__, [:ordered_set, :named_table, :public]) __MODULE__ = :ets.new(__MODULE__, [:ordered_set, :named_table, :public])
:ok :ok
end end
@spec update([LastFm.Track.t()]) :: :ok | no_return
def update(tracks) do def update(tracks) do
data = Enum.map(tracks, fn t -> {t.scrobbled_at_uts, t} end) data = Enum.map(tracks, fn t -> {t.scrobbled_at_uts, t} end)
@@ -20,6 +23,7 @@ defmodule LastFm.Feed do
Phoenix.PubSub.broadcast(LastFm.PubSub, "feed:update", %{tracks: tracks}) Phoenix.PubSub.broadcast(LastFm.PubSub, "feed:update", %{tracks: tracks})
end end
@spec all() :: [LastFm.Track.t()]
def all do def all do
m = [ m = [
{ {
@@ -29,9 +33,11 @@ defmodule LastFm.Feed do
} }
] ]
# reversing to get tracks in DESC order
:ets.select_reverse(__MODULE__, m) :ets.select_reverse(__MODULE__, m)
end end
@spec subscribe() :: :ok
def subscribe do def subscribe do
Phoenix.PubSub.subscribe(LastFm.PubSub, "feed:update") Phoenix.PubSub.subscribe(LastFm.PubSub, "feed:update")
end end
+11
View File
@@ -5,11 +5,20 @@ defmodule LastFm.Refresh do
alias LastFm.Feed alias LastFm.Feed
@type config :: %{
api: module(),
api_key: String.t(),
user: String.t(),
refresh_interval: pos_integer()
}
@spec start_link(config) :: GenServer.on_start()
def start_link(config) do def start_link(config) do
GenServer.start_link(__MODULE__, config, name: __MODULE__) GenServer.start_link(__MODULE__, config, name: __MODULE__)
end end
@impl true @impl true
@spec init(config) :: {:ok, config, {:continue, :refresh}} | :ignore
def init(config) do def init(config) do
config = Map.new(config) config = Map.new(config)
@@ -21,9 +30,11 @@ defmodule LastFm.Refresh do
end end
@impl true @impl true
@spec handle_continue(atom(), config) :: {:noreply, config}
def handle_continue(:refresh, config), do: refresh(config) def handle_continue(:refresh, config), do: refresh(config)
@impl true @impl true
@spec handle_info(atom(), config) :: {:noreply, config}
def handle_info(:refresh, config), do: refresh(config) def handle_info(:refresh, config), do: refresh(config)
defp refresh(config) do defp refresh(config) do
+10
View File
@@ -17,6 +17,16 @@ defmodule LastFm.Track do
:scrobbled_at_label :scrobbled_at_label
] ]
@type t :: %__MODULE__{
musicbrainz_id: String.t(),
title: String.t(),
artist: Artist.t(),
album: Album.t(),
cover_url: String.t(),
scrobbled_at_uts: integer(),
scrobbled_at_label: String.t()
}
def from_api_response(raw_tracks) do def from_api_response(raw_tracks) do
Enum.map(raw_tracks, fn t -> Enum.map(raw_tracks, fn t ->
album = %Album{ album = %Album{