1.6 KiB · text History 4b6fe3b
defmodule OhMyExOhIrcd.Images.Image do
  @moduledoc """
  A hosted image: metadata for one uploaded file. The bytes live on the
  local filesystem at `<upload_dir>/<filename>`; `filename` is an
  unguessable random name that also forms the public `/i/<filename>` URL.

  Images are GC'd after the channel's retention window unless `pinned`.
  """

  use Ecto.Schema
  import Ecto.Changeset

  alias OhMyExOhIrcd.Accounts.User
  alias OhMyExOhIrcd.Channels.ChannelRecord

  schema "images" do
    field :who, :string
    field :filename, :string
    field :content_type, :string
    field :byte_size, :integer
    field :title, :string
    field :pinned, :boolean, default: false
    field :pinned_at, :utc_datetime

    belongs_to :channel, ChannelRecord
    belongs_to :user, User
    belongs_to :pinned_by, User, foreign_key: :pinned_by_user_id

    timestamps(type: :utc_datetime)
  end

  def changeset(record, attrs) do
    record
    |> cast(attrs, [:channel_id, :user_id, :who, :filename, :content_type, :byte_size, :title])
    |> validate_required([:channel_id, :who, :filename, :content_type, :byte_size])
    |> validate_length(:who, max: 64)
    |> validate_length(:title, max: 256)
    |> validate_number(:byte_size, greater_than: 0)
    |> unique_constraint(:filename)
    |> assoc_constraint(:channel)
  end

  def pin_changeset(record, %User{} = user) do
    change(record, pinned: true, pinned_by_user_id: user.id, pinned_at: DateTime.utc_now(:second))
  end

  def unpin_changeset(record) do
    change(record, pinned: false, pinned_by_user_id: nil, pinned_at: nil)
  end
end