2020-02-18 08:57:00 +01:00
|
|
|
defmodule Mobilizon.Resources.Resource do
|
|
|
|
@moduledoc """
|
|
|
|
Represents a web resource
|
|
|
|
"""
|
|
|
|
use Ecto.Schema
|
|
|
|
import Ecto.Changeset
|
|
|
|
alias Ecto.Changeset
|
2020-08-14 11:32:23 +02:00
|
|
|
import Mobilizon.Storage.Ecto, only: [ensure_url: 2, maybe_add_published_at: 1]
|
2020-02-18 08:57:00 +01:00
|
|
|
|
|
|
|
import EctoEnum
|
|
|
|
defenum(TypeEnum, folder: 0, link: 1, picture: 20, pad: 30, calc: 40, visio: 50)
|
|
|
|
alias Mobilizon.Actors.Actor
|
2021-09-27 09:41:36 +02:00
|
|
|
alias Mobilizon.Resources.Resource.Metadata
|
2020-02-18 08:57:00 +01:00
|
|
|
|
|
|
|
@type t :: %__MODULE__{
|
2021-09-28 19:40:37 +02:00
|
|
|
id: String.t(),
|
2020-02-18 08:57:00 +01:00
|
|
|
title: String.t(),
|
|
|
|
summary: String.t(),
|
|
|
|
url: String.t(),
|
|
|
|
resource_url: String.t(),
|
|
|
|
type: atom(),
|
2021-09-27 09:41:36 +02:00
|
|
|
metadata: Metadata.t(),
|
2020-02-18 08:57:00 +01:00
|
|
|
children: list(__MODULE__),
|
|
|
|
parent: __MODULE__,
|
|
|
|
actor: Actor.t(),
|
|
|
|
creator: Actor.t(),
|
2020-08-14 11:32:23 +02:00
|
|
|
local: boolean,
|
|
|
|
published_at: DateTime.t()
|
2020-02-18 08:57:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@primary_key {:id, :binary_id, autogenerate: true}
|
|
|
|
schema "resource" do
|
|
|
|
field(:summary, :string)
|
|
|
|
field(:title, :string)
|
|
|
|
field(:url, :string)
|
|
|
|
field(:resource_url, :string)
|
|
|
|
field(:type, TypeEnum)
|
|
|
|
field(:path, :string)
|
|
|
|
field(:local, :boolean, default: true)
|
2020-08-14 11:32:23 +02:00
|
|
|
field(:published_at, :utc_datetime)
|
2020-02-18 08:57:00 +01:00
|
|
|
|
2021-09-27 09:41:36 +02:00
|
|
|
embeds_one(:metadata, Metadata, on_replace: :delete)
|
2020-02-18 08:57:00 +01:00
|
|
|
|
|
|
|
has_many(:children, __MODULE__, foreign_key: :parent_id)
|
|
|
|
belongs_to(:parent, __MODULE__, type: :binary_id)
|
|
|
|
belongs_to(:actor, Actor)
|
|
|
|
belongs_to(:creator, Actor)
|
|
|
|
|
|
|
|
timestamps()
|
|
|
|
end
|
|
|
|
|
2020-08-14 11:32:23 +02:00
|
|
|
@required_attrs [:title, :url, :actor_id, :creator_id, :type, :path, :published_at]
|
2020-02-18 08:57:00 +01:00
|
|
|
@optional_attrs [:summary, :parent_id, :resource_url, :local]
|
|
|
|
@attrs @required_attrs ++ @optional_attrs
|
|
|
|
|
|
|
|
@doc false
|
2021-09-24 16:46:42 +02:00
|
|
|
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
2020-02-18 08:57:00 +01:00
|
|
|
def changeset(resource, attrs) do
|
|
|
|
resource
|
|
|
|
|> cast(attrs, @attrs)
|
2021-09-27 09:41:36 +02:00
|
|
|
|> cast_embed(:metadata)
|
2020-02-18 08:57:00 +01:00
|
|
|
|> ensure_url(:resource)
|
2020-08-14 11:32:23 +02:00
|
|
|
|> maybe_add_published_at()
|
2020-02-18 08:57:00 +01:00
|
|
|
|> validate_resource_or_folder()
|
|
|
|
|> validate_required(@required_attrs)
|
|
|
|
|> unique_constraint(:url, name: :resource_url_index)
|
|
|
|
end
|
|
|
|
|
|
|
|
@spec validate_resource_or_folder(Changeset.t()) :: Changeset.t()
|
|
|
|
defp validate_resource_or_folder(%Changeset{} = changeset) do
|
|
|
|
with {status, type} when status in [:changes, :data] <- fetch_field(changeset, :type),
|
|
|
|
true <- type != :folder do
|
|
|
|
validate_required(changeset, [:resource_url])
|
|
|
|
else
|
|
|
|
_ -> changeset
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|