Extend last.fm token diagnostics for maintenance page
This commit is contained in:
@@ -83,6 +83,12 @@ defmodule LastFm do
|
|||||||
|> API.scrobble(session_key, last_fm_config)
|
|> API.scrobble(session_key, last_fm_config)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec get_profile(String.t()) :: {:ok, String.t()} | {:error, term()}
|
||||||
|
def get_profile(session_key) do
|
||||||
|
last_fm_config = last_fm_config()
|
||||||
|
API.get_user_info(session_key, last_fm_config)
|
||||||
|
end
|
||||||
|
|
||||||
@spec auth_url() :: String.t()
|
@spec auth_url() :: String.t()
|
||||||
def auth_url do
|
def auth_url do
|
||||||
last_fm_config = last_fm_config()
|
last_fm_config = last_fm_config()
|
||||||
|
|||||||
@@ -121,6 +121,27 @@ defmodule LastFm.API do
|
|||||||
|> get_request()
|
|> get_request()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@spec get_user_info(String.t(), LastFm.Config.t()) :: {:ok, String.t()} | {:error, term()}
|
||||||
|
def get_user_info(session_key, config) do
|
||||||
|
params =
|
||||||
|
%{
|
||||||
|
api_key: config.api_key,
|
||||||
|
method: "user.getInfo",
|
||||||
|
sk: session_key,
|
||||||
|
format: "json"
|
||||||
|
}
|
||||||
|
|
||||||
|
signature = Signature.generate(params, config.shared_secret)
|
||||||
|
|
||||||
|
params = Map.put(params, "api_sig", signature)
|
||||||
|
|
||||||
|
config
|
||||||
|
|> new_request()
|
||||||
|
|> Req.merge(url: "/", params: params)
|
||||||
|
|> Req.Request.append_response_steps(parse_user_info: &parse_user_info/1)
|
||||||
|
|> get_request()
|
||||||
|
end
|
||||||
|
|
||||||
defp put_musicbrainz_id_or_name(params, {:musicbrainz_id, musicbrainz_id}) do
|
defp put_musicbrainz_id_or_name(params, {:musicbrainz_id, musicbrainz_id}) do
|
||||||
Keyword.put(params, :mbid, musicbrainz_id)
|
Keyword.put(params, :mbid, musicbrainz_id)
|
||||||
end
|
end
|
||||||
@@ -273,6 +294,11 @@ defmodule LastFm.API do
|
|||||||
|
|
||||||
defp parse_tag_count(_), do: 0
|
defp parse_tag_count(_), do: 0
|
||||||
|
|
||||||
|
defp parse_user_info({request, response}) do
|
||||||
|
username = get_in(response.body, ["user", "name"])
|
||||||
|
{request, Map.put(response, :body, username)}
|
||||||
|
end
|
||||||
|
|
||||||
defp sanitize_url(url, api_key) do
|
defp sanitize_url(url, api_key) do
|
||||||
String.replace(url, api_key, "<redacted_api_key>")
|
String.replace(url, api_key, "<redacted_api_key>")
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -214,18 +214,36 @@ defmodule MusicLibraryWeb.MaintenanceLive.Index do
|
|||||||
</h3>
|
</h3>
|
||||||
<p class="mt-2 max-w-4xl text-sm text-zinc-500 dark:text-zinc-400">
|
<p class="mt-2 max-w-4xl text-sm text-zinc-500 dark:text-zinc-400">
|
||||||
{gettext("Manage your Last.fm connection.")}
|
{gettext("Manage your Last.fm connection.")}
|
||||||
<span
|
<.async_result :let={status} assign={@lastfm_status}>
|
||||||
:if={@lastfm_connected}
|
<:loading>
|
||||||
class="ml-2 inline-flex items-center rounded-full bg-green-100 px-2 py-0.5 text-xs font-medium text-green-800 dark:bg-green-900 dark:text-green-200"
|
<span class="ml-2 inline-flex items-center rounded-full bg-zinc-100 px-2 py-0.5 text-xs font-medium text-zinc-600 dark:bg-zinc-700 dark:text-zinc-300">
|
||||||
>
|
{gettext("Checking...")}
|
||||||
{gettext("Connected")}
|
</span>
|
||||||
</span>
|
</:loading>
|
||||||
<span
|
<:failed :let={_failure}>
|
||||||
:if={!@lastfm_connected}
|
<span class="ml-2 inline-flex items-center rounded-full bg-red-100 px-2 py-0.5 text-xs font-medium text-red-800 dark:bg-red-900 dark:text-red-200">
|
||||||
class="ml-2 inline-flex items-center rounded-full bg-zinc-100 px-2 py-0.5 text-xs font-medium text-zinc-600 dark:bg-zinc-700 dark:text-zinc-300"
|
{gettext("Not connected")}
|
||||||
>
|
</span>
|
||||||
{gettext("Not connected")}
|
</:failed>
|
||||||
</span>
|
<span
|
||||||
|
:if={status == :not_connected}
|
||||||
|
class="ml-2 inline-flex items-center rounded-full bg-red-100 px-2 py-0.5 text-xs font-medium text-red-800 dark:bg-red-900 dark:text-red-200"
|
||||||
|
>
|
||||||
|
{gettext("Not connected")}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
:if={status == :outdated_token}
|
||||||
|
class="ml-2 inline-flex items-center rounded-full bg-yellow-100 px-2 py-0.5 text-xs font-medium text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200"
|
||||||
|
>
|
||||||
|
{gettext("Outdated token")}
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
:if={is_tuple(status) and elem(status, 0) == :connected}
|
||||||
|
class="ml-2 inline-flex items-center rounded-full bg-green-100 px-2 py-0.5 text-xs font-medium text-green-800 dark:bg-green-900 dark:text-green-200"
|
||||||
|
>
|
||||||
|
{gettext("Connected as %{username}", username: elem(status, 1))}
|
||||||
|
</span>
|
||||||
|
</.async_result>
|
||||||
</p>
|
</p>
|
||||||
<ul class="mt-4">
|
<ul class="mt-4">
|
||||||
<li class="space-y-4">
|
<li class="space-y-4">
|
||||||
@@ -262,7 +280,21 @@ defmodule MusicLibraryWeb.MaintenanceLive.Index do
|
|||||||
current_section: :maintenance
|
current_section: :maintenance
|
||||||
)
|
)
|
||||||
|> assign_job_counts()
|
|> assign_job_counts()
|
||||||
|> assign_lastfm_status()}
|
|> assign_async(:lastfm_status, fn ->
|
||||||
|
status =
|
||||||
|
case Secrets.get("last_fm_session_key") do
|
||||||
|
nil ->
|
||||||
|
:not_connected
|
||||||
|
|
||||||
|
%{value: value} ->
|
||||||
|
case LastFm.get_profile(value) do
|
||||||
|
{:ok, username} -> {:connected, username}
|
||||||
|
{:error, _} -> :outdated_token
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
{:ok, %{lastfm_status: status}}
|
||||||
|
end)}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
@@ -272,10 +304,6 @@ defmodule MusicLibraryWeb.MaintenanceLive.Index do
|
|||||||
{:noreply, assign_job_counts(socket)}
|
{:noreply, assign_job_counts(socket)}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp assign_lastfm_status(socket) do
|
|
||||||
assign(socket, :lastfm_connected, Secrets.get("last_fm_session_key") != nil)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp assign_job_counts(socket) do
|
defp assign_job_counts(socket) do
|
||||||
socket
|
socket
|
||||||
|> assign(
|
|> assign(
|
||||||
|
|||||||
@@ -2321,11 +2321,6 @@ msgstr ""
|
|||||||
msgid "Are you sure you want to re-connect to Last.fm? This will disconnect the current account."
|
msgid "Are you sure you want to re-connect to Last.fm? This will disconnect the current account."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/music_library_web/live/maintenance_live/index.ex
|
|
||||||
#, elixir-autogen, elixir-format
|
|
||||||
msgid "Connected"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/music_library_web/live/maintenance_live/index.ex
|
#: lib/music_library_web/live/maintenance_live/index.ex
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Manage your Last.fm connection."
|
msgid "Manage your Last.fm connection."
|
||||||
@@ -2360,3 +2355,18 @@ msgstr ""
|
|||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Search to scrobble"
|
msgid "Search to scrobble"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/live/maintenance_live/index.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Checking..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/live/maintenance_live/index.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Connected as %{username}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/live/maintenance_live/index.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Outdated token"
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -2321,11 +2321,6 @@ msgstr ""
|
|||||||
msgid "Are you sure you want to re-connect to Last.fm? This will disconnect the current account."
|
msgid "Are you sure you want to re-connect to Last.fm? This will disconnect the current account."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: lib/music_library_web/live/maintenance_live/index.ex
|
|
||||||
#, elixir-autogen, elixir-format, fuzzy
|
|
||||||
msgid "Connected"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: lib/music_library_web/live/maintenance_live/index.ex
|
#: lib/music_library_web/live/maintenance_live/index.ex
|
||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Manage your Last.fm connection."
|
msgid "Manage your Last.fm connection."
|
||||||
@@ -2360,3 +2355,18 @@ msgstr ""
|
|||||||
#, elixir-autogen, elixir-format
|
#, elixir-autogen, elixir-format
|
||||||
msgid "Search to scrobble"
|
msgid "Search to scrobble"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/live/maintenance_live/index.ex
|
||||||
|
#, elixir-autogen, elixir-format, fuzzy
|
||||||
|
msgid "Checking..."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/live/maintenance_live/index.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Connected as %{username}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: lib/music_library_web/live/maintenance_live/index.ex
|
||||||
|
#, elixir-autogen, elixir-format
|
||||||
|
msgid "Outdated token"
|
||||||
|
msgstr ""
|
||||||
|
|||||||
@@ -21,6 +21,32 @@ defmodule LastFmTest do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "get_profile/1" do
|
||||||
|
test "returns the username for a valid session key" do
|
||||||
|
Req.Test.stub(LastFm.API, fn conn ->
|
||||||
|
Req.Test.json(conn, %{
|
||||||
|
"user" => %{
|
||||||
|
"name" => "testuser",
|
||||||
|
"realname" => "Test User",
|
||||||
|
"playcount" => "12345",
|
||||||
|
"url" => "https://www.last.fm/user/testuser"
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert {:ok, "testuser"} == LastFm.get_profile("valid_session_key")
|
||||||
|
end
|
||||||
|
|
||||||
|
@tag :capture_log
|
||||||
|
test "returns an error for an invalid session key" do
|
||||||
|
Req.Test.stub(LastFm.API, fn conn ->
|
||||||
|
Req.Test.json(conn, %{"error" => 9, "message" => "Invalid session key"})
|
||||||
|
end)
|
||||||
|
|
||||||
|
assert {:error, :invalid_session_key} == LastFm.get_profile("invalid_session_key")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "scrobble/2" do
|
describe "scrobble/2" do
|
||||||
test "returns the scrobbled track" do
|
test "returns the scrobbled track" do
|
||||||
scrobbles = [
|
scrobbles = [
|
||||||
|
|||||||
Reference in New Issue
Block a user