Various refactoring and typespec improvements
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
@@ -15,7 +15,8 @@ defmodule Mobilizon.Activities.Activity do
|
||||
:message,
|
||||
:message_params,
|
||||
:object_type,
|
||||
:object_id
|
||||
:object_id,
|
||||
:object
|
||||
]
|
||||
@attrs @required_attrs ++ @optional_attrs
|
||||
|
||||
@@ -28,6 +29,7 @@ defmodule Mobilizon.Activities.Activity do
|
||||
message_params: map(),
|
||||
object_type: ObjectType.t(),
|
||||
object_id: String.t(),
|
||||
object: map(),
|
||||
author: Actor.t(),
|
||||
group: Actor.t()
|
||||
}
|
||||
@@ -41,12 +43,14 @@ defmodule Mobilizon.Activities.Activity do
|
||||
field(:message_params, :map, default: %{})
|
||||
field(:object_type, ObjectType)
|
||||
field(:object_id, :string)
|
||||
field(:object, :map, virtual: true)
|
||||
field(:inserted_at, :utc_datetime)
|
||||
belongs_to(:author, Actor)
|
||||
belongs_to(:group, Actor)
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(activity, attrs) do
|
||||
activity
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -11,7 +11,7 @@ defmodule Mobilizon.Actors.Actor do
|
||||
alias Mobilizon.Actors.{ActorOpenness, ActorType, ActorVisibility, Follower, Member}
|
||||
alias Mobilizon.Addresses.Address
|
||||
alias Mobilizon.Discussions.Comment
|
||||
alias Mobilizon.Events.{Event, FeedToken}
|
||||
alias Mobilizon.Events.{Event, FeedToken, Participant}
|
||||
alias Mobilizon.Medias.File
|
||||
alias Mobilizon.Reports.{Note, Report}
|
||||
alias Mobilizon.Users.User
|
||||
@@ -33,8 +33,8 @@ defmodule Mobilizon.Actors.Actor do
|
||||
posts_url: String.t(),
|
||||
events_url: String.t(),
|
||||
type: ActorType.t(),
|
||||
name: String.t(),
|
||||
domain: String.t(),
|
||||
name: String.t() | nil,
|
||||
domain: String.t() | nil,
|
||||
summary: String.t(),
|
||||
preferred_username: String.t(),
|
||||
keys: String.t(),
|
||||
@@ -42,12 +42,13 @@ defmodule Mobilizon.Actors.Actor do
|
||||
openness: ActorOpenness.t(),
|
||||
visibility: ActorVisibility.t(),
|
||||
suspended: boolean,
|
||||
avatar: File.t(),
|
||||
banner: File.t(),
|
||||
avatar: File.t() | nil,
|
||||
banner: File.t() | nil,
|
||||
user: User.t(),
|
||||
followers: [Follower.t()],
|
||||
followings: [Follower.t()],
|
||||
organized_events: [Event.t()],
|
||||
participations: [Participant.t()],
|
||||
comments: [Comment.t()],
|
||||
feed_tokens: [FeedToken.t()],
|
||||
created_reports: [Report.t()],
|
||||
@@ -184,6 +185,7 @@ defmodule Mobilizon.Actors.Actor do
|
||||
has_many(:created_reports, Report, foreign_key: :reporter_id)
|
||||
has_many(:subject_reports, Report, foreign_key: :reported_id)
|
||||
has_many(:report_notes, Note, foreign_key: :moderator_id)
|
||||
has_many(:participations, Participant, foreign_key: :actor_id)
|
||||
has_many(:mentions, Mention)
|
||||
has_many(:shares, Share, foreign_key: :actor_id)
|
||||
has_many(:owner_shares, Share, foreign_key: :owner_actor_id)
|
||||
@@ -243,7 +245,7 @@ defmodule Mobilizon.Actors.Actor do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(%__MODULE__{} = actor, attrs) do
|
||||
actor
|
||||
|> cast(attrs, @attrs)
|
||||
@@ -278,7 +280,7 @@ defmodule Mobilizon.Actors.Actor do
|
||||
@doc """
|
||||
Changeset for person registration.
|
||||
"""
|
||||
@spec registration_changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec registration_changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def registration_changeset(%__MODULE__{} = actor, attrs) do
|
||||
actor
|
||||
|> cast(attrs, @registration_attrs)
|
||||
@@ -293,19 +295,14 @@ defmodule Mobilizon.Actors.Actor do
|
||||
"""
|
||||
@spec remote_actor_creation_changeset(map) :: Ecto.Changeset.t()
|
||||
def remote_actor_creation_changeset(attrs) do
|
||||
changeset =
|
||||
%__MODULE__{}
|
||||
|> cast(attrs, @remote_actor_creation_attrs)
|
||||
|> validate_required(@remote_actor_creation_required_attrs)
|
||||
|> common_changeset(attrs)
|
||||
|> unique_username_validator()
|
||||
|> validate_required(:domain)
|
||||
|> validate_length(:summary, max: 5000)
|
||||
|> validate_length(:preferred_username, max: 100)
|
||||
|
||||
Logger.debug("Remote actor creation: #{inspect(changeset)}")
|
||||
|
||||
changeset
|
||||
%__MODULE__{}
|
||||
|> cast(attrs, @remote_actor_creation_attrs)
|
||||
|> validate_required(@remote_actor_creation_required_attrs)
|
||||
|> common_changeset(attrs)
|
||||
|> unique_username_validator()
|
||||
|> validate_required(:domain)
|
||||
|> validate_length(:summary, max: 5000)
|
||||
|> validate_length(:preferred_username, max: 100)
|
||||
end
|
||||
|
||||
@spec common_changeset(Ecto.Changeset.t(), map()) :: Ecto.Changeset.t()
|
||||
@@ -323,7 +320,7 @@ defmodule Mobilizon.Actors.Actor do
|
||||
@doc """
|
||||
Changeset for group creation
|
||||
"""
|
||||
@spec group_creation_changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec group_creation_changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def group_creation_changeset(actor, params) do
|
||||
actor
|
||||
|> cast(params, @group_creation_attrs)
|
||||
@@ -416,12 +413,8 @@ defmodule Mobilizon.Actors.Actor do
|
||||
@spec build_relay_creation_attrs :: Ecto.Changeset.t()
|
||||
def build_relay_creation_attrs do
|
||||
data = %{
|
||||
name: Config.get([:instance, :name], "Mobilizon"),
|
||||
summary:
|
||||
Config.get(
|
||||
[:instance, :description],
|
||||
"An internal service actor for this Mobilizon instance"
|
||||
),
|
||||
name: Config.instance_name(),
|
||||
summary: Config.instance_description(),
|
||||
keys: Crypto.generate_rsa_2048_private_key(),
|
||||
preferred_username: "relay",
|
||||
domain: nil,
|
||||
|
||||
@@ -75,13 +75,20 @@ defmodule Mobilizon.Actors do
|
||||
@doc """
|
||||
Gets an actor with preloaded relations.
|
||||
"""
|
||||
@spec get_actor_with_preload(integer | String.t()) :: Actor.t() | nil
|
||||
@spec get_actor_with_preload(integer | String.t(), boolean) :: Actor.t() | nil
|
||||
def get_actor_with_preload(id, include_suspended \\ false) do
|
||||
id
|
||||
|> actor_with_preload_query(include_suspended)
|
||||
|> Repo.one()
|
||||
end
|
||||
|
||||
@spec get_actor_with_preload!(integer | String.t(), boolean) :: Actor.t()
|
||||
def get_actor_with_preload!(id, include_suspended \\ false) do
|
||||
id
|
||||
|> actor_with_preload_query(include_suspended)
|
||||
|> Repo.one!()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets a local actor with preloaded relations.
|
||||
"""
|
||||
@@ -148,9 +155,7 @@ defmodule Mobilizon.Actors do
|
||||
"""
|
||||
@spec get_actor_by_name(String.t(), ActorType.t() | nil) :: Actor.t() | nil
|
||||
def get_actor_by_name(name, type \\ nil) do
|
||||
query = from(a in Actor)
|
||||
|
||||
query
|
||||
Actor
|
||||
|> filter_by_type(type)
|
||||
|> filter_by_name(name |> String.trim() |> String.trim_leading("@") |> String.split("@"))
|
||||
|> Repo.one()
|
||||
@@ -161,9 +166,7 @@ defmodule Mobilizon.Actors do
|
||||
"""
|
||||
@spec get_local_actor_by_name(String.t()) :: Actor.t() | nil
|
||||
def get_local_actor_by_name(name) do
|
||||
query = from(a in Actor)
|
||||
|
||||
query
|
||||
Actor
|
||||
|> filter_by_name([name])
|
||||
|> Repo.one()
|
||||
end
|
||||
@@ -210,7 +213,8 @@ defmodule Mobilizon.Actors do
|
||||
@doc """
|
||||
Creates a new person actor.
|
||||
"""
|
||||
@spec new_person(map) :: {:ok, Actor.t()} | {:error, Ecto.Changeset.t()}
|
||||
@spec new_person(map, default_actor :: boolean()) ::
|
||||
{:ok, Actor.t()} | {:error, Ecto.Changeset.t()}
|
||||
def new_person(args, default_actor \\ false) do
|
||||
args = Map.put(args, :keys, Crypto.generate_rsa_2048_private_key())
|
||||
|
||||
@@ -323,8 +327,8 @@ defmodule Mobilizon.Actors do
|
||||
String.t(),
|
||||
boolean,
|
||||
boolean,
|
||||
integer,
|
||||
integer
|
||||
integer | nil,
|
||||
integer | nil
|
||||
) :: Page.t()
|
||||
def list_actors(
|
||||
type \\ :Person,
|
||||
@@ -367,7 +371,23 @@ defmodule Mobilizon.Actors do
|
||||
|> Page.build_page(page, limit)
|
||||
end
|
||||
|
||||
@spec filter_actors(Ecto.Query.t(), String.t(), String.t(), String.t(), boolean(), boolean()) ::
|
||||
@spec list_suspended_actors_to_purge(Keyword.t()) :: list(Actors.t())
|
||||
def list_suspended_actors_to_purge(options) do
|
||||
suspension_days = Keyword.get(options, :suspension, 30)
|
||||
|
||||
Actor
|
||||
|> filter_suspended_days(suspension_days)
|
||||
|> Repo.all()
|
||||
end
|
||||
|
||||
@spec filter_actors(
|
||||
Ecto.Queryable.t(),
|
||||
String.t(),
|
||||
String.t(),
|
||||
String.t(),
|
||||
boolean(),
|
||||
boolean()
|
||||
) ::
|
||||
Ecto.Query.t()
|
||||
defp filter_actors(
|
||||
query,
|
||||
@@ -403,14 +423,27 @@ defmodule Mobilizon.Actors do
|
||||
defp filter_remote(query, true), do: filter_local(query)
|
||||
defp filter_remote(query, false), do: filter_external(query)
|
||||
|
||||
@spec filter_suspended(Ecto.Query.t(), boolean()) :: Ecto.Query.t()
|
||||
@spec filter_suspended(Ecto.Queryable.t(), boolean()) :: Ecto.Query.t()
|
||||
defp filter_suspended(query, true), do: where(query, [a], a.suspended)
|
||||
defp filter_suspended(query, false), do: where(query, [a], not a.suspended)
|
||||
|
||||
@spec filter_out_anonymous_actor_id(Ecto.Query.t(), integer() | String.t()) :: Ecto.Query.t()
|
||||
@spec filter_out_anonymous_actor_id(Ecto.Queryable.t(), integer() | String.t()) ::
|
||||
Ecto.Query.t()
|
||||
defp filter_out_anonymous_actor_id(query, anonymous_actor_id),
|
||||
do: where(query, [a], a.id != ^anonymous_actor_id)
|
||||
|
||||
@spec filter_suspended_days(Ecto.Queryable.t(), integer()) :: Ecto.Query.t()
|
||||
defp filter_suspended_days(query, suspended_days) do
|
||||
expiration_date = DateTime.add(DateTime.utc_now(), suspended_days * 24 * -3600)
|
||||
|
||||
where(
|
||||
query,
|
||||
[a],
|
||||
a.suspended and
|
||||
a.updated_at > ^expiration_date
|
||||
)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Returns the list of local actors by their username.
|
||||
"""
|
||||
@@ -486,14 +519,14 @@ defmodule Mobilizon.Actors do
|
||||
end
|
||||
end
|
||||
|
||||
@spec get_local_group_by_url(String.t()) :: Actor.t()
|
||||
@spec get_local_group_by_url(String.t()) :: Actor.t() | nil
|
||||
def get_local_group_by_url(group_url) do
|
||||
group_query()
|
||||
|> where([q], q.url == ^group_url and is_nil(q.domain))
|
||||
|> Repo.one()
|
||||
end
|
||||
|
||||
@spec get_group_by_members_url(String.t()) :: Actor.t()
|
||||
@spec get_group_by_members_url(String.t()) :: Actor.t() | nil
|
||||
def get_group_by_members_url(members_url) do
|
||||
group_query()
|
||||
|> where([q], q.members_url == ^members_url)
|
||||
@@ -531,7 +564,7 @@ defmodule Mobilizon.Actors do
|
||||
{:ok, %{insert_group: %Actor{} = group, add_admin_member: %Member{} = _admin_member}} ->
|
||||
{:ok, group}
|
||||
|
||||
{:error, %Ecto.Changeset{} = err} ->
|
||||
{:error, _err, %Ecto.Changeset{} = err, _} ->
|
||||
{:error, err}
|
||||
end
|
||||
else
|
||||
@@ -606,7 +639,7 @@ defmodule Mobilizon.Actors do
|
||||
@doc """
|
||||
Gets a single member.
|
||||
"""
|
||||
@spec get_member(integer | String.t()) :: {:ok, Member.t()} | nil
|
||||
@spec get_member(integer | String.t()) :: Member.t() | nil
|
||||
def get_member(id) do
|
||||
Member
|
||||
|> Repo.get(id)
|
||||
@@ -623,7 +656,7 @@ defmodule Mobilizon.Actors do
|
||||
@doc """
|
||||
Gets a single member of an actor (for example a group).
|
||||
"""
|
||||
@spec get_member(integer | String.t(), integer | String.t()) ::
|
||||
@spec get_member(actor_id :: integer | String.t(), parent_id :: integer | String.t()) ::
|
||||
{:ok, Member.t()} | {:error, :member_not_found}
|
||||
def get_member(actor_id, parent_id) do
|
||||
case Repo.get_by(Member, actor_id: actor_id, parent_id: parent_id) do
|
||||
@@ -1190,31 +1223,35 @@ defmodule Mobilizon.Actors do
|
||||
@doc """
|
||||
Makes an actor following another actor.
|
||||
"""
|
||||
@spec follow(Actor.t(), Actor.t(), String.t() | nil, boolean | nil) ::
|
||||
{:ok, Follower.t()} | {:error, atom, String.t()}
|
||||
@spec follow(
|
||||
followed :: Actor.t(),
|
||||
follower :: Actor.t(),
|
||||
url :: String.t() | nil,
|
||||
approved :: boolean | nil
|
||||
) ::
|
||||
{:ok, Follower.t()}
|
||||
| {:error, :already_following | :followed_suspended | Ecto.Changeset.t()}
|
||||
def follow(%Actor{} = followed, %Actor{} = follower, url \\ nil, approved \\ true) do
|
||||
with {:suspended, false} <- {:suspended, followed.suspended},
|
||||
# Check if followed has blocked follower
|
||||
{:already_following, nil} <- {:already_following, is_following(follower, followed)} do
|
||||
Logger.info(
|
||||
"Making #{Actor.preferred_username_and_domain(follower)} follow #{Actor.preferred_username_and_domain(followed)} " <>
|
||||
"(approved: #{approved})"
|
||||
)
|
||||
|
||||
create_follower(%{
|
||||
"actor_id" => follower.id,
|
||||
"target_actor_id" => followed.id,
|
||||
"approved" => approved,
|
||||
"url" => url
|
||||
})
|
||||
if followed.suspended do
|
||||
{:error, :followed_suspended}
|
||||
else
|
||||
{:already_following, %Follower{}} ->
|
||||
{:error, :already_following,
|
||||
"Could not follow actor: you are already following #{Actor.preferred_username_and_domain(followed)}"}
|
||||
case is_following(follower, followed) do
|
||||
%Follower{} ->
|
||||
{:error, :already_following}
|
||||
|
||||
{:suspended, _} ->
|
||||
{:error, :suspended,
|
||||
"Could not follow actor: #{Actor.preferred_username_and_domain(followed)} has been suspended"}
|
||||
nil ->
|
||||
Logger.info(
|
||||
"Making #{Actor.preferred_username_and_domain(follower)} follow #{Actor.preferred_username_and_domain(followed)} " <>
|
||||
"(approved: #{approved})"
|
||||
)
|
||||
|
||||
create_follower(%{
|
||||
"actor_id" => follower.id,
|
||||
"target_actor_id" => followed.id,
|
||||
"approved" => approved,
|
||||
"url" => url
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1331,7 +1368,7 @@ defmodule Mobilizon.Actors do
|
||||
)
|
||||
end
|
||||
|
||||
@spec actor_by_username_or_name_query(Ecto.Query.t(), String.t()) :: Ecto.Query.t()
|
||||
@spec actor_by_username_or_name_query(Ecto.Queryable.t(), String.t()) :: Ecto.Query.t()
|
||||
defp actor_by_username_or_name_query(query, ""), do: query
|
||||
|
||||
defp actor_by_username_or_name_query(query, username) do
|
||||
@@ -1358,7 +1395,7 @@ defmodule Mobilizon.Actors do
|
||||
)
|
||||
end
|
||||
|
||||
@spec actors_for_location(Ecto.Query.t(), String.t(), integer()) :: Ecto.Query.t()
|
||||
@spec actors_for_location(Ecto.Queryable.t(), String.t(), integer()) :: Ecto.Query.t()
|
||||
defp actors_for_location(query, location, radius)
|
||||
when is_valid_string(location) and not is_nil(radius) do
|
||||
with {lon, lat} <- Geohax.decode(location),
|
||||
@@ -1474,7 +1511,7 @@ defmodule Mobilizon.Actors do
|
||||
|> select([m, _a], m)
|
||||
end
|
||||
|
||||
@spec filter_member_role(Ecto.Query.t(), list(atom()) | atom()) :: Ecto.Query.t()
|
||||
@spec filter_member_role(Ecto.Queryable.t(), list(atom()) | atom()) :: Ecto.Query.t()
|
||||
defp filter_member_role(query, []), do: query
|
||||
|
||||
defp filter_member_role(query, roles) when is_list(roles) do
|
||||
@@ -1597,24 +1634,24 @@ defmodule Mobilizon.Actors do
|
||||
|> order_by(desc: :updated_at)
|
||||
end
|
||||
|
||||
@spec filter_local(Ecto.Query.t()) :: Ecto.Query.t()
|
||||
@spec filter_local(Ecto.Queryable.t()) :: Ecto.Query.t()
|
||||
defp filter_local(query) do
|
||||
from(a in query, where: is_nil(a.domain))
|
||||
end
|
||||
|
||||
@spec filter_external(Ecto.Query.t()) :: Ecto.Query.t()
|
||||
@spec filter_external(Ecto.Queryable.t()) :: Ecto.Query.t()
|
||||
defp filter_external(query) do
|
||||
from(a in query, where: not is_nil(a.domain))
|
||||
end
|
||||
|
||||
@spec filter_follower_actors_external(Ecto.Query.t()) :: Ecto.Query.t()
|
||||
@spec filter_follower_actors_external(Ecto.Queryable.t()) :: Ecto.Query.t()
|
||||
defp filter_follower_actors_external(query) do
|
||||
query
|
||||
|> where([_f, a], not is_nil(a.domain))
|
||||
|> preload([f, a], [:target_actor, :actor])
|
||||
end
|
||||
|
||||
@spec filter_by_type(Ecto.Query.t(), ActorType.t()) :: Ecto.Query.t()
|
||||
@spec filter_by_type(Ecto.Queryable.t(), ActorType.t() | nil) :: Ecto.Queryable.t()
|
||||
defp filter_by_type(query, type)
|
||||
when type in [:Person, :Group, :Application, :Service, :Organisation] do
|
||||
from(a in query, where: a.type == ^type)
|
||||
@@ -1622,12 +1659,12 @@ defmodule Mobilizon.Actors do
|
||||
|
||||
defp filter_by_type(query, _type), do: query
|
||||
|
||||
@spec filter_by_types(Ecto.Query.t(), [ActorType.t()]) :: Ecto.Query.t()
|
||||
@spec filter_by_types(Ecto.Queryable.t(), [ActorType.t()]) :: Ecto.Query.t()
|
||||
defp filter_by_types(query, types) do
|
||||
from(a in query, where: a.type in ^types)
|
||||
end
|
||||
|
||||
@spec filter_by_minimum_visibility(Ecto.Query.t(), atom()) :: Ecto.Query.t()
|
||||
@spec filter_by_minimum_visibility(Ecto.Queryable.t(), atom()) :: Ecto.Query.t()
|
||||
defp filter_by_minimum_visibility(query, :private), do: query
|
||||
|
||||
defp filter_by_minimum_visibility(query, :restricted) do
|
||||
@@ -1642,7 +1679,7 @@ defmodule Mobilizon.Actors do
|
||||
from(a in query, where: a.visibility == ^:public)
|
||||
end
|
||||
|
||||
@spec filter_by_name(query :: Ecto.Query.t(), [String.t()]) :: Ecto.Query.t()
|
||||
@spec filter_by_name(query :: Ecto.Queryable.t(), [String.t()]) :: Ecto.Query.t()
|
||||
defp filter_by_name(query, [name]) do
|
||||
where(query, [a], a.preferred_username == ^name and is_nil(a.domain))
|
||||
end
|
||||
@@ -1655,7 +1692,7 @@ defmodule Mobilizon.Actors do
|
||||
end
|
||||
end
|
||||
|
||||
@spec filter_followed_by_approved_status(Ecto.Query.t(), boolean() | nil) :: Ecto.Query.t()
|
||||
@spec filter_followed_by_approved_status(Ecto.Queryable.t(), boolean() | nil) :: Ecto.Query.t()
|
||||
defp filter_followed_by_approved_status(query, nil), do: query
|
||||
|
||||
defp filter_followed_by_approved_status(query, approved) do
|
||||
|
||||
@@ -32,7 +32,7 @@ defmodule Mobilizon.Actors.Bot do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(%__MODULE__{} = bot, attrs) do
|
||||
bot
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -38,7 +38,7 @@ defmodule Mobilizon.Actors.Follower do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(follower :: t, attrs :: map) :: Ecto.Changeset.t()
|
||||
@spec changeset(follower :: t | Ecto.Schema.t(), attrs :: map) :: Ecto.Changeset.t()
|
||||
def changeset(follower, attrs) do
|
||||
follower
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -59,7 +59,7 @@ defmodule Mobilizon.Actors.Member do
|
||||
def is_administrator(%__MODULE__{}), do: false
|
||||
|
||||
@doc false
|
||||
@spec changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(%__MODULE__{} = member, attrs) do
|
||||
member
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -57,7 +57,7 @@ defmodule Mobilizon.Addresses.Address do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(%__MODULE__{} = address, attrs) do
|
||||
address
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -118,7 +118,7 @@ defmodule Mobilizon.Addresses do
|
||||
)
|
||||
end
|
||||
|
||||
@spec order_by_coords(Ecto.Query.t(), map | nil) :: Ecto.Query.t()
|
||||
@spec order_by_coords(Ecto.Queryable.t(), map | nil) :: Ecto.Query.t()
|
||||
defp order_by_coords(query, nil), do: query
|
||||
|
||||
defp order_by_coords(query, coords) do
|
||||
@@ -128,7 +128,7 @@ defmodule Mobilizon.Addresses do
|
||||
)
|
||||
end
|
||||
|
||||
@spec filter_by_contry(Ecto.Query.t(), String.t() | nil) :: Ecto.Query.t()
|
||||
@spec filter_by_contry(Ecto.Queryable.t(), String.t() | nil) :: Ecto.Query.t()
|
||||
defp filter_by_contry(query, nil), do: query
|
||||
|
||||
defp filter_by_contry(query, country) do
|
||||
|
||||
@@ -35,7 +35,7 @@ defmodule Mobilizon.Admin.ActionLog do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(%__MODULE__{} = action_log, attrs) do
|
||||
action_log
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -45,7 +45,8 @@ defmodule Mobilizon.Admin do
|
||||
@doc """
|
||||
Log an admin action
|
||||
"""
|
||||
@spec log_action(Actor.t(), String.t(), String.t()) :: {:ok, ActionLog.t()}
|
||||
@spec log_action(Actor.t(), String.t(), struct()) ::
|
||||
{:ok, ActionLog.t()} | {:error, Ecto.Changeset.t() | :user_not_moderator}
|
||||
def log_action(%Actor{user_id: user_id, id: actor_id}, action, target) do
|
||||
with %User{role: role} <- Users.get_user!(user_id),
|
||||
{:role, true} <- {:role, role in [:administrator, :moderator]},
|
||||
@@ -58,6 +59,9 @@ defmodule Mobilizon.Admin do
|
||||
"changes" => stringify_struct(target)
|
||||
}) do
|
||||
{:ok, create_action_log}
|
||||
else
|
||||
{:role, false} ->
|
||||
{:error, :user_not_moderator}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -109,12 +113,7 @@ defmodule Mobilizon.Admin do
|
||||
end
|
||||
end
|
||||
|
||||
def set_admin_setting_value(group, name, value) do
|
||||
Setting
|
||||
|> Setting.changeset(%{group: group, name: name, value: value})
|
||||
|> Repo.insert(on_conflict: :replace_all, conflict_target: [:group, :name])
|
||||
end
|
||||
|
||||
@spec save_settings(String.t(), map()) :: {:ok, any} | {:error, any}
|
||||
def save_settings(group, args) do
|
||||
Multi.new()
|
||||
|> do_save_setting(group, args)
|
||||
@@ -125,6 +124,7 @@ defmodule Mobilizon.Admin do
|
||||
Setting |> where([s], s.group == ^group) |> Repo.delete_all()
|
||||
end
|
||||
|
||||
@spec do_save_setting(Ecto.Multi.t(), String.t(), map()) :: Ecto.Multi.t()
|
||||
defp do_save_setting(transaction, _group, args) when args == %{}, do: transaction
|
||||
|
||||
defp do_save_setting(transaction, group, args) do
|
||||
@@ -147,6 +147,7 @@ defmodule Mobilizon.Admin do
|
||||
do_save_setting(transaction, group, rest)
|
||||
end
|
||||
|
||||
@spec convert_to_string(any()) :: String.t()
|
||||
defp convert_to_string(val) do
|
||||
case val do
|
||||
val when is_list(val) -> Jason.encode!(val)
|
||||
|
||||
@@ -9,6 +9,12 @@ defmodule Mobilizon.Admin.Setting do
|
||||
@optional_attrs [:value]
|
||||
@attrs @required_attrs ++ @optional_attrs
|
||||
|
||||
@type t :: %{
|
||||
group: String.t(),
|
||||
name: String.t(),
|
||||
value: String.t()
|
||||
}
|
||||
|
||||
schema "admin_settings" do
|
||||
field(:group, :string)
|
||||
field(:name, :string)
|
||||
@@ -18,6 +24,7 @@ defmodule Mobilizon.Admin.Setting do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(setting, attrs) do
|
||||
setting
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -7,7 +7,24 @@ defmodule Mobilizon.Config do
|
||||
alias Mobilizon.Service.GitStatus
|
||||
require Logger
|
||||
|
||||
@spec instance_config :: keyword
|
||||
@type mobilizon_config :: [
|
||||
name: String.t(),
|
||||
description: String.t(),
|
||||
hostname: String.t(),
|
||||
registrations_open: boolean(),
|
||||
languages: list(String.t()),
|
||||
default_language: String.t(),
|
||||
registration_email_allowlist: list(String.t()),
|
||||
registration_email_denylist: list(String.t()),
|
||||
demo: boolean(),
|
||||
repository: String.t(),
|
||||
email_from: String.t(),
|
||||
email_reply_to: String.t(),
|
||||
federating: boolean(),
|
||||
remove_orphan_uploads: boolean()
|
||||
]
|
||||
|
||||
@spec instance_config :: mobilizon_config
|
||||
def instance_config, do: Application.get_env(:mobilizon, :instance)
|
||||
|
||||
@spec instance_name :: String.t()
|
||||
@@ -139,10 +156,10 @@ defmodule Mobilizon.Config do
|
||||
def instance_user_agent,
|
||||
do: "#{instance_hostname()} - Mobilizon #{instance_version()}"
|
||||
|
||||
@spec instance_federating :: String.t()
|
||||
@spec instance_federating :: boolean()
|
||||
def instance_federating, do: instance_config()[:federating]
|
||||
|
||||
@spec instance_geocoding_provider :: atom()
|
||||
@spec instance_geocoding_provider :: module()
|
||||
def instance_geocoding_provider,
|
||||
do: get_in(Application.get_env(:mobilizon, Mobilizon.Service.Geospatial), [:service])
|
||||
|
||||
@@ -150,63 +167,90 @@ defmodule Mobilizon.Config do
|
||||
def instance_geocoding_autocomplete,
|
||||
do: instance_geocoding_provider() !== Mobilizon.Service.Geospatial.Nominatim
|
||||
|
||||
@spec maps_config :: [
|
||||
tiles: [endpoint: String.t(), attribution: String.t()],
|
||||
rounting: [type: atom]
|
||||
]
|
||||
defp maps_config, do: Application.get_env(:mobilizon, :maps)
|
||||
|
||||
@spec instance_maps_tiles_endpoint :: String.t()
|
||||
def instance_maps_tiles_endpoint, do: Application.get_env(:mobilizon, :maps)[:tiles][:endpoint]
|
||||
def instance_maps_tiles_endpoint, do: maps_config()[:tiles][:endpoint]
|
||||
|
||||
@spec instance_maps_tiles_attribution :: String.t()
|
||||
def instance_maps_tiles_attribution,
|
||||
do: Application.get_env(:mobilizon, :maps)[:tiles][:attribution]
|
||||
do: maps_config()[:tiles][:attribution]
|
||||
|
||||
@spec instance_maps_routing_type :: atom()
|
||||
def instance_maps_routing_type,
|
||||
do: Application.get_env(:mobilizon, :maps)[:routing][:type]
|
||||
do: maps_config()[:routing][:type]
|
||||
|
||||
@typep anonymous_config_type :: [
|
||||
participation: [
|
||||
allowed: boolean,
|
||||
validation: [
|
||||
email: [enabled: boolean(), confirmation_required: boolean()],
|
||||
captcha: [enabled: boolean()]
|
||||
]
|
||||
],
|
||||
event_creation: [
|
||||
allowed: boolean,
|
||||
validation: [
|
||||
email: [enabled: boolean(), confirmation_required: boolean()],
|
||||
captcha: [enabled: boolean()]
|
||||
]
|
||||
],
|
||||
reports: [
|
||||
allowed: boolean()
|
||||
]
|
||||
]
|
||||
|
||||
@spec anonymous_config :: anonymous_config_type
|
||||
defp anonymous_config, do: Application.get_env(:mobilizon, :anonymous)
|
||||
|
||||
@spec anonymous_participation? :: boolean
|
||||
def anonymous_participation?,
|
||||
do: Application.get_env(:mobilizon, :anonymous)[:participation][:allowed]
|
||||
do: anonymous_config()[:participation][:allowed]
|
||||
|
||||
@spec anonymous_participation_email_required? :: boolean
|
||||
def anonymous_participation_email_required?,
|
||||
do: Application.get_env(:mobilizon, :anonymous)[:participation][:validation][:email][:enabled]
|
||||
do: anonymous_config()[:participation][:validation][:email][:enabled]
|
||||
|
||||
@spec anonymous_participation_email_confirmation_required? :: boolean
|
||||
def anonymous_participation_email_confirmation_required?,
|
||||
do:
|
||||
Application.get_env(:mobilizon, :anonymous)[:participation][:validation][:email][
|
||||
anonymous_config()[:participation][:validation][:email][
|
||||
:confirmation_required
|
||||
]
|
||||
|
||||
@spec anonymous_participation_email_captcha_required? :: boolean
|
||||
def anonymous_participation_email_captcha_required?,
|
||||
do:
|
||||
Application.get_env(:mobilizon, :anonymous)[:participation][:validation][:captcha][:enabled]
|
||||
do: anonymous_config()[:participation][:validation][:captcha][:enabled]
|
||||
|
||||
@spec anonymous_event_creation? :: boolean
|
||||
def anonymous_event_creation?,
|
||||
do: Application.get_env(:mobilizon, :anonymous)[:event_creation][:allowed]
|
||||
do: anonymous_config()[:event_creation][:allowed]
|
||||
|
||||
@spec anonymous_event_creation_email_required? :: boolean
|
||||
def anonymous_event_creation_email_required?,
|
||||
do:
|
||||
Application.get_env(:mobilizon, :anonymous)[:event_creation][:validation][:email][:enabled]
|
||||
do: anonymous_config()[:event_creation][:validation][:email][:enabled]
|
||||
|
||||
@spec anonymous_event_creation_email_confirmation_required? :: boolean
|
||||
def anonymous_event_creation_email_confirmation_required?,
|
||||
do:
|
||||
Application.get_env(:mobilizon, :anonymous)[:event_creation][:validation][:email][
|
||||
anonymous_config()[:event_creation][:validation][:email][
|
||||
:confirmation_required
|
||||
]
|
||||
|
||||
@spec anonymous_event_creation_email_captcha_required? :: boolean
|
||||
def anonymous_event_creation_email_captcha_required?,
|
||||
do:
|
||||
Application.get_env(:mobilizon, :anonymous)[:event_creation][:validation][:captcha][
|
||||
anonymous_config()[:event_creation][:validation][:captcha][
|
||||
:enabled
|
||||
]
|
||||
|
||||
@spec anonymous_reporting? :: boolean
|
||||
def anonymous_reporting?,
|
||||
do: Application.get_env(:mobilizon, :anonymous)[:reports][:allowed]
|
||||
do: anonymous_config()[:reports][:allowed]
|
||||
|
||||
@spec oauth_consumer_strategies() :: list({atom(), String.t()})
|
||||
def oauth_consumer_strategies do
|
||||
@@ -265,7 +309,7 @@ defmodule Mobilizon.Config do
|
||||
@spec admin_settings :: map
|
||||
def admin_settings, do: get_cached_value(:admin_config)
|
||||
|
||||
@spec get(key :: module | atom) :: any
|
||||
@spec get(keys :: module | atom | [module | atom]) :: any
|
||||
def get(key), do: get(key, nil)
|
||||
|
||||
@spec get(keys :: [module | atom], default :: any) :: any
|
||||
@@ -281,7 +325,7 @@ defmodule Mobilizon.Config do
|
||||
@spec get(key :: module | atom, default :: any) :: any
|
||||
def get(key, default), do: Application.get_env(:mobilizon, key, default)
|
||||
|
||||
@spec get!(key :: module | atom) :: any
|
||||
@spec get!(key :: module | atom) :: any | no_return
|
||||
def get!(key) do
|
||||
value = get(key, nil)
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ defmodule Mobilizon.Discussions.Comment do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(%__MODULE__{} = comment, attrs) do
|
||||
comment
|
||||
|> common_changeset(attrs)
|
||||
|
||||
@@ -59,7 +59,7 @@ defmodule Mobilizon.Discussions.Discussion do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(%__MODULE__{} = discussion, attrs) do
|
||||
discussion
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -71,7 +71,7 @@ defmodule Mobilizon.Discussions do
|
||||
We only get first comment of thread, and count replies.
|
||||
Read: https://hexdocs.pm/absinthe/ecto.html#dataloader
|
||||
"""
|
||||
@spec query(atom(), map()) :: Ecto.Queryable.t()
|
||||
@spec query(atom(), map()) :: Ecto.Query.t()
|
||||
def query(Comment, %{top_level: true}) do
|
||||
Comment
|
||||
|> join(:left, [c], r in Comment, on: r.origin_comment_id == c.id)
|
||||
@@ -158,7 +158,7 @@ defmodule Mobilizon.Discussions do
|
||||
Gets a comment by its URL, with all associations loaded.
|
||||
Raises `Ecto.NoResultsError` if the comment does not exist.
|
||||
"""
|
||||
@spec get_comment_from_url_with_preload(String.t()) :: Comment.t()
|
||||
@spec get_comment_from_url_with_preload!(String.t()) :: Comment.t()
|
||||
def get_comment_from_url_with_preload!(url) do
|
||||
Comment
|
||||
|> Repo.get_by!(url: url)
|
||||
@@ -168,7 +168,7 @@ defmodule Mobilizon.Discussions do
|
||||
@doc """
|
||||
Gets a comment by its UUID, with all associations loaded.
|
||||
"""
|
||||
@spec get_comment_from_uuid_with_preload(String.t()) :: Comment.t()
|
||||
@spec get_comment_from_uuid_with_preload(String.t()) :: Comment.t() | nil
|
||||
def get_comment_from_uuid_with_preload(uuid) do
|
||||
Comment
|
||||
|> Repo.get_by(uuid: uuid)
|
||||
@@ -355,7 +355,7 @@ defmodule Mobilizon.Discussions do
|
||||
@doc """
|
||||
Get a discussion by it's slug
|
||||
"""
|
||||
@spec get_discussion_by_slug(String.t()) :: Discussion.t()
|
||||
@spec get_discussion_by_slug(String.t()) :: Discussion.t() | nil
|
||||
def get_discussion_by_slug(discussion_slug) do
|
||||
Discussion
|
||||
|> Repo.get_by(slug: discussion_slug)
|
||||
@@ -494,11 +494,11 @@ defmodule Mobilizon.Discussions do
|
||||
)
|
||||
end
|
||||
|
||||
@spec filter_comments_under_events(Ecto.Query.t()) :: Ecto.Query.t()
|
||||
@spec filter_comments_under_events(Ecto.Queryable.t()) :: Ecto.Query.t()
|
||||
defp filter_comments_under_events(query) do
|
||||
where(query, [c], is_nil(c.discussion_id) and not is_nil(c.event_id))
|
||||
end
|
||||
|
||||
@spec preload_for_comment(Ecto.Query.t()) :: Ecto.Query.t()
|
||||
@spec preload_for_comment(Ecto.Queryable.t()) :: Ecto.Query.t()
|
||||
defp preload_for_comment(query), do: preload(query, ^@comment_preloads)
|
||||
end
|
||||
|
||||
@@ -35,6 +35,7 @@ defmodule Mobilizon.Events.Event do
|
||||
alias Mobilizon.Web.Router.Helpers, as: Routes
|
||||
|
||||
@type t :: %__MODULE__{
|
||||
id: String.t(),
|
||||
url: String.t(),
|
||||
local: boolean,
|
||||
begins_on: DateTime.t(),
|
||||
@@ -53,7 +54,7 @@ defmodule Mobilizon.Events.Event do
|
||||
category: String.t(),
|
||||
options: EventOptions.t(),
|
||||
organizer_actor: Actor.t(),
|
||||
attributed_to: Actor.t(),
|
||||
attributed_to: Actor.t() | nil,
|
||||
physical_address: Address.t(),
|
||||
picture: Media.t(),
|
||||
media: [Media.t()],
|
||||
@@ -130,7 +131,7 @@ defmodule Mobilizon.Events.Event do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t, map) :: Changeset.t()
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Changeset.t()
|
||||
def changeset(%__MODULE__{} = event, attrs) do
|
||||
attrs = Map.update(attrs, :uuid, Ecto.UUID.generate(), & &1)
|
||||
attrs = Map.update(attrs, :url, Routes.page_url(Endpoint, :event, attrs.uuid), & &1)
|
||||
@@ -289,4 +290,12 @@ defmodule Mobilizon.Events.Event do
|
||||
|
||||
defp put_creator_if_published(%Changeset{} = changeset, _),
|
||||
do: cast_embed(changeset, :participant_stats)
|
||||
|
||||
@doc """
|
||||
Whether we can show the event. Returns false if the organizer actor or group is suspended
|
||||
"""
|
||||
@spec show?(t) :: boolean()
|
||||
def show?(%__MODULE__{attributed_to: %Actor{suspended: true}}), do: false
|
||||
def show?(%__MODULE__{organizer_actor: %Actor{suspended: true}}), do: false
|
||||
def show?(%__MODULE__{}), do: true
|
||||
end
|
||||
|
||||
@@ -36,7 +36,7 @@ defmodule Mobilizon.Events.EventMetadata do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(%__MODULE__{} = event_metadata, attrs) do
|
||||
event_metadata
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -64,7 +64,7 @@ defmodule Mobilizon.Events.EventOptions do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(%__MODULE__{} = event_options, attrs) do
|
||||
event_options
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -40,7 +40,7 @@ defmodule Mobilizon.Events.EventParticipantStats do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(%__MODULE__{} = event_options, attrs) do
|
||||
event_options
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -263,7 +263,10 @@ defmodule Mobilizon.Events do
|
||||
@doc """
|
||||
Creates an event.
|
||||
"""
|
||||
@spec create_event(map) :: {:ok, Event.t()} | {:error, Changeset.t()}
|
||||
@spec create_event(map) ::
|
||||
{:ok, Event.t()}
|
||||
| {:error, Changeset.t()}
|
||||
| {:error, :update | :write, Changeset.t(), map()}
|
||||
def create_event(attrs \\ %{}) do
|
||||
with {:ok, %{insert: %Event{} = event}} <- do_create_event(attrs),
|
||||
%Event{} = event <- Repo.preload(event, @event_preloads) do
|
||||
@@ -278,7 +281,10 @@ defmodule Mobilizon.Events do
|
||||
end
|
||||
|
||||
# We start by inserting the event and then insert a first participant if the event is not a draft
|
||||
@spec do_create_event(map) :: {:ok, Event.t()} | {:error, Changeset.t()}
|
||||
@spec do_create_event(map) ::
|
||||
{:ok, Event.t()}
|
||||
| {:error, Changeset.t()}
|
||||
| {:error, :update | :write, Changeset.t(), map()}
|
||||
defp do_create_event(attrs) do
|
||||
Multi.new()
|
||||
|> Multi.insert(:insert, Event.changeset(%Event{}, attrs))
|
||||
@@ -307,7 +313,10 @@ defmodule Mobilizon.Events do
|
||||
|
||||
We start by updating the event and then insert a first participant if the event is not a draft anymore
|
||||
"""
|
||||
@spec update_event(Event.t(), map) :: {:ok, Event.t()} | {:error, Changeset.t()}
|
||||
@spec update_event(Event.t(), map) ::
|
||||
{:ok, Event.t()}
|
||||
| {:error, Changeset.t()}
|
||||
| {:error, :update | :write, Changeset.t(), map()}
|
||||
def update_event(%Event{draft: old_draft} = old_event, attrs) do
|
||||
with %Event{} = old_event <- Repo.preload(old_event, @event_preloads),
|
||||
%Changeset{changes: changes} = changeset <-
|
||||
@@ -394,7 +403,7 @@ defmodule Mobilizon.Events do
|
||||
|> Repo.stream()
|
||||
end
|
||||
|
||||
@spec list_public_local_events(integer | nil, integer | nil) :: Page.t()
|
||||
@spec list_public_local_events(integer | nil, integer | nil) :: Page.t(Event.t())
|
||||
def list_public_local_events(page \\ nil, limit \\ nil) do
|
||||
Event
|
||||
|> filter_public_visibility()
|
||||
@@ -452,7 +461,7 @@ defmodule Mobilizon.Events do
|
||||
DateTime.t() | nil,
|
||||
integer | nil,
|
||||
integer | nil
|
||||
) :: Page.t()
|
||||
) :: Page.t(Event.t())
|
||||
def list_organized_events_for_group(
|
||||
%Actor{id: group_id},
|
||||
visibility \\ :public,
|
||||
@@ -729,7 +738,7 @@ defmodule Mobilizon.Events do
|
||||
nil
|
||||
|
||||
"""
|
||||
@spec get_participant(integer) :: Participant.t()
|
||||
@spec get_participant(integer) :: Participant.t() | nil
|
||||
def get_participant(participant_id) do
|
||||
Participant
|
||||
|> where([p], p.id == ^participant_id)
|
||||
@@ -1040,21 +1049,18 @@ defmodule Mobilizon.Events do
|
||||
Deletes a participant.
|
||||
"""
|
||||
@spec delete_participant(Participant.t()) ::
|
||||
{:ok, Participant.t()} | {:error, Changeset.t()}
|
||||
{:ok, %{participant: Participant.t()}}
|
||||
| {:error, :participant | :update_event_participation_stats, Changeset.t(), map()}
|
||||
def delete_participant(%Participant{role: old_role} = participant) do
|
||||
with {:ok, %{participant: %Participant{} = participant}} <-
|
||||
Multi.new()
|
||||
|> Multi.delete(:participant, participant)
|
||||
|> Multi.run(:update_event_participation_stats, fn _repo,
|
||||
%{
|
||||
participant:
|
||||
%Participant{} = participant
|
||||
} ->
|
||||
update_participant_stats(participant, old_role, nil)
|
||||
end)
|
||||
|> Repo.transaction() do
|
||||
{:ok, participant}
|
||||
end
|
||||
Multi.new()
|
||||
|> Multi.delete(:participant, participant)
|
||||
|> Multi.run(:update_event_participation_stats, fn _repo,
|
||||
%{
|
||||
participant: %Participant{} = participant
|
||||
} ->
|
||||
update_participant_stats(participant, old_role, nil)
|
||||
end)
|
||||
|> Repo.transaction()
|
||||
end
|
||||
|
||||
defp update_participant_stats(
|
||||
@@ -1330,7 +1336,7 @@ defmodule Mobilizon.Events do
|
||||
)
|
||||
end
|
||||
|
||||
@spec user_events_query(Ecto.Query.t(), number()) :: Ecto.Query.t()
|
||||
@spec user_events_query(Ecto.Queryable.t(), number()) :: Ecto.Query.t()
|
||||
defp user_events_query(query, user_id) do
|
||||
from(
|
||||
e in query,
|
||||
@@ -1373,7 +1379,7 @@ defmodule Mobilizon.Events do
|
||||
)
|
||||
end
|
||||
|
||||
@spec events_for_begins_on(Ecto.Query.t(), map()) :: Ecto.Query.t()
|
||||
@spec events_for_begins_on(Ecto.Queryable.t(), map()) :: Ecto.Query.t()
|
||||
defp events_for_begins_on(query, args) do
|
||||
begins_on = Map.get(args, :begins_on, DateTime.utc_now())
|
||||
|
||||
@@ -1381,7 +1387,7 @@ defmodule Mobilizon.Events do
|
||||
|> where([q], q.begins_on >= ^begins_on)
|
||||
end
|
||||
|
||||
@spec events_for_ends_on(Ecto.Query.t(), map()) :: Ecto.Query.t()
|
||||
@spec events_for_ends_on(Ecto.Queryable.t(), map()) :: Ecto.Query.t()
|
||||
defp events_for_ends_on(query, args) do
|
||||
ends_on = Map.get(args, :ends_on)
|
||||
|
||||
@@ -1396,7 +1402,7 @@ defmodule Mobilizon.Events do
|
||||
)
|
||||
end
|
||||
|
||||
@spec events_for_tags(Ecto.Query.t(), map()) :: Ecto.Query.t()
|
||||
@spec events_for_tags(Ecto.Queryable.t(), map()) :: Ecto.Query.t()
|
||||
defp events_for_tags(query, %{tags: tags}) when is_valid_string(tags) do
|
||||
query
|
||||
|> join(:inner, [q], te in "events_tags", on: q.id == te.event_id)
|
||||
@@ -1406,7 +1412,7 @@ defmodule Mobilizon.Events do
|
||||
|
||||
defp events_for_tags(query, _args), do: query
|
||||
|
||||
@spec events_for_location(Ecto.Query.t(), map()) :: Ecto.Query.t()
|
||||
@spec events_for_location(Ecto.Queryable.t(), map()) :: Ecto.Query.t()
|
||||
defp events_for_location(query, %{radius: radius}) when is_nil(radius),
|
||||
do: query
|
||||
|
||||
@@ -1472,7 +1478,7 @@ defmodule Mobilizon.Events do
|
||||
from(t in Tag, where: t.title == ^title, limit: 1)
|
||||
end
|
||||
|
||||
@spec tag_filter(Ecto.Query.t(), String.t() | nil) :: Ecto.Query.t()
|
||||
@spec tag_filter(Ecto.Queryable.t(), String.t() | nil) :: Ecto.Query.t()
|
||||
defp tag_filter(query, nil), do: query
|
||||
defp tag_filter(query, ""), do: query
|
||||
|
||||
@@ -1511,7 +1517,7 @@ defmodule Mobilizon.Events do
|
||||
)
|
||||
end
|
||||
|
||||
@spec tag_relation_union_subquery(Ecto.Query.t(), integer) :: Ecto.Query.t()
|
||||
@spec tag_relation_union_subquery(Ecto.Queryable.t(), integer) :: Ecto.Query.t()
|
||||
defp tag_relation_union_subquery(subquery, tag_id) do
|
||||
from(
|
||||
tr in TagRelation,
|
||||
@@ -1521,7 +1527,7 @@ defmodule Mobilizon.Events do
|
||||
)
|
||||
end
|
||||
|
||||
@spec tag_neighbors_query(Ecto.Query.t(), integer, integer) :: Ecto.Query.t()
|
||||
@spec tag_neighbors_query(Ecto.Queryable.t(), integer, integer) :: Ecto.Query.t()
|
||||
defp tag_neighbors_query(subquery, relation_minimum, limit) do
|
||||
from(
|
||||
t in Tag,
|
||||
@@ -1673,38 +1679,34 @@ defmodule Mobilizon.Events do
|
||||
from(tk in FeedToken, where: tk.actor_id == ^actor_id, preload: [:actor, :user])
|
||||
end
|
||||
|
||||
@spec filter_public_visibility(Ecto.Query.t()) :: Ecto.Query.t()
|
||||
@spec filter_public_visibility(Ecto.Queryable.t()) :: Ecto.Query.t()
|
||||
defp filter_public_visibility(query) do
|
||||
from(e in query, where: e.visibility == ^:public)
|
||||
end
|
||||
|
||||
@spec filter_unlisted_and_public_visibility(Ecto.Query.t()) :: Ecto.Query.t()
|
||||
@spec filter_unlisted_and_public_visibility(Ecto.Queryable.t()) :: Ecto.Query.t()
|
||||
defp filter_unlisted_and_public_visibility(query) do
|
||||
from(q in query, where: q.visibility in ^@public_visibility)
|
||||
end
|
||||
|
||||
@spec filter_not_event_uuid(Ecto.Query.t(), String.t() | nil) :: Ecto.Query.t()
|
||||
@spec filter_not_event_uuid(Ecto.Queryable.t(), String.t() | nil) :: Ecto.Query.t()
|
||||
defp filter_not_event_uuid(query, nil), do: query
|
||||
|
||||
defp filter_not_event_uuid(query, not_event_uuid) do
|
||||
from(e in query, where: e.uuid != ^not_event_uuid)
|
||||
end
|
||||
|
||||
@spec filter_draft(Ecto.Query.t(), boolean) :: Ecto.Query.t()
|
||||
@spec filter_draft(Ecto.Queryable.t(), boolean) :: Ecto.Query.t()
|
||||
defp filter_draft(query, is_draft \\ false) do
|
||||
from(e in query, where: e.draft == ^is_draft)
|
||||
end
|
||||
|
||||
@spec filter_cancelled_events(Ecto.Query.t(), boolean()) :: Ecto.Query.t()
|
||||
defp filter_cancelled_events(query, hide_cancelled \\ true)
|
||||
|
||||
defp filter_cancelled_events(query, false), do: query
|
||||
|
||||
defp filter_cancelled_events(query, true) do
|
||||
@spec filter_cancelled_events(Ecto.Queryable.t()) :: Ecto.Query.t()
|
||||
defp filter_cancelled_events(query) do
|
||||
from(e in query, where: e.status != ^:cancelled)
|
||||
end
|
||||
|
||||
@spec filter_future_events(Ecto.Query.t(), boolean) :: Ecto.Query.t()
|
||||
@spec filter_future_events(Ecto.Queryable.t(), boolean) :: Ecto.Query.t()
|
||||
defp filter_future_events(query, true) do
|
||||
from(q in query,
|
||||
where: q.begins_on > ^DateTime.utc_now()
|
||||
@@ -1713,12 +1715,12 @@ defmodule Mobilizon.Events do
|
||||
|
||||
defp filter_future_events(query, false), do: query
|
||||
|
||||
@spec filter_local(Ecto.Query.t()) :: Ecto.Query.t()
|
||||
@spec filter_local(Ecto.Queryable.t()) :: Ecto.Query.t()
|
||||
defp filter_local(query) do
|
||||
where(query, [q], q.local == true)
|
||||
end
|
||||
|
||||
@spec filter_local_or_from_followed_instances_events(Ecto.Query.t()) ::
|
||||
@spec filter_local_or_from_followed_instances_events(Ecto.Queryable.t()) ::
|
||||
Ecto.Query.t()
|
||||
defp filter_local_or_from_followed_instances_events(query) do
|
||||
follower_actor_id = Mobilizon.Config.relay_actor_id()
|
||||
@@ -1732,22 +1734,22 @@ defmodule Mobilizon.Events do
|
||||
)
|
||||
end
|
||||
|
||||
@spec filter_approved_role(Ecto.Query.t()) :: Ecto.Query.t()
|
||||
@spec filter_approved_role(Ecto.Queryable.t()) :: Ecto.Query.t()
|
||||
defp filter_approved_role(query) do
|
||||
filter_role(query, [:not_approved, :rejected])
|
||||
end
|
||||
|
||||
@spec filter_participant_role(Ecto.Query.t()) :: Ecto.Query.t()
|
||||
@spec filter_participant_role(Ecto.Queryable.t()) :: Ecto.Query.t()
|
||||
defp filter_participant_role(query) do
|
||||
filter_role(query, :participant)
|
||||
end
|
||||
|
||||
@spec filter_rejected_role(Ecto.Query.t()) :: Ecto.Query.t()
|
||||
@spec filter_rejected_role(Ecto.Queryable.t()) :: Ecto.Query.t()
|
||||
defp filter_rejected_role(query) do
|
||||
filter_role(query, :rejected)
|
||||
end
|
||||
|
||||
@spec filter_role(Ecto.Query.t(), list(atom())) :: Ecto.Query.t()
|
||||
@spec filter_role(Ecto.Queryable.t(), list(atom()) | atom()) :: Ecto.Query.t()
|
||||
def filter_role(query, []), do: query
|
||||
|
||||
def filter_role(query, roles) when is_list(roles) do
|
||||
@@ -1829,6 +1831,6 @@ defmodule Mobilizon.Events do
|
||||
defp participation_order_begins_on_desc(query),
|
||||
do: order_by(query, [_p, e, _a], desc: e.begins_on)
|
||||
|
||||
@spec preload_for_event(Ecto.Query.t()) :: Ecto.Query.t()
|
||||
@spec preload_for_event(Ecto.Queryable.t()) :: Ecto.Query.t()
|
||||
defp preload_for_event(query), do: preload(query, ^@event_preloads)
|
||||
end
|
||||
|
||||
@@ -12,7 +12,7 @@ defmodule Mobilizon.Events.FeedToken do
|
||||
|
||||
@type t :: %__MODULE__{
|
||||
token: Ecto.UUID.t(),
|
||||
actor: Actor.t(),
|
||||
actor: Actor.t() | nil,
|
||||
user: User.t()
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ defmodule Mobilizon.Events.FeedToken do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(%__MODULE__{} = feed_token, attrs) do
|
||||
feed_token
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -57,7 +57,7 @@ defmodule Mobilizon.Events.Participant do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(%__MODULE__{} = participant, attrs) do
|
||||
participant
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -27,7 +27,7 @@ defmodule Mobilizon.Events.Participant.Metadata do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(schema, params) do
|
||||
schema
|
||||
|> cast(params, @attrs)
|
||||
|
||||
@@ -56,7 +56,7 @@ defmodule Mobilizon.Events.Session do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(%__MODULE__{} = session, attrs) do
|
||||
session
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -29,7 +29,7 @@ defmodule Mobilizon.Events.Tag do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(%__MODULE__{} = tag, attrs) do
|
||||
tag
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -28,7 +28,7 @@ defmodule Mobilizon.Events.TagRelation do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(%__MODULE__{} = tag, attrs) do
|
||||
# Return if tag_id or link_id are not set because it will fail later otherwise
|
||||
with %Ecto.Changeset{errors: [], changes: changes} = changeset <-
|
||||
|
||||
@@ -33,7 +33,7 @@ defmodule Mobilizon.Events.Track do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(%__MODULE__{} = track, attrs) do
|
||||
track
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -29,7 +29,7 @@ defmodule Mobilizon.Medias.File do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(%__MODULE__{} = file, attrs) do
|
||||
file
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -42,7 +42,7 @@ defmodule Mobilizon.Medias.Media do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(%__MODULE__{} = media, attrs) do
|
||||
media
|
||||
|> cast(attrs, [:actor_id])
|
||||
|
||||
@@ -130,7 +130,7 @@ defmodule Mobilizon.Medias do
|
||||
|> Multi.run(:remove, fn _repo, %{media: %Media{file: %File{url: url}} = media} ->
|
||||
case Upload.remove(url) do
|
||||
{:error, err} ->
|
||||
if err =~ "doesn't exist" and Keyword.get(opts, :ignore_file_not_found, false) do
|
||||
if err == :enofile and Keyword.get(opts, :ignore_file_not_found, false) do
|
||||
Logger.info("Deleting media and ignoring absent file.")
|
||||
{:ok, media}
|
||||
else
|
||||
|
||||
@@ -31,6 +31,7 @@ defmodule Mobilizon.Mention do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(event, attrs) do
|
||||
event
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -82,6 +82,7 @@ defmodule Mobilizon.Posts.Post do
|
||||
@attrs @required_attrs ++ @optional_attrs
|
||||
|
||||
@doc false
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(%__MODULE__{} = post, attrs) do
|
||||
post
|
||||
|> cast(attrs, @attrs)
|
||||
@@ -153,17 +154,20 @@ defmodule Mobilizon.Posts.Post do
|
||||
# In case the provided picture is an existing one
|
||||
@spec put_picture(Changeset.t(), map) :: Changeset.t()
|
||||
defp put_picture(%Changeset{} = changeset, %{picture: %{picture_id: id} = _picture}) do
|
||||
case Medias.get_media!(id) do
|
||||
%Media{} = picture ->
|
||||
put_assoc(changeset, :picture, picture)
|
||||
|
||||
_ ->
|
||||
changeset
|
||||
end
|
||||
%Media{} = picture = Medias.get_media!(id)
|
||||
put_assoc(changeset, :picture, picture)
|
||||
end
|
||||
|
||||
# In case it's a new picture
|
||||
defp put_picture(%Changeset{} = changeset, _attrs) do
|
||||
cast_assoc(changeset, :picture)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Whether we can show the post. Returns false if the organizer actor or group is suspended
|
||||
"""
|
||||
@spec show?(t) :: boolean()
|
||||
def show?(%__MODULE__{attributed_to: %Actor{suspended: true}}), do: false
|
||||
def show?(%__MODULE__{author: %Actor{suspended: true}}), do: false
|
||||
def show?(%__MODULE__{}), do: true
|
||||
end
|
||||
|
||||
@@ -21,6 +21,7 @@ defmodule Mobilizon.Posts do
|
||||
:private
|
||||
])
|
||||
|
||||
@spec list_public_local_posts(integer | nil, integer | nil) :: Page.t(Post.t())
|
||||
def list_public_local_posts(page \\ nil, limit \\ nil) do
|
||||
Post
|
||||
|> filter_public()
|
||||
@@ -144,12 +145,12 @@ defmodule Mobilizon.Posts do
|
||||
)
|
||||
end
|
||||
|
||||
@spec filter_public(Ecto.Query.t()) :: Ecto.Query.t()
|
||||
@spec filter_public(Ecto.Queryable.t()) :: Ecto.Query.t()
|
||||
defp filter_public(query) do
|
||||
where(query, [p], p.visibility == ^:public and not p.draft)
|
||||
end
|
||||
|
||||
@spec filter_local(Ecto.Query.t()) :: Ecto.Query.t()
|
||||
@spec filter_local(Ecto.Queryable.t()) :: Ecto.Query.t()
|
||||
defp filter_local(query) do
|
||||
where(query, [q], q.local == true)
|
||||
end
|
||||
@@ -161,7 +162,7 @@ defmodule Mobilizon.Posts do
|
||||
|> preload_post_associations()
|
||||
end
|
||||
|
||||
@spec preload_post_associations(Ecto.Query.t(), list()) :: Ecto.Query.t()
|
||||
@spec preload_post_associations(Ecto.Queryable.t(), list()) :: Ecto.Query.t()
|
||||
defp preload_post_associations(query, associations \\ @post_preloads) do
|
||||
preload(query, ^associations)
|
||||
end
|
||||
|
||||
@@ -32,7 +32,7 @@ defmodule Mobilizon.Reports.Note do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(%__MODULE__{} = note, attrs) do
|
||||
note
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -56,7 +56,7 @@ defmodule Mobilizon.Reports.Report do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(%__MODULE__{} = report, attrs) do
|
||||
report
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -79,6 +79,7 @@ defmodule Mobilizon.Resources.Resource do
|
||||
]
|
||||
|
||||
@doc false
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(resource, attrs) do
|
||||
resource
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -29,6 +29,7 @@ defmodule Mobilizon.Share do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t | Ecto.Schema.t(), map()) :: Ecto.Changeset.t()
|
||||
def changeset(share, attrs) do
|
||||
share
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -12,9 +12,9 @@ defmodule Mobilizon.Storage.Page do
|
||||
:elements
|
||||
]
|
||||
|
||||
@type t :: %__MODULE__{
|
||||
@type t(structure) :: %__MODULE__{
|
||||
total: integer,
|
||||
elements: struct
|
||||
elements: list(structure)
|
||||
}
|
||||
|
||||
@doc """
|
||||
@@ -23,7 +23,7 @@ defmodule Mobilizon.Storage.Page do
|
||||
`field` is use to define the field that will be used for the count aggregate, which should be the same as the field used for order_by
|
||||
See https://stackoverflow.com/q/12693089/10204399
|
||||
"""
|
||||
@spec build_page(Ecto.Query.t(), integer | nil, integer | nil, atom()) :: t
|
||||
@spec build_page(Ecto.Queryable.t(), integer | nil, integer | nil, atom()) :: t(any)
|
||||
def build_page(query, page, limit, field \\ :id) do
|
||||
[total, elements] =
|
||||
[
|
||||
@@ -39,7 +39,7 @@ defmodule Mobilizon.Storage.Page do
|
||||
@doc """
|
||||
Add limit and offset to the query.
|
||||
"""
|
||||
@spec paginate(Ecto.Query.t() | struct, integer | nil, integer | nil) :: Ecto.Query.t()
|
||||
@spec paginate(Ecto.Queryable.t() | struct, integer | nil, integer | nil) :: Ecto.Query.t()
|
||||
def paginate(query, page \\ 1, size \\ 10)
|
||||
|
||||
def paginate(query, page, _size) when is_nil(page), do: paginate(query)
|
||||
|
||||
@@ -40,6 +40,7 @@ defmodule Mobilizon.Todos.Todo do
|
||||
@attrs @required_attrs ++ @optional_attrs
|
||||
|
||||
@doc false
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(todo, attrs) do
|
||||
todo
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -34,6 +34,7 @@ defmodule Mobilizon.Todos.TodoList do
|
||||
@attrs @required_attrs ++ @optional_attrs
|
||||
|
||||
@doc false
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(todo_list, attrs) do
|
||||
todo_list
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -26,20 +26,21 @@ defmodule Mobilizon.Tombstone do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t | Ecto.Schema.t(), map()) :: Ecto.Changeset.t()
|
||||
def changeset(%__MODULE__{} = tombstone, attrs) do
|
||||
tombstone
|
||||
|> cast(attrs, @attrs)
|
||||
|> validate_required(@required_attrs)
|
||||
end
|
||||
|
||||
@spec create_tombstone(map) :: {:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()}
|
||||
@spec create_tombstone(map) :: {:ok, t()} | {:error, Ecto.Changeset.t()}
|
||||
def create_tombstone(attrs) do
|
||||
%__MODULE__{}
|
||||
|> changeset(attrs)
|
||||
|> Repo.insert(on_conflict: :replace_all, conflict_target: :uri)
|
||||
end
|
||||
|
||||
@spec find_tombstone(String.t()) :: Ecto.Schema.t() | nil
|
||||
@spec find_tombstone(String.t()) :: t() | nil
|
||||
def find_tombstone(uri) do
|
||||
__MODULE__
|
||||
|> Ecto.Query.where([t], t.uri == ^uri)
|
||||
@@ -54,6 +55,7 @@ defmodule Mobilizon.Tombstone do
|
||||
|> Repo.delete_all()
|
||||
end
|
||||
|
||||
@spec delete_uri_tombstone(String.t()) :: {integer(), nil}
|
||||
def delete_uri_tombstone(uri) do
|
||||
__MODULE__
|
||||
|> Ecto.Query.where(uri: ^uri)
|
||||
|
||||
@@ -25,6 +25,7 @@ defmodule Mobilizon.Users.ActivitySetting do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(activity_setting, attrs) do
|
||||
activity_setting
|
||||
|> cast(attrs, @attrs)
|
||||
|
||||
@@ -25,6 +25,7 @@ defmodule Mobilizon.Users.PushSubscription do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(push_subscription, attrs) do
|
||||
push_subscription
|
||||
|> cast(attrs, [:user_id, :endpoint, :auth, :p256dh])
|
||||
|
||||
@@ -19,6 +19,12 @@ defmodule Mobilizon.Users.Setting do
|
||||
user: User.t()
|
||||
}
|
||||
|
||||
@type location :: %{
|
||||
name: String.t(),
|
||||
range: integer,
|
||||
geohash: String.t()
|
||||
}
|
||||
|
||||
@required_attrs [:user_id]
|
||||
|
||||
@optional_attrs [
|
||||
@@ -66,6 +72,7 @@ defmodule Mobilizon.Users.Setting do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(setting, attrs) do
|
||||
setting
|
||||
|> cast(attrs, @attrs)
|
||||
@@ -73,6 +80,7 @@ defmodule Mobilizon.Users.Setting do
|
||||
|> validate_required(@required_attrs)
|
||||
end
|
||||
|
||||
@spec location_changeset(location, map) :: Ecto.Changeset.t()
|
||||
def location_changeset(schema, params) do
|
||||
schema
|
||||
|> cast(params, @location_attrs)
|
||||
|
||||
@@ -19,7 +19,7 @@ defmodule Mobilizon.Users.User do
|
||||
password_hash: String.t(),
|
||||
password: String.t(),
|
||||
role: UserRole.t(),
|
||||
confirmed_at: DateTime.t(),
|
||||
confirmed_at: DateTime.t() | nil,
|
||||
confirmation_sent_at: DateTime.t(),
|
||||
confirmation_token: String.t(),
|
||||
reset_password_sent_at: DateTime.t(),
|
||||
@@ -32,7 +32,10 @@ defmodule Mobilizon.Users.User do
|
||||
last_sign_in_at: DateTime.t(),
|
||||
last_sign_in_ip: String.t(),
|
||||
current_sign_in_ip: String.t(),
|
||||
current_sign_in_at: DateTime.t()
|
||||
current_sign_in_at: DateTime.t(),
|
||||
activity_settings: [ActivitySetting.t()],
|
||||
settings: Setting.t(),
|
||||
unconfirmed_email: String.t() | nil
|
||||
}
|
||||
|
||||
@required_attrs [:email]
|
||||
@@ -96,7 +99,7 @@ defmodule Mobilizon.Users.User do
|
||||
end
|
||||
|
||||
@doc false
|
||||
@spec changeset(t, map) :: Ecto.Changeset.t()
|
||||
@spec changeset(t | Ecto.Schema.t(), map) :: Ecto.Changeset.t()
|
||||
def changeset(%__MODULE__{} = user, attrs) do
|
||||
changeset =
|
||||
user
|
||||
@@ -129,7 +132,6 @@ defmodule Mobilizon.Users.User do
|
||||
def registration_changeset(%__MODULE__{} = user, attrs) do
|
||||
user
|
||||
|> changeset(attrs)
|
||||
|> cast_assoc(:default_actor)
|
||||
|> validate_required(@registration_required_attrs)
|
||||
|> hash_password()
|
||||
|> save_confirmation_token()
|
||||
@@ -148,7 +150,6 @@ defmodule Mobilizon.Users.User do
|
||||
def auth_provider_changeset(%__MODULE__{} = user, attrs) do
|
||||
user
|
||||
|> changeset(attrs)
|
||||
|> cast_assoc(:default_actor)
|
||||
|> put_change(:confirmed_at, DateTime.utc_now() |> DateTime.truncate(:second))
|
||||
|> validate_required(@auth_provider_required_attrs)
|
||||
end
|
||||
|
||||
@@ -338,10 +338,10 @@ defmodule Mobilizon.Users do
|
||||
"""
|
||||
def get_setting!(user_id), do: Repo.get!(Setting, user_id)
|
||||
|
||||
@spec get_setting(User.t()) :: Setting.t()
|
||||
@spec get_setting(User.t()) :: Setting.t() | nil
|
||||
def get_setting(%User{id: user_id}), do: get_setting(user_id)
|
||||
|
||||
@spec get_setting(String.t() | integer()) :: Setting.t()
|
||||
@spec get_setting(String.t() | integer()) :: Setting.t() | nil
|
||||
def get_setting(user_id), do: Repo.get(Setting, user_id)
|
||||
|
||||
@doc """
|
||||
@@ -356,6 +356,7 @@ defmodule Mobilizon.Users do
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
@spec create_setting(map()) :: {:ok, Setting.t()} | {:error, Ecto.Changeset.t()}
|
||||
def create_setting(attrs \\ %{}) do
|
||||
%Setting{}
|
||||
|> Setting.changeset(attrs)
|
||||
@@ -445,6 +446,8 @@ defmodule Mobilizon.Users do
|
||||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
@spec create_push_subscription(map()) ::
|
||||
{:ok, PushSubscription.t()} | {:error, Ecto.Changeset.t()}
|
||||
def create_push_subscription(attrs \\ %{}) do
|
||||
%PushSubscription{}
|
||||
|> PushSubscription.changeset(attrs)
|
||||
|
||||
Reference in New Issue
Block a user