mirror of
https://github.com/fly-apps/live_beats.git
synced 2024-11-21 23:50:59 +00:00
Merge pull request #5 from chrismccord/feature/validate_max_songs_per_account
Limit # of songs per account
This commit is contained in:
commit
19241308ae
5 changed files with 101 additions and 9 deletions
|
@ -4,6 +4,7 @@ defmodule LiveBeats.Accounts.User do
|
||||||
|
|
||||||
alias LiveBeats.Accounts.{User, Identity}
|
alias LiveBeats.Accounts.{User, Identity}
|
||||||
|
|
||||||
|
|
||||||
schema "users" do
|
schema "users" do
|
||||||
field :email, :string
|
field :email, :string
|
||||||
field :name, :string
|
field :name, :string
|
||||||
|
@ -14,6 +15,7 @@ defmodule LiveBeats.Accounts.User do
|
||||||
field :active_profile_user_id, :id
|
field :active_profile_user_id, :id
|
||||||
field :avatar_url, :string
|
field :avatar_url, :string
|
||||||
field :external_homepage_url, :string
|
field :external_homepage_url, :string
|
||||||
|
field :songs_number, :integer
|
||||||
|
|
||||||
has_many :identities, Identity
|
has_many :identities, Identity
|
||||||
|
|
||||||
|
@ -59,6 +61,7 @@ defmodule LiveBeats.Accounts.User do
|
||||||
|> validate_username()
|
|> validate_username()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
defp validate_email(changeset) do
|
defp validate_email(changeset) do
|
||||||
changeset
|
changeset
|
||||||
|> validate_required([:email])
|
|> validate_required([:email])
|
||||||
|
|
|
@ -11,6 +11,7 @@ defmodule LiveBeats.MediaLibrary do
|
||||||
|
|
||||||
@pubsub LiveBeats.PubSub
|
@pubsub LiveBeats.PubSub
|
||||||
@auto_next_threshold_seconds 5
|
@auto_next_threshold_seconds 5
|
||||||
|
@max_songs 30
|
||||||
|
|
||||||
defdelegate stopped?(song), to: Song
|
defdelegate stopped?(song), to: Song
|
||||||
defdelegate playing?(song), to: Song
|
defdelegate playing?(song), to: Song
|
||||||
|
@ -157,6 +158,27 @@ defmodule LiveBeats.MediaLibrary do
|
||||||
|
|
||||||
Ecto.Multi.insert(acc, {:song, ref}, chset)
|
Ecto.Multi.insert(acc, {:song, ref}, chset)
|
||||||
end)
|
end)
|
||||||
|
|> Ecto.Multi.run(:valid_songs_number, fn _repo, changes ->
|
||||||
|
user = Accounts.get_user!(user.id)
|
||||||
|
new_songs_count = changes |> Enum.filter(&match?({{:song, _ref}, _}, &1)) |> Enum.count()
|
||||||
|
validate_songs_limit(user.songs_number, new_songs_count)
|
||||||
|
end)
|
||||||
|
|> Ecto.Multi.update_all(
|
||||||
|
:update_songs_number,
|
||||||
|
fn %{valid_songs_number: new_songs_count} ->
|
||||||
|
from(u in Accounts.User,
|
||||||
|
where: u.id == ^user.id and u.songs_number == ^user.songs_number,
|
||||||
|
update: [inc: [songs_number: ^new_songs_count]]
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
|> Ecto.Multi.run(:is_songs_number_updated?, fn _repo, %{update_songs_number: result} ->
|
||||||
|
case result do
|
||||||
|
{1, _} -> {:ok, user}
|
||||||
|
_ -> {:error, :invalid}
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
case LiveBeats.Repo.transaction(multi) do
|
case LiveBeats.Repo.transaction(multi) do
|
||||||
{:ok, results} ->
|
{:ok, results} ->
|
||||||
|
@ -169,8 +191,15 @@ defmodule LiveBeats.MediaLibrary do
|
||||||
end)
|
end)
|
||||||
|> Enum.into(%{})}
|
|> Enum.into(%{})}
|
||||||
|
|
||||||
{:error, _failed_op, _failed_val, _changes} ->
|
{:error, failed_op, failed_val, _changes} ->
|
||||||
{:error, :invalid}
|
failed_op =
|
||||||
|
case failed_op do
|
||||||
|
{:song, _number} -> :invalid_song
|
||||||
|
:is_songs_number_updated? -> :invalid
|
||||||
|
failed_op -> failed_op
|
||||||
|
end
|
||||||
|
|
||||||
|
{:error, {failed_op, failed_val}}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -314,7 +343,20 @@ defmodule LiveBeats.MediaLibrary do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
Repo.delete(song)
|
Ecto.Multi.new()
|
||||||
|
|> Ecto.Multi.delete(:delete, song)
|
||||||
|
|> Ecto.Multi.update_all(
|
||||||
|
:update_songs_number,
|
||||||
|
fn _ ->
|
||||||
|
from(u in Accounts.User,
|
||||||
|
where: u.id == ^song.user_id,
|
||||||
|
update: [inc: [songs_number: -1]]
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
|> Repo.transaction()
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def change_song(song_or_changeset, attrs \\ %{})
|
def change_song(song_or_changeset, attrs \\ %{})
|
||||||
|
@ -338,4 +380,12 @@ defmodule LiveBeats.MediaLibrary do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp topic(user_id) when is_integer(user_id), do: "profile:#{user_id}"
|
defp topic(user_id) when is_integer(user_id), do: "profile:#{user_id}"
|
||||||
|
|
||||||
|
defp validate_songs_limit(user_songs, new_songs_count) do
|
||||||
|
if user_songs + new_songs_count <= @max_songs do
|
||||||
|
{:ok, new_songs_count}
|
||||||
|
else
|
||||||
|
{:error, :songs_limit_exceeded}
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -56,8 +56,12 @@ defmodule LiveBeatsWeb.SongLive.UploadFormComponent do
|
||||||
|> put_flash(:info, "#{map_size(songs)} song(s) uploaded")
|
|> put_flash(:info, "#{map_size(songs)} song(s) uploaded")
|
||||||
|> push_redirect(to: profile_path(current_user))}
|
|> push_redirect(to: profile_path(current_user))}
|
||||||
|
|
||||||
{:error, _reason} ->
|
{:error, error} ->
|
||||||
{:noreply, socket}
|
updated_socket =
|
||||||
|
socket
|
||||||
|
|> update(:error_messages, &Enum.take(&1 ++ [error], -10))
|
||||||
|
|
||||||
|
{:noreply, updated_socket}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -148,6 +152,15 @@ defmodule LiveBeatsWeb.SongLive.UploadFormComponent do
|
||||||
defp file_error(%{kind: :not_accepted} = assigns), do: ~H|not a valid MP3 file|
|
defp file_error(%{kind: :not_accepted} = assigns), do: ~H|not a valid MP3 file|
|
||||||
defp file_error(%{kind: :too_many_files} = assigns), do: ~H|too many files|
|
defp file_error(%{kind: :too_many_files} = assigns), do: ~H|too many files|
|
||||||
|
|
||||||
|
defp file_error(%{kind: :songs_limit_exceeded} = assigns),
|
||||||
|
do: ~H|You exceeded the limit of songs per account|
|
||||||
|
|
||||||
|
defp file_error(%{kind: :invalid} = assigns), do: ~H|Something went wrong|
|
||||||
|
|
||||||
|
defp file_error(%{kind: %Ecto.Changeset{} = changeset} = assigns) do
|
||||||
|
~H|<%= LiveBeatsWeb.ErrorHelpers.translate_changeset_errors(@kind) %>|
|
||||||
|
end
|
||||||
|
|
||||||
defp file_error(%{kind: {msg, opts}} = assigns) when is_binary(msg) and is_list(opts) do
|
defp file_error(%{kind: {msg, opts}} = assigns) when is_binary(msg) and is_list(opts) do
|
||||||
~H|<%= LiveBeatsWeb.ErrorHelpers.translate_error(@kind) %>|
|
~H|<%= LiveBeatsWeb.ErrorHelpers.translate_error(@kind) %>|
|
||||||
end
|
end
|
||||||
|
@ -190,7 +203,7 @@ defmodule LiveBeatsWeb.SongLive.UploadFormComponent do
|
||||||
socket
|
socket
|
||||||
|> cancel_upload(:mp3, entry.ref)
|
|> cancel_upload(:mp3, entry.ref)
|
||||||
|> drop_changeset(entry.ref)
|
|> drop_changeset(entry.ref)
|
||||||
|> update(:error_messages, &(Enum.take(&1 ++ [{entry.client_name, reason}], -10)))
|
|> update(:error_messages, &Enum.take(&1 ++ [{entry.client_name, reason}], -10))
|
||||||
end
|
end
|
||||||
|
|
||||||
defp get_entry!(socket, entry_ref) do
|
defp get_entry!(socket, entry_ref) do
|
||||||
|
|
|
@ -63,4 +63,10 @@ defmodule LiveBeatsWeb.ErrorHelpers do
|
||||||
Gettext.dgettext(LiveBeatsWeb.Gettext, "errors", msg, opts)
|
Gettext.dgettext(LiveBeatsWeb.Gettext, "errors", msg, opts)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def translate_changeset_errors(changeset) do
|
||||||
|
changeset.errors
|
||||||
|
|> Enum.map(fn {key, value} -> "#{key} #{translate_error(value)}" end)
|
||||||
|
|> Enum.join("\n")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
defmodule LiveBeats.Repo.Migrations.AddSongsNumberToUsers do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def up do
|
||||||
|
alter table(:users) do
|
||||||
|
add :songs_number, :integer, null: false, default: 0
|
||||||
|
end
|
||||||
|
|
||||||
|
execute("
|
||||||
|
UPDATE users set songs_number =
|
||||||
|
(SELECT count (*) from songs
|
||||||
|
where songs.user_id = users.id)")
|
||||||
|
end
|
||||||
|
|
||||||
|
def down do
|
||||||
|
alter table(:users) do
|
||||||
|
remove :songs_number
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue