defmodule OhMyExOhIrcd.Scrobbles.ChannelConfig do
@moduledoc """
Per-channel ScrobbleServ configuration. One row per registered channel
that has been set up for scrobbling. `joined` tracks whether
ScrobbleServ is currently sitting in the channel (so it can re-join on
restart); `allowlist` holds downcased `who` display names.
"""
use Ecto.Schema
import Ecto.Changeset
alias OhMyExOhIrcd.Channels.ChannelRecord
@default_format "%who% is now playing %artist% - %track%"
schema "scrobble_channel_configs" do
field :enabled, :boolean, default: true
field :joined, :boolean, default: false
field :format, :string, default: @default_format
field :rate_limit_seconds, :integer, default: 30
field :restrict_to_allowlist, :boolean, default: false
field :allowlist, {:array, :string}, default: []
belongs_to :channel, ChannelRecord
timestamps(type: :utc_datetime)
end
@doc "Default announcement template."
def default_format, do: @default_format
def changeset(record, attrs) do
record
|> cast(attrs, [
:channel_id,
:enabled,
:joined,
:format,
:rate_limit_seconds,
:restrict_to_allowlist,
:allowlist
])
|> validate_required([:channel_id])
|> validate_length(:format, min: 1, max: 390)
|> validate_number(:rate_limit_seconds,
greater_than_or_equal_to: 0,
less_than_or_equal_to: 86_400
)
|> sanitize_format()
|> unique_constraint(:channel_id)
|> assoc_constraint(:channel)
end
# Strip CR/LF/NUL/control chars from the template so an op can't smuggle
# an IRC line break into announcements.
defp sanitize_format(changeset) do
update_change(changeset, :format, fn fmt ->
fmt
|> String.replace(~r/[\x00-\x1f]/, "")
|> String.trim()
end)
end
end
neiam
/oh-my-ex-oh-ircd
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
Log in to mark this repository.
1.8 KiB · text
History
4b6fe3b