Skip to content

Commit f4cd96e

Browse files
committed
Crudely implement playlist link cleaning
1 parent 757104e commit f4cd96e

File tree

2 files changed

+65
-7
lines changed

2 files changed

+65
-7
lines changed

lib/pling/playlists.ex

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,32 @@ defmodule Pling.Playlists do
7272
Playlist.changeset(playlist, attrs)
7373
end
7474

75+
@playlist_id_length 22
76+
77+
@doc """
78+
Extracts and validates a Spotify playlist ID from either a full Spotify URL or a raw ID.
79+
Returns nil if the input is invalid.
80+
"""
81+
def extract_playlist_id("https://open.spotify.com/playlist/" <> potential_id) do
82+
potential_id = String.slice(potential_id, 0, @playlist_id_length)
83+
validate_playlist_id(potential_id)
84+
end
85+
86+
def extract_playlist_id(potential_id) when is_binary(potential_id) do
87+
validate_playlist_id(potential_id)
88+
end
89+
90+
def extract_playlist_id(_), do: nil
91+
92+
# IDs are 22 chars
93+
defp validate_playlist_id(id) do
94+
if byte_size(id) == @playlist_id_length and id =~ ~r/^[a-zA-Z0-9]{#{@playlist_id_length}}$/ do
95+
id
96+
else
97+
nil
98+
end
99+
end
100+
75101
# Track Operations
76102

77103
@doc """

lib/pling_web/live/room_live.ex

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ defmodule PlingWeb.RoomLive do
55
alias Pling.Rooms.Presence
66
require Logger
77

8+
@playlist_id_length 22
9+
810
@impl true
911
def mount(
1012
%{"room_code" => room_code, "game_mode" => game_mode} = params,
@@ -116,11 +118,14 @@ defmodule PlingWeb.RoomLive do
116118

117119
@impl true
118120
def handle_event("set_playlist", %{"playlist_id" => playlist_id}, socket) do
121+
cleaned_playlist_id = extract_playlist_id(playlist_id)
122+
119123
{:noreply,
120124
socket
121125
|> assign(show_playlist_modal: false)
122126
|> push_patch(
123-
to: ~p"/#{socket.assigns.game_mode}/#{socket.assigns.room_code}?list=#{playlist_id}"
127+
to:
128+
~p"/#{socket.assigns.game_mode}/#{socket.assigns.room_code}?list=#{cleaned_playlist_id}"
124129
)}
125130
end
126131

@@ -426,12 +431,12 @@ defmodule PlingWeb.RoomLive do
426431
427432
<div class="mt-6 space-y-2">
428433
<label class="text-sm text-gray-600">{gettext("Or use your own playlist:")}</label>
429-
<form class="flex gap-2" action={~p"/#{@game_mode}/#{@room_code}"}>
434+
<form class="flex gap-2" phx-submit="set_playlist">
430435
<.input
431436
type="text"
432-
name="list"
437+
name="playlist_id"
433438
value=""
434-
placeholder={gettext("Spotify playlist ID")}
439+
placeholder={gettext("Spotify playlist link or ID")}
435440
autocomplete="off"
436441
/>
437442
<.button type="submit">
@@ -464,10 +469,12 @@ defmodule PlingWeb.RoomLive do
464469
end
465470

466471
defp handle_playlist_join(room_code, user_id, game_mode, playlist_id) do
467-
case Pling.Playlists.MusicLibrary.get_or_fetch_playlist(playlist_id) do
472+
cleaned_playlist_id = extract_playlist_id(playlist_id)
473+
474+
case Pling.Playlists.MusicLibrary.get_or_fetch_playlist(cleaned_playlist_id) do
468475
{:ok, :first_track_saved, playlist} ->
469476
{:ok, _state} = Rooms.join_room(room_code, user_id, self(), game_mode, playlist)
470-
{:ok, state} = Rooms.set_playlist(room_code, playlist_id)
477+
{:ok, state} = Rooms.set_playlist(room_code, cleaned_playlist_id)
471478
state
472479

473480
{:ok, _, playlist} ->
@@ -479,9 +486,34 @@ defmodule PlingWeb.RoomLive do
479486
end
480487
end
481488

489+
defp extract_playlist_id("https://open.spotify.com/playlist/" <> potential_id) do
490+
potential_id = String.slice(potential_id, 0, @playlist_id_length)
491+
validate_playlist_id(potential_id)
492+
end
493+
494+
defp extract_playlist_id(potential_id) when is_binary(potential_id) do
495+
validate_playlist_id(potential_id)
496+
end
497+
498+
defp extract_playlist_id(_), do: nil
499+
500+
# IDs are 22 chars
501+
defp validate_playlist_id(id) do
502+
if byte_size(id) == @playlist_id_length and id =~ ~r/^[a-zA-Z0-9]{#{@playlist_id_length}}$/ do
503+
id
504+
else
505+
nil
506+
end
507+
end
508+
482509
@impl true
483510
def handle_params(%{"list" => playlist_id}, _uri, socket) do
484-
Rooms.set_playlist(socket.assigns.room_code, playlist_id)
511+
cleaned_playlist_id = extract_playlist_id(playlist_id)
512+
513+
if cleaned_playlist_id do
514+
Rooms.set_playlist(socket.assigns.room_code, cleaned_playlist_id)
515+
end
516+
485517
{:noreply, socket}
486518
end
487519

0 commit comments

Comments
 (0)