diff --git a/lib/federation/activity_pub/utils.ex b/lib/federation/activity_pub/utils.ex index 08879e01..77a3e5f7 100644 --- a/lib/federation/activity_pub/utils.ex +++ b/lib/federation/activity_pub/utils.ex @@ -12,7 +12,7 @@ defmodule Mobilizon.Federation.ActivityPub.Utils do alias Mobilizon.Actors.Actor alias Mobilizon.Medias.Media - alias Mobilizon.Federation.ActivityPub.{Actions, Activity, Federator, Relay} + alias Mobilizon.Federation.ActivityPub.{Actions, Activity, Federator} alias Mobilizon.Federation.ActivityPub.Actor, as: ActivityPubActor alias Mobilizon.Federation.ActivityStream.Converter alias Mobilizon.Federation.HTTPSignatures @@ -345,10 +345,6 @@ defmodule Mobilizon.Federation.ActivityPub.Utils do end end - def make_media_data(%Media{} = media) do - Converter.Media.model_to_as(media) - end - def make_media_data(media) when is_map(media) do with {:ok, %{url: url} = uploaded} <- Mobilizon.Web.Upload.store(media.file), @@ -618,16 +614,6 @@ defmodule Mobilizon.Federation.ActivityPub.Utils do [{:Signature, signature}] end - @doc """ - Sign a request with the instance Relay actor. - """ - @spec sign_fetch_relay(Enum.t(), String.t(), String.t()) :: Enum.t() - def sign_fetch_relay(headers, id, date) do - with %Actor{} = actor <- Relay.get_actor() do - sign_fetch(headers, actor, id, date) - end - end - @doc """ Sign a request with an actor. """ diff --git a/lib/federation/activity_stream/converter/utils.ex b/lib/federation/activity_stream/converter/utils.ex index a01be5bd..b05eb6d3 100644 --- a/lib/federation/activity_stream/converter/utils.ex +++ b/lib/federation/activity_stream/converter/utils.ex @@ -38,14 +38,6 @@ defmodule Mobilizon.Federation.ActivityStream.Converter.Utils do def fetch_mentions(_), do: [] - def fetch_address(%{id: id}) do - with {id, ""} <- Integer.parse(id), do: %{id: id} - end - - def fetch_address(address) when is_map(address) do - address - end - def fetch_actors(actors) when is_list(actors) do Logger.debug("fetching contacts") actors |> Enum.map(& &1.id) |> Enum.filter(& &1) |> Enum.map(&Actors.get_actor/1) diff --git a/lib/federation/web_finger/web_finger.ex b/lib/federation/web_finger/web_finger.ex index 65790eb2..e7bcd49d 100644 --- a/lib/federation/web_finger/web_finger.ex +++ b/lib/federation/web_finger/web_finger.ex @@ -76,10 +76,7 @@ defmodule Mobilizon.Federation.WebFinger do @doc """ Return an `Mobilizon.Actors.Actor` Webfinger representation (as JSON) """ - @spec represent_actor(Actor.t()) :: map() @spec represent_actor(Actor.t(), String.t()) :: map() - def represent_actor(%Actor{} = actor), do: represent_actor(actor, "JSON") - def represent_actor(%Actor{} = actor, "JSON") do links = [ diff --git a/lib/graphql/api/events.ex b/lib/graphql/api/events.ex index d71a37f4..92d4b111 100644 --- a/lib/graphql/api/events.ex +++ b/lib/graphql/api/events.ex @@ -29,9 +29,9 @@ defmodule Mobilizon.GraphQL.API.Events do @doc """ Trigger the deletion of an event """ - @spec delete_event(Event.t(), Actor.t(), boolean()) :: {:ok, Activity.t(), Entity.t()} | any() - def delete_event(%Event{} = event, %Actor{} = actor, federate \\ true) do - Actions.Delete.delete(event, actor, federate) + @spec delete_event(Event.t(), Actor.t()) :: {:ok, Activity.t(), Entity.t()} | any() + def delete_event(%Event{} = event, %Actor{} = actor) do + Actions.Delete.delete(event, actor, true) end @spec prepare_args(map) :: map diff --git a/lib/graphql/api/utils.ex b/lib/graphql/api/utils.ex index 1effea58..bde6ce86 100644 --- a/lib/graphql/api/utils.ex +++ b/lib/graphql/api/utils.ex @@ -3,7 +3,7 @@ defmodule Mobilizon.GraphQL.API.Utils do Utils for API. """ - alias Mobilizon.{Config, Medias} + alias Mobilizon.Medias alias Mobilizon.Medias.Media alias Mobilizon.Service.Formatter @@ -30,18 +30,6 @@ defmodule Mobilizon.GraphQL.API.Utils do |> Formatter.linkify(options) end - def make_report_content_text(nil), do: {:ok, nil} - - def make_report_content_text(comment) do - max_size = Config.get([:instance, :max_report_comment_size], 1000) - - if String.length(comment) <= max_size do - {:ok, Formatter.html_escape(comment, "text/plain")} - else - {:error, "Comment must be up to #{max_size} characters"} - end - end - @doc """ Use the data-media-id attributes to extract media from body text """ diff --git a/lib/graphql/resolvers/comment.ex b/lib/graphql/resolvers/comment.ex index 115b654e..247138f8 100644 --- a/lib/graphql/resolvers/comment.ex +++ b/lib/graphql/resolvers/comment.ex @@ -89,7 +89,7 @@ defmodule Mobilizon.GraphQL.Resolvers.Comment do end end - def edit_comment(_parent, _args, _context) do + def update_comment(_parent, _args, _context) do {:error, dgettext("errors", "You are not allowed to update a comment if not connected")} end diff --git a/lib/graphql/resolvers/todos.ex b/lib/graphql/resolvers/todos.ex index f8a269ea..502dda86 100644 --- a/lib/graphql/resolvers/todos.ex +++ b/lib/graphql/resolvers/todos.ex @@ -21,17 +21,17 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do {:ok, Page.t(TodoList.t())} def find_todo_lists_for_group( %Actor{id: group_id} = group, - _args, + %{page: page, limit: limit}, %{ context: %{current_actor: %Actor{id: actor_id}} } = _resolution ) do with {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)}, - %Page{} = page <- Todos.get_todo_lists_for_group(group) do + %Page{} = page <- Todos.get_todo_lists_for_group(group, page, limit) do {:ok, page} else {:member, _} -> - with %Page{} = page <- Todos.get_todo_lists_for_group(group) do + with %Page{} = page <- Todos.get_todo_lists_for_group(group, page, limit) do {:ok, %Page{page | elements: []}} end end @@ -41,17 +41,17 @@ defmodule Mobilizon.GraphQL.Resolvers.Todos do {:ok, %Page{total: 0, elements: []}} end - @spec find_todo_lists_for_group(TodoList.t(), map(), Absinthe.Resolution.t()) :: + @spec find_todos_for_todo_list(TodoList.t(), map(), Absinthe.Resolution.t()) :: {:ok, Page.t(Todo.t())} | {:error, String.t()} def find_todos_for_todo_list( %TodoList{actor_id: group_id} = todo_list, - _args, + %{page: page, limit: limit}, %{ context: %{current_actor: %Actor{id: actor_id}} } = _resolution ) do with {:member, true} <- {:member, Actors.is_member?(actor_id, group_id)}, - %Page{} = page <- Todos.get_todos_for_todo_list(todo_list) do + %Page{} = page <- Todos.get_todos_for_todo_list(todo_list, page, limit) do {:ok, page} else {:member, _} -> diff --git a/lib/graphql/schema/actors/group.ex b/lib/graphql/schema/actors/group.ex index b0917a49..32e12a78 100644 --- a/lib/graphql/schema/actors/group.ex +++ b/lib/graphql/schema/actors/group.ex @@ -129,6 +129,12 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do end field :todo_lists, :paginated_todo_list_list do + arg(:page, :integer, + default_value: 1, + description: "The page in the paginated todo-lists list" + ) + + arg(:limit, :integer, default_value: 10, description: "The limit of todo-lists per page") resolve(&Todos.find_todo_lists_for_group/3) description("A paginated list of the todo lists this group has") end diff --git a/lib/graphql/schema/todos/todo_list.ex b/lib/graphql/schema/todos/todo_list.ex index 7d9b2410..d1b299b8 100644 --- a/lib/graphql/schema/todos/todo_list.ex +++ b/lib/graphql/schema/todos/todo_list.ex @@ -17,10 +17,20 @@ defmodule Mobilizon.GraphQL.Schema.Todos.TodoListType do description: "The actor that owns this todo list" ) - field(:todos, :paginated_todo_list, - resolve: &Todos.find_todos_for_todo_list/3, - description: "The todo-list's todos" - ) + field :todos, :paginated_todo_list do + arg(:page, :integer, + default_value: 1, + description: "The page in the paginated todos list" + ) + + arg(:limit, :integer, + default_value: 10, + description: "The limit of todos per page" + ) + + resolve(&Todos.find_todos_for_todo_list/3) + description("The todo-list's todos") + end end @desc """ diff --git a/lib/mix/tasks/mobilizon/actors/utils.ex b/lib/mix/tasks/mobilizon/actors/utils.ex index 28daefdf..2da7fab4 100644 --- a/lib/mix/tasks/mobilizon/actors/utils.ex +++ b/lib/mix/tasks/mobilizon/actors/utils.ex @@ -50,9 +50,9 @@ defmodule Mix.Tasks.Mobilizon.Actors.Utils do new_person end - @spec create_group(Actor.t(), String.t(), String.t(), Keyword.t()) :: + @spec create_group(Actor.t(), String.t(), String.t()) :: {:ok, Actor.t()} | {:error, Ecto.Changeset.t()} - def create_group(%Actor{id: admin_id}, username, name, _options \\ []) do + def create_group(%Actor{id: admin_id}, username, name) do {username, name} = username_and_name(username, name) Actors.create_group(%{creator_actor_id: admin_id, preferred_username: username, name: name}) diff --git a/lib/mobilizon/activities/activities.ex b/lib/mobilizon/activities/activities.ex index 3989463b..9d826bd7 100644 --- a/lib/mobilizon/activities/activities.ex +++ b/lib/mobilizon/activities/activities.ex @@ -189,12 +189,6 @@ defmodule Mobilizon.Activities do Repo.preload(activity, @activity_preloads) end - @spec object_types :: list(String.t()) - def object_types, do: @object_type - - @spec subjects :: list(String.t()) - def subjects, do: @subjects - @spec activity_types :: list(String.t()) def activity_types, do: @activity_types diff --git a/lib/mobilizon/actors/actors.ex b/lib/mobilizon/actors/actors.ex index 5a253024..68fe1fdc 100644 --- a/lib/mobilizon/actors/actors.ex +++ b/lib/mobilizon/actors/actors.ex @@ -82,10 +82,10 @@ defmodule Mobilizon.Actors do |> Repo.one() end - @spec get_actor_with_preload!(integer | String.t(), boolean) :: Actor.t() - def get_actor_with_preload!(id, include_suspended \\ false) do + @spec get_actor_with_preload!(integer | String.t()) :: Actor.t() + def get_actor_with_preload!(id) do id - |> actor_with_preload_query(include_suspended) + |> actor_with_preload_query(false) |> Repo.one!() end @@ -100,14 +100,6 @@ defmodule Mobilizon.Actors do |> Repo.one() end - @spec get_remote_actor_with_preload(integer | String.t(), boolean()) :: Actor.t() | nil - def get_remote_actor_with_preload(id, include_suspended \\ false) do - id - |> actor_with_preload_query(include_suspended) - |> filter_external() - |> Repo.one() - end - @doc """ Gets an actor by its URL (ActivityPub ID). The `:preload` option allows to preload the followers relation. @@ -131,11 +123,9 @@ defmodule Mobilizon.Actors do New function to replace `Mobilizon.Actors.get_actor_by_url/1` with better signature """ - @spec get_actor_by_url_2(String.t(), boolean) :: Actor.t() | nil - def get_actor_by_url_2(url, preload \\ false) do - Actor - |> Repo.get_by(url: url) - |> preload_followers(preload) + @spec get_actor_by_url_2(String.t()) :: Actor.t() | nil + def get_actor_by_url_2(url) do + Repo.get_by(Actor, url: url) end @doc """ @@ -495,16 +485,6 @@ defmodule Mobilizon.Actors do |> Repo.one() end - @doc """ - Gets a local group by its title. - """ - @spec get_local_group_by_title(String.t()) :: Actor.t() | nil - def get_local_group_by_title(title) do - group_query() - |> filter_by_name([title]) - |> Repo.one() - end - @doc """ Gets a group by its actor id. """ @@ -575,11 +555,6 @@ defmodule Mobilizon.Actors do end end - @doc """ - Deletes a group. - """ - def delete_group!(%Actor{type: :Group} = group), do: Repo.delete!(group) - @doc """ Counts the local groups """ @@ -599,15 +574,6 @@ defmodule Mobilizon.Actors do |> Repo.aggregate(:count) end - @doc """ - Lists the groups. - """ - @spec list_groups(integer | nil, integer | nil) :: Page.t() - def list_groups(page \\ nil, limit \\ nil) do - groups_query() - |> Page.build_page(page, limit) - end - @doc """ Lists the groups. """ @@ -620,10 +586,10 @@ defmodule Mobilizon.Actors do @doc """ Lists the groups. """ - @spec list_external_groups(non_neg_integer()) :: list(Actor.t()) - def list_external_groups(limit \\ 100) when limit > 0 do + @spec list_external_groups :: list(Actor.t()) + def list_external_groups do external_groups_query() - |> limit(^limit) + |> limit(100) |> Repo.all() end @@ -833,30 +799,6 @@ defmodule Mobilizon.Actors do |> Repo.all() end - @spec list_local_members_for_group(Actor.t(), integer | nil, integer | nil) :: - Page.t(Member.t()) - def list_local_members_for_group( - %Actor{id: group_id, type: :Group} = _group, - page \\ nil, - limit \\ nil - ) do - group_id - |> group_internal_member_query() - |> Page.build_page(page, limit) - end - - @spec list_remote_members_for_group(Actor.t(), integer | nil, integer | nil) :: - Page.t(Member.t()) - def list_remote_members_for_group( - %Actor{id: group_id, type: :Group} = _group, - page \\ nil, - limit \\ nil - ) do - group_id - |> group_external_member_query() - |> Page.build_page(page, limit) - end - @doc """ Returns a paginated list of members for a group. """ @@ -888,17 +830,6 @@ defmodule Mobilizon.Actors do |> Repo.all() end - @doc """ - Returns a paginated list of administrator members for a group. - """ - @spec list_administrator_members_for_group(integer | String.t(), integer | nil, integer | nil) :: - Page.t() - def list_administrator_members_for_group(id, page \\ nil, limit \\ nil) do - id - |> administrator_members_for_group_query() - |> Page.build_page(page, limit) - end - @doc """ Returns the complete list of administrator members for a group. """ @@ -1012,12 +943,6 @@ defmodule Mobilizon.Actors do @spec delete_bot(Bot.t()) :: {:ok, Bot.t()} | {:error, Ecto.Changeset.t()} def delete_bot(%Bot{} = bot), do: Repo.delete(bot) - @doc """ - Returns the list of bots. - """ - @spec list_bots :: [Bot.t()] - def list_bots, do: Repo.all(Bot) - @doc """ Gets a single follower. """ @@ -1105,17 +1030,6 @@ defmodule Mobilizon.Actors do |> Repo.delete() end - @doc """ - Returns the list of followers for an actor. - If actor A and C both follow actor B, actor B's followers are A and C. - """ - @spec list_followers_actors_for_actor(Actor.t()) :: [Actor.t()] - def list_followers_actors_for_actor(%Actor{id: actor_id}) do - actor_id - |> follower_actors_for_actor_query() - |> Repo.all() - end - @doc """ Returns the list of external followers for an actor. """ @@ -1177,17 +1091,6 @@ defmodule Mobilizon.Actors do |> Page.build_page(page, limit) end - @doc """ - Returns the list of followings for an actor. - If actor A follows actor B and C, actor A's followings are B and C. - """ - @spec list_followings_for_actor(Actor.t()) :: [Follower.t()] - def list_followings_for_actor(%Actor{id: actor_id}) do - actor_id - |> followings_actors_for_actor_query() - |> Repo.all() - end - @doc """ Returns the number of followings for an actor """ @@ -1485,16 +1388,6 @@ defmodule Mobilizon.Actors do |> select([_m, a], a) end - @spec group_external_member_query(integer()) :: Ecto.Query.t() - defp group_external_member_query(group_id) do - Member - |> where([m], m.parent_id == ^group_id) - |> join(:inner, [m], a in Actor, on: m.actor_id == a.id) - |> where([_m, a], not is_nil(a.domain)) - |> preload([m], [:parent, :actor]) - |> select([m, _a], m) - end - @spec group_internal_member_actor_query(integer(), list()) :: Ecto.Query.t() defp group_internal_member_actor_query(group_id, role) do Member diff --git a/lib/mobilizon/cli.ex b/lib/mobilizon/cli.ex index 56016063..fe032a84 100644 --- a/lib/mobilizon/cli.ex +++ b/lib/mobilizon/cli.ex @@ -44,12 +44,12 @@ defmodule Mobilizon.CLI do end end - @spec migrate(String.t()) :: any() + @spec migrate(any()) :: any() defp migrate(args) do Migrate.run(args) end - @spec rollback(String.t()) :: any() + @spec rollback(any()) :: any() defp rollback(args) do Rollback.run(args) end diff --git a/lib/mobilizon/config.ex b/lib/mobilizon/config.ex index 792eb41b..4cdefb97 100644 --- a/lib/mobilizon/config.ex +++ b/lib/mobilizon/config.ex @@ -223,10 +223,6 @@ defmodule Mobilizon.Config do :confirmation_required ] - @spec anonymous_participation_email_captcha_required? :: boolean - def anonymous_participation_email_captcha_required?, - do: anonymous_config()[:participation][:validation][:captcha][:enabled] - @spec anonymous_event_creation? :: boolean def anonymous_event_creation?, do: anonymous_config()[:event_creation][:allowed] @@ -265,9 +261,6 @@ defmodule Mobilizon.Config do end) end - @spec oauth_consumer_enabled? :: boolean() - def oauth_consumer_enabled?, do: oauth_consumer_strategies() != [] - @spec ldap_enabled? :: boolean() def ldap_enabled?, do: get([:ldap, :enabled], false) diff --git a/lib/mobilizon/discussions/discussions.ex b/lib/mobilizon/discussions/discussions.ex index cc4d1581..cfb080e2 100644 --- a/lib/mobilizon/discussions/discussions.ex +++ b/lib/mobilizon/discussions/discussions.ex @@ -125,13 +125,6 @@ defmodule Mobilizon.Discussions do @spec get_comment_from_url(String.t()) :: Comment.t() | nil def get_comment_from_url(url), do: Repo.get_by(Comment, url: url) - @doc """ - Gets a comment by its URL. - Raises `Ecto.NoResultsError` if the comment does not exist. - """ - @spec get_comment_from_url!(String.t()) :: Comment.t() - def get_comment_from_url!(url), do: Repo.get_by!(Comment, url: url) - @doc """ Gets a comment by its URL, with all associations loaded. """ @@ -175,19 +168,6 @@ defmodule Mobilizon.Discussions do |> Repo.preload(@comment_preloads) end - @doc """ - Get all comment threads under an event - """ - @spec get_threads(String.t() | integer()) :: [Comment.t()] - def get_threads(event_id) do - Comment - |> where([c, _], c.event_id == ^event_id and is_nil(c.origin_comment_id)) - |> join(:left, [c], r in Comment, on: r.origin_comment_id == c.id) - |> group_by([c], c.id) - |> select([c, r], %{c | total_replies: count(r.id)}) - |> Repo.all() - end - @doc """ Gets paginated replies for root comment """ @@ -198,17 +178,6 @@ defmodule Mobilizon.Discussions do |> Repo.all() end - @doc """ - Get a comment or create it - """ - @spec get_or_create_comment(map()) :: {:ok, Comment.t()} - def get_or_create_comment(%{"url" => url} = attrs) do - case Repo.get_by(Comment, url: url) do - %Comment{} = comment -> {:ok, Repo.preload(comment, @comment_preloads)} - nil -> create_comment(attrs) - end - end - @doc """ Creates a comment. """ @@ -253,14 +222,6 @@ defmodule Mobilizon.Discussions do end end - @doc """ - Returns the list of public comments. - """ - @spec list_comments :: [Comment.t()] - def list_comments do - Repo.all(from(c in Comment, where: c.visibility == ^:public)) - end - @doc """ Returns a paginated list of local comments """ diff --git a/lib/mobilizon/events/events.ex b/lib/mobilizon/events/events.ex index b4dec274..25982f68 100644 --- a/lib/mobilizon/events/events.ex +++ b/lib/mobilizon/events/events.ex @@ -159,34 +159,11 @@ defmodule Mobilizon.Events do |> Repo.one!() end - @doc """ - Gets an event by its URL, with all associations loaded. - """ - @spec get_public_event_by_url_with_preload(String.t()) :: - {:ok, Event.t()} | {:error, :event_not_found} - def get_public_event_by_url_with_preload(url) do - event = - url - |> event_by_url_query() - |> filter_unlisted_and_public_visibility() - |> filter_draft() - |> preload_for_event() - |> Repo.one() - - case event do - %Event{} = event -> - {:ok, event} - - nil -> - {:error, :event_not_found} - end - end - @doc """ Gets an event by its URL, with all associations loaded. Raises `Ecto.NoResultsError` if the event does not exist. """ - @spec get_public_event_by_url_with_preload(String.t()) :: Event.t() + @spec get_public_event_by_url_with_preload!(String.t()) :: Event.t() def get_public_event_by_url_with_preload!(url) do url |> event_by_url_query() @@ -228,18 +205,6 @@ defmodule Mobilizon.Events do |> Repo.one() end - @doc """ - Gets an event by its UUID, with all associations loaded. - """ - @spec get_own_event_by_uuid_with_preload(String.t(), integer()) :: Event.t() | nil - def get_own_event_by_uuid_with_preload(uuid, user_id) do - uuid - |> event_by_uuid_query() - |> user_events_query(user_id) - |> preload_for_event() - |> Repo.one() - end - @doc """ Gets an actor's eventual upcoming public event. """ @@ -253,13 +218,6 @@ defmodule Mobilizon.Events do |> Repo.one() end - def get_or_create_event(%{"url" => url} = attrs) do - case Repo.get_by(Event, url: url) do - %Event{} = event -> {:ok, Repo.preload(event, @event_preloads)} - nil -> create_event(attrs) - end - end - @doc """ Creates an event. """ @@ -502,9 +460,9 @@ defmodule Mobilizon.Events do Finds close events to coordinates. Radius is in meters and defaults to 50km. """ - @spec find_close_events(number, number, number, number) :: [Event.t()] - def find_close_events(lon, lat, radius \\ 50_000, srid \\ 4326) do - "SRID=#{srid};POINT(#{lon} #{lat})" + @spec find_close_events(float(), float(), non_neg_integer()) :: [Event.t()] + def find_close_events(lon, lat, radius \\ 50_000) do + "SRID=#{4326};POINT(#{lon} #{lat})" |> Geo.WKT.decode!() |> close_events_query(radius) |> filter_draft() @@ -585,33 +543,6 @@ defmodule Mobilizon.Events do |> Repo.one() end - @doc """ - Gets an existing tag or creates the new one. - - From a map containing a %{"name" => "#mytag"} or a direct binary - """ - @spec get_or_create_tag(map) :: {:ok, Tag.t()} | {:error, Changeset.t()} - def get_or_create_tag(%{"name" => "#" <> title}) do - case Repo.get_by(Tag, title: title) do - %Tag{} = tag -> - {:ok, tag} - - nil -> - create_tag(%{"title" => title}) - end - end - - @spec get_or_create_tag(String.t()) :: {:ok, Tag.t()} | {:error, Changeset.t()} - def get_or_create_tag(title) do - case Repo.get_by(Tag, title: title) do - %Tag{} = tag -> - {:ok, tag} - - nil -> - create_tag(%{"title" => title}) - end - end - @doc """ Creates a tag. """ @@ -663,8 +594,8 @@ defmodule Mobilizon.Events do @doc """ Checks whether two tags are linked or not. """ - @spec are_tags_linked(Tag.t(), Tag.t()) :: boolean - def are_tags_linked(%Tag{id: tag1_id}, %Tag{id: tag2_id}) do + @spec are_tags_linked?(Tag.t(), Tag.t()) :: boolean + def are_tags_linked?(%Tag{id: tag1_id}, %Tag{id: tag2_id}) do tag_relation = tag1_id |> tags_linked_query(tag2_id) @@ -833,8 +764,6 @@ defmodule Mobilizon.Events do |> Repo.one() end - @moderator_roles [:moderator, :administrator, :creator] - @doc """ Returns the number of participations for all local events """ @@ -894,28 +823,6 @@ defmodule Mobilizon.Events do |> Page.build_page(page, limit) end - @doc """ - Returns the list of moderator participants for an event. - - ## Examples - - iex> moderator_for_event?(5, 3) - true - - """ - @spec moderator_for_event?(integer, integer) :: boolean - def moderator_for_event?(event_id, actor_id) do - !(Repo.one( - from( - p in Participant, - where: - p.event_id == ^event_id and - p.actor_id == - ^actor_id and p.role in ^@moderator_roles - ) - ) == nil) - end - @doc """ Returns the list of organizers participants for an event. @@ -957,17 +864,6 @@ defmodule Mobilizon.Events do |> Page.build_page(page, limit) end - @doc """ - Counts approved participants. - """ - @spec count_approved_participants(integer | String.t()) :: integer - def count_approved_participants(event_id) do - event_id - |> count_participants_query() - |> filter_approved_role() - |> Repo.aggregate(:count, :id) - end - @doc """ Counts participant participants (participants with no extra role) """ @@ -979,17 +875,6 @@ defmodule Mobilizon.Events do |> Repo.aggregate(:count, :id) end - @doc """ - Counts rejected participants. - """ - @spec count_rejected_participants(integer | String.t()) :: integer - def count_rejected_participants(event_id) do - event_id - |> count_participants_query() - |> filter_rejected_role() - |> Repo.aggregate(:count, :id) - end - @doc """ Gets the default participant role depending on the event join options. """ @@ -1221,17 +1106,6 @@ defmodule Mobilizon.Events do |> Repo.one() end - @doc """ - Gets a single feed token. - Raises `Ecto.NoResultsError` if the feed token does not exist. - """ - @spec get_feed_token!(String.t()) :: FeedToken.t() - def get_feed_token!(token) do - token - |> feed_token_query() - |> Repo.one!() - end - @doc """ Creates a feed token. """ @@ -1244,17 +1118,6 @@ defmodule Mobilizon.Events do |> Repo.insert() end - @doc """ - Updates a feed token. - """ - @spec update_feed_token(FeedToken.t(), map) :: - {:ok, FeedToken.t()} | {:error, Changeset.t()} - def update_feed_token(%FeedToken{} = feed_token, attrs) do - feed_token - |> FeedToken.changeset(attrs) - |> Repo.update() - end - @doc """ Deletes a feed token. """ @@ -1746,21 +1609,11 @@ defmodule Mobilizon.Events do ) end - @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.Queryable.t()) :: Ecto.Query.t() defp filter_participant_role(query) do filter_role(query, :participant) end - @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.Queryable.t(), list(atom()) | atom()) :: Ecto.Query.t() def filter_role(query, []), do: query diff --git a/lib/mobilizon/medias/medias.ex b/lib/mobilizon/medias/medias.ex index a706e8b1..d781de87 100644 --- a/lib/mobilizon/medias/medias.ex +++ b/lib/mobilizon/medias/medias.ex @@ -52,16 +52,6 @@ defmodule Mobilizon.Medias do |> Repo.all() end - @doc """ - List the paginated media for an actor - """ - @spec medias_for_actor(integer | String.t(), integer | nil, integer | nil) :: Page.t() - def medias_for_actor(actor_id, page, limit) do - actor_id - |> medias_for_actor_query() - |> Page.build_page(page, limit) - end - @doc """ List the paginated media for user """ @@ -109,16 +99,6 @@ defmodule Mobilizon.Medias do |> Repo.insert() end - @doc """ - Updates a media. - """ - @spec update_media(Media.t(), map) :: {:ok, Media.t()} | {:error, Ecto.Changeset.t()} - def update_media(%Media{} = media, attrs) do - media - |> Media.changeset(attrs) - |> Repo.update() - end - @doc """ Deletes a media. """ diff --git a/lib/mobilizon/posts/posts.ex b/lib/mobilizon/posts/posts.ex index d7bd9294..2f4d7897 100644 --- a/lib/mobilizon/posts/posts.ex +++ b/lib/mobilizon/posts/posts.ex @@ -69,10 +69,6 @@ defmodule Mobilizon.Posts do |> Repo.preload(@post_preloads) end - @spec get_post_by_slug(String.t()) :: Post.t() | nil - def get_post_by_slug(nil), do: nil - def get_post_by_slug(slug), do: Repo.get_by(Post, slug: slug) - @spec get_post_by_slug_with_preloads(String.t()) :: Post.t() | nil def get_post_by_slug_with_preloads(slug) do Post diff --git a/lib/mobilizon/reports/reports.ex b/lib/mobilizon/reports/reports.ex index d774c616..419dd3b9 100644 --- a/lib/mobilizon/reports/reports.ex +++ b/lib/mobilizon/reports/reports.ex @@ -23,27 +23,6 @@ defmodule Mobilizon.Reports do |> Repo.preload([:reported, :reporter, :manager, :event, :comments, :notes]) end - @doc """ - Gets a single report. - Raises `Ecto.NoResultsError` if the report does not exist. - """ - @spec get_report!(integer | String.t()) :: Report.t() - def get_report!(id) do - Report - |> Repo.get!(id) - |> Repo.preload([:reported, :reporter, :manager, :event, :comments, :notes]) - end - - @doc """ - Get a report by its URL - """ - @spec get_report_by_url(String.t()) :: Report.t() | nil - def get_report_by_url(url) do - url - |> report_by_url_query() - |> Repo.one() - end - @doc """ Creates a report. """ @@ -67,12 +46,6 @@ defmodule Mobilizon.Reports do |> Repo.update() end - @doc """ - Deletes a report. - """ - @spec delete_report(Report.t()) :: {:ok, Report.t()} | {:error, Ecto.Changeset.t()} - def delete_report(%Report{} = report), do: Repo.delete(report) - @doc """ Returns the list of reports. """ @@ -104,13 +77,6 @@ defmodule Mobilizon.Reports do @spec get_note(integer | String.t()) :: Note.t() | nil def get_note(id), do: Repo.get(Note, id) - @doc """ - Gets a single note. - Raises `Ecto.NoResultsError` if the Note does not exist. - """ - @spec get_note!(integer | String.t()) :: Note.t() - def get_note!(id), do: Repo.get!(Note, id) - @doc """ Creates a note. """ @@ -130,21 +96,6 @@ defmodule Mobilizon.Reports do @spec delete_note(Note.t()) :: {:ok, Note.t()} | {:error, Ecto.Changeset.t()} def delete_note(%Note{} = note), do: Repo.delete(note) - @doc """ - Returns the list of notes for a report. - """ - @spec list_notes_for_report(Report.t()) :: [Note.t()] - def list_notes_for_report(%Report{id: report_id}) do - report_id - |> list_notes_for_report_query() - |> Repo.all() - end - - @spec report_by_url_query(String.t()) :: Ecto.Query.t() - defp report_by_url_query(url) do - from(r in Report, where: r.uri == ^url) - end - @spec list_reports_query(ReportStatus.t()) :: Ecto.Query.t() defp list_reports_query(status) do from( @@ -158,13 +109,4 @@ defmodule Mobilizon.Reports do defp count_reports_query do from(r in Report, where: r.status == ^:open) end - - @spec list_notes_for_report_query(integer | String.t()) :: Ecto.Query.t() - defp list_notes_for_report_query(report_id) do - from( - n in Note, - where: n.report_id == ^report_id, - preload: [:report, :moderator] - ) - end end diff --git a/lib/mobilizon/resources/resources.ex b/lib/mobilizon/resources/resources.ex index 1293a9da..9ef6302f 100644 --- a/lib/mobilizon/resources/resources.ex +++ b/lib/mobilizon/resources/resources.ex @@ -27,13 +27,6 @@ defmodule Mobilizon.Resources do |> Page.build_page(page, limit) end - @doc """ - Returns the list of top-level resources for a group - """ - def get_top_level_resources_for_group(%Actor{id: group_id}, page \\ nil, limit \\ nil) do - get_resources_for_folder(%Resource{id: "root_something", actor_id: group_id}, page, limit) - end - @doc """ Returns the list of resources for a resource folder. """ diff --git a/lib/mobilizon/users/user.ex b/lib/mobilizon/users/user.ex index cc61aaee..c0e50b6a 100644 --- a/lib/mobilizon/users/user.ex +++ b/lib/mobilizon/users/user.ex @@ -188,13 +188,6 @@ defmodule Mobilizon.Users.User do |> hash_password() end - @doc """ - Checks whether an user is confirmed. - """ - @spec is_confirmed(t) :: boolean - def is_confirmed(%__MODULE__{confirmed_at: nil}), do: false - def is_confirmed(%__MODULE__{}), do: true - @doc """ Returns whether an user owns an actor. """ diff --git a/lib/mobilizon/users/users.ex b/lib/mobilizon/users/users.ex index 1d8b746b..380d6ac3 100644 --- a/lib/mobilizon/users/users.ex +++ b/lib/mobilizon/users/users.ex @@ -91,19 +91,6 @@ defmodule Mobilizon.Users do end end - @doc """ - Gets an user by its email. - """ - @spec get_user_by_email!(String.t(), Keyword.t()) :: User.t() - def get_user_by_email!(email, options \\ []) do - activated = Keyword.get(options, :activated, nil) - unconfirmed = Keyword.get(options, :unconfirmed, true) - - email - |> user_by_email_query(activated, unconfirmed) - |> Repo.one!() - end - @doc """ Get an user by its activation token. """ @@ -326,22 +313,6 @@ defmodule Mobilizon.Users do @spec count_users :: integer def count_users, do: Repo.one(from(u in User, select: count(u.id), where: u.disabled == false)) - @doc """ - Gets a settings for an user. - - Raises `Ecto.NoResultsError` if the Setting does not exist. - - ## Examples - - iex> get_setting!(123) - %Setting{} - - iex> get_setting!(456) - ** (Ecto.NoResultsError) - - """ - def get_setting!(user_id), do: Repo.get!(Setting, user_id) - @spec get_setting(User.t()) :: Setting.t() | nil def get_setting(%User{id: user_id}), do: get_setting(user_id) @@ -388,35 +359,6 @@ defmodule Mobilizon.Users do |> Repo.update() end - @doc """ - Deletes a setting. - - ## Examples - - iex> delete_setting(setting) - {:ok, %Setting{}} - - iex> delete_setting(setting) - {:error, %Ecto.Changeset{}} - - """ - def delete_setting(%Setting{} = setting) do - Repo.delete(setting) - end - - @doc """ - Returns an `%Ecto.Changeset{}` for tracking setting changes. - - ## Examples - - iex> change_setting(setting) - %Ecto.Changeset{source: %Setting{}} - - """ - def change_setting(%Setting{} = setting) do - Setting.changeset(setting, %{}) - end - @doc """ Get a paginated list of all of a user's subscriptions """ @@ -458,24 +400,6 @@ defmodule Mobilizon.Users do |> Repo.insert() end - @doc """ - Updates a push subscription. - - ## Examples - - iex> update_push_subscription(push_subscription, %{field: new_value}) - {:ok, %PushSubscription{}} - - iex> update_push_subscription(push_subscription, %{field: bad_value}) - {:error, %Ecto.Changeset{}} - - """ - def update_push_subscription(%PushSubscription{} = push_subscription, attrs) do - push_subscription - |> PushSubscription.changeset(attrs) - |> Repo.update() - end - @doc """ Deletes a push subscription. diff --git a/lib/mobilizon/utils.ex b/lib/mobilizon/utils.ex deleted file mode 100644 index 400edf4c..00000000 --- a/lib/mobilizon/utils.ex +++ /dev/null @@ -1,25 +0,0 @@ -# Portions of this file are derived from Pleroma: -# Pleroma: A lightweight social networking server -# Copyright © 2017-2020 Pleroma Authors -# SPDX-License-Identifier: AGPL-3.0-only - -defmodule Mobilizon.Utils do - @moduledoc """ - Module that provide generic utils functions for Mobilizon - """ - - @doc """ - POSIX-compliant check if command is available in the system - - ## Examples - iex> command_available?("git") - true - iex> command_available?("wrongcmd") - false - - """ - @spec command_available?(String.t()) :: boolean() - def command_available?(command) do - match?({_output, 0}, System.cmd("sh", ["-c", "command -v #{command}"])) - end -end diff --git a/lib/service/activity/activity.ex b/lib/service/activity/activity.ex index 3435f44e..6287f86b 100644 --- a/lib/service/activity/activity.ex +++ b/lib/service/activity/activity.ex @@ -16,11 +16,6 @@ defmodule Mobilizon.Service.Activity do do_get_object(object_type, object_id) end - @spec has_object?(Activity.t()) :: boolean() - def has_object?(%Activity{} = activity) do - !is_nil(object(activity)) - end - defp do_get_object(_, nil), do: nil defp do_get_object(:event, event_id) do diff --git a/lib/service/export/common.ex b/lib/service/export/common.ex index 8b11870b..0a39b1ce 100644 --- a/lib/service/export/common.ex +++ b/lib/service/export/common.ex @@ -102,7 +102,7 @@ defmodule Mobilizon.Service.Export.Common do end @spec fetch_actor_private_events(Actor.t(), integer()) :: list(Event.t()) - def fetch_actor_private_events(%Actor{} = actor, limit) do + defp fetch_actor_private_events(%Actor{} = actor, limit) do actor |> fetch_identity_participations(limit) |> participations_to_events() end diff --git a/lib/service/export/icalendar.ex b/lib/service/export/icalendar.ex index 74e2ee3d..83125bde 100644 --- a/lib/service/export/icalendar.ex +++ b/lib/service/export/icalendar.ex @@ -3,7 +3,6 @@ defmodule Mobilizon.Service.Export.ICalendar do Export an event to iCalendar format. """ - alias Mobilizon.Actors.Actor alias Mobilizon.Addresses.Address alias Mobilizon.{Config, Events} alias Mobilizon.Events.Event @@ -79,14 +78,11 @@ defmodule Mobilizon.Service.Export.ICalendar do def export_public_event(%Event{}), do: {:error, :event_not_public} - @doc """ - Export a public actor's events to iCalendar format. - - The actor must have a visibility of `:public` or `:unlisted`, as well as the events - """ + # Export a public actor's events to iCalendar format. + # The actor must have a visibility of `:public` or `:unlisted`, as well as the events @spec export_public_actor(String.t()) :: {:ok, String.t()} | {:error, :actor_not_public | :actor_not_found} - def export_public_actor(name, limit \\ @item_limit) do + defp export_public_actor(name, limit \\ @item_limit) do case Common.fetch_actor_event_feed(name, limit) do {:ok, _actor, events, _posts} -> {:ok, events_to_ics(events)} @@ -96,12 +92,6 @@ defmodule Mobilizon.Service.Export.ICalendar do end end - @spec export_private_actor(Actor.t(), integer()) :: {:ok, String.t()} - def export_private_actor(%Actor{} = actor, limit \\ @item_limit) do - events = Common.fetch_actor_private_events(actor, limit) - {:ok, events_to_ics(events)} - end - @spec fetch_events_from_token(String.t(), integer()) :: {:ok, String.t()} | {:error, :actor_not_public | :actor_not_found} defp fetch_events_from_token(token, limit \\ @item_limit) do diff --git a/lib/service/http/activity_pub.ex b/lib/service/http/activity_pub.ex index 57e4ea83..a84b28a8 100644 --- a/lib/service/http/activity_pub.ex +++ b/lib/service/http/activity_pub.ex @@ -28,12 +28,12 @@ defmodule Mobilizon.Service.HTTP.ActivityPub do Tesla.client(middleware, {adapter, opts}) end - @spec get(Tesla.Client.t(), String.t()) :: Tesla.Env.t() + @spec get(Tesla.Client.t(), String.t()) :: Tesla.Env.result() def get(client, url) do Tesla.get(client, url) end - @spec post(Tesla.Client.t(), String.t(), map() | String.t()) :: Tesla.Env.t() + @spec post(Tesla.Client.t(), String.t(), map() | String.t()) :: Tesla.Env.result() def post(client, url, data) do Tesla.post(client, url, data) end diff --git a/lib/service/rich_media/parsers/twitter_card.ex b/lib/service/rich_media/parsers/twitter_card.ex index 6d2d5297..70740d16 100644 --- a/lib/service/rich_media/parsers/twitter_card.ex +++ b/lib/service/rich_media/parsers/twitter_card.ex @@ -25,19 +25,29 @@ defmodule Mobilizon.Service.RichMedia.Parsers.TwitterCard do Logger.debug("Using Twitter card parser") with {:ok, data} <- parse_name_attrs(data, html), - {:ok, data} <- parse_property_attrs(data, html), - data <- transform_tags(data) do + {:ok, data} <- parse_property_attrs(data, html) do + data = transform_tags(data) Logger.debug("Data found with Twitter card parser") Logger.debug(inspect(data)) data end end + @spec parse_name_attrs(map(), String.t()) :: {:ok, map()} | {:error, String.t()} defp parse_name_attrs(data, html) do - MetaTagsParser.parse(html, data, "twitter", %{}, :name, :content, [:"twitter:card"]) + MetaTagsParser.parse( + html, + data, + "twitter", + "No twitter card metadata found", + :name, + :content, + [:"twitter:card"] + ) end - defp parse_property_attrs({_, data}, html) do + @spec parse_property_attrs(map(), String.t()) :: {:ok, map()} | {:error, String.t()} + defp parse_property_attrs(data, html) do MetaTagsParser.parse( html, data, @@ -49,6 +59,7 @@ defmodule Mobilizon.Service.RichMedia.Parsers.TwitterCard do ) end + @spec transform_tags(map()) :: map() defp transform_tags(data) do data |> Enum.reject(fn {_, v} -> is_nil(v) end) diff --git a/lib/web/cache/cache.ex b/lib/web/cache/cache.ex index d90007a0..39180667 100644 --- a/lib/web/cache/cache.ex +++ b/lib/web/cache/cache.ex @@ -10,21 +10,9 @@ defmodule Mobilizon.Web.Cache do alias Mobilizon.Resources.Resource alias Mobilizon.Todos.{Todo, TodoList} alias Mobilizon.Web.Cache.ActivityPub - import Mobilizon.Service.Guards, only: [is_valid_string: 1] - - @caches [:activity_pub, :feed, :ics] @type local_actor :: %Actor{domain: nil} - @doc """ - Clears all caches for a local actor. - """ - @spec clear_cache(%Actor{domain: nil, preferred_username: String.t()}) :: :ok - def clear_cache(%Actor{preferred_username: preferred_username, domain: nil}) - when is_valid_string(preferred_username) do - Enum.each(@caches, &Cachex.del(&1, "actor_" <> preferred_username)) - end - @spec get_actor_by_name(binary) :: {:commit, Actor.t()} | {:ignore, nil} defdelegate get_actor_by_name(name), to: ActivityPub @spec get_local_actor_by_name(binary) :: {:commit, Actor.t()} | {:ignore, nil} diff --git a/lib/web/controllers/feed_controller.ex b/lib/web/controllers/feed_controller.ex index cf464626..8e8e2b22 100644 --- a/lib/web/controllers/feed_controller.ex +++ b/lib/web/controllers/feed_controller.ex @@ -30,7 +30,6 @@ defmodule Mobilizon.Web.FeedController do return_data(conn, "ics", "event_" <> uuid, "event") end - @spec instance(Plug.Conn.t(), map()) :: Plug.Conn.t() def event(_conn, _) do {:error, :not_found} end diff --git a/lib/web/email/admin.ex b/lib/web/email/admin.ex index bde93cf0..d9e2cce3 100644 --- a/lib/web/email/admin.ex +++ b/lib/web/email/admin.ex @@ -15,9 +15,9 @@ defmodule Mobilizon.Web.Email.Admin do alias Mobilizon.Web.Email - @spec report(User.t(), Report.t(), String.t()) :: Bamboo.Email.t() - def report(%User{email: email} = user, %Report{} = report, default_locale \\ "en") do - locale = Map.get(user, :locale, default_locale) + @spec report(User.t(), Report.t()) :: Bamboo.Email.t() + def report(%User{email: email} = user, %Report{} = report) do + locale = Map.get(user, :locale, "en") Gettext.put_locale(locale) subject = diff --git a/lib/web/email/checker.ex b/lib/web/email/checker.ex index 977eb58c..fd30f567 100644 --- a/lib/web/email/checker.ex +++ b/lib/web/email/checker.ex @@ -11,11 +11,11 @@ defmodule Mobilizon.Web.Email.Checker do @spec valid?(String.t()) :: boolean def valid?(email), do: email =~ @email_regex - @spec validate_changeset(Ecto.Changeset.t(), atom()) :: Ecto.Changeset.t() - def validate_changeset(%Ecto.Changeset{} = changeset, key \\ :email) do + @spec validate_changeset(Ecto.Changeset.t()) :: Ecto.Changeset.t() + def validate_changeset(%Ecto.Changeset{} = changeset) do changeset = Ecto.Changeset.validate_length(changeset, :email, min: 3, max: 250) - case Ecto.Changeset.fetch_change(changeset, key) do + case Ecto.Changeset.fetch_change(changeset, :email) do {:ok, email} -> if valid?(email), do: changeset, diff --git a/lib/web/email/group.ex b/lib/web/email/group.ex index 6a81fd39..faad3e2a 100644 --- a/lib/web/email/group.ex +++ b/lib/web/email/group.ex @@ -15,17 +15,15 @@ defmodule Mobilizon.Web.Email.Group do @doc """ Send emails to local user """ - @spec send_invite_to_user(Member.t(), String.t()) :: :ok - def send_invite_to_user(member, locale \\ "en") - def send_invite_to_user(%Member{actor: %Actor{user_id: nil}}, _locale), do: :ok + @spec send_invite_to_user(Member.t()) :: :ok + def send_invite_to_user(%Member{actor: %Actor{user_id: nil}}), do: :ok def send_invite_to_user( %Member{actor: %Actor{user_id: user_id}, parent: %Actor{} = group, role: :invited} = - member, - locale + member ) do with %User{email: email} = user <- Users.get_user!(user_id) do - locale = Map.get(user, :locale, locale) + locale = Map.get(user, :locale, "en") Gettext.put_locale(locale) %Actor{name: invited_by_name} = inviter = Actors.get_actor(member.invited_by_id) diff --git a/lib/web/email/user.ex b/lib/web/email/user.ex index 1ad29b71..413fb81b 100644 --- a/lib/web/email/user.ex +++ b/lib/web/email/user.ex @@ -144,10 +144,11 @@ defmodule Mobilizon.Web.Email.User do end end - def send_email_reset_old_email( - %User{locale: user_locale, email: email, unconfirmed_email: unconfirmed_email} = _user, - _locale \\ "en" - ) do + def send_email_reset_old_email(%User{ + locale: user_locale, + email: email, + unconfirmed_email: unconfirmed_email + }) do Gettext.put_locale(user_locale) subject = @@ -163,14 +164,11 @@ defmodule Mobilizon.Web.Email.User do |> render(:email_changed_old) end - def send_email_reset_new_email( - %User{ - locale: user_locale, - unconfirmed_email: unconfirmed_email, - confirmation_token: confirmation_token - } = _user, - _locale \\ "en" - ) do + def send_email_reset_new_email(%User{ + locale: user_locale, + unconfirmed_email: unconfirmed_email, + confirmation_token: confirmation_token + }) do Gettext.put_locale(user_locale) subject = diff --git a/lib/web/proxy/reverse_proxy.ex b/lib/web/proxy/reverse_proxy.ex index 9bb83b5a..9ac99938 100644 --- a/lib/web/proxy/reverse_proxy.ex +++ b/lib/web/proxy/reverse_proxy.ex @@ -17,9 +17,6 @@ defmodule Mobilizon.Web.ReverseProxy do @max_body_length :infinity @methods ~w(GET HEAD) - def max_read_duration_default, do: @max_read_duration - def default_cache_control_header, do: @default_cache_control_header - @moduledoc """ A reverse proxy. diff --git a/lib/web/upload/mime.ex b/lib/web/upload/mime.ex index 2f547803..3f07a0e7 100644 --- a/lib/web/upload/mime.ex +++ b/lib/web/upload/mime.ex @@ -36,22 +36,6 @@ defmodule Mobilizon.Web.Upload.MIME do end) end - def bin_mime_type(binary, filename) do - with {:ok, content_type} <- bin_mime_type(binary), - filename <- fix_extension(filename, content_type) do - {:ok, content_type, filename} - end - end - - @spec bin_mime_type(binary()) :: {:ok, String.t()} | {:error, :unknown_mime} - def bin_mime_type(<>) do - {:ok, check_mime_type(head)} - end - - def bin_mime_type(_), do: {:error, :unknown_mime} - - def mime_type(<<_::binary>>), do: {:ok, @default} - defp fix_extension(filename, content_type) when is_binary(filename) and is_binary(content_type) do parts = String.split(filename, ".") diff --git a/lib/web/upload/upload.ex b/lib/web/upload/upload.ex index 5a4ec274..f762b0f9 100644 --- a/lib/web/upload/upload.ex +++ b/lib/web/upload/upload.ex @@ -94,19 +94,21 @@ defmodule Mobilizon.Web.Upload do end end - @spec remove(String.t(), Keyword.t()) :: - {:ok, String.t()} | {:error, atom} | {:error, String.t()} - def remove(url, opts \\ []) do - with opts <- get_opts(opts), - %URI{path: "/media/" <> path, host: host} <- URI.parse(url), - {:same_host, true} <- {:same_host, host == Endpoint.host()} do - Uploader.remove_file(opts.uploader, path) - else - %URI{} = _uri -> - {:error, "URL doesn't match pattern"} + @spec remove(String.t()) :: {:ok, String.t()} | {:error, atom} + def remove(url) do + %{uploader: uploader} = get_opts([]) - {:same_host, _} -> - Logger.error("Media can't be deleted because its URL doesn't match current host") + case URI.parse(url) do + %URI{path: "/media/" <> path, host: host} -> + if host == Endpoint.host() do + Uploader.remove_file(uploader, path) + else + Logger.error("Media can't be deleted because its URL doesn't match current host") + {:error, :not_same_host} + end + + %URI{} = _uri -> + {:error, :url_invalid} end end diff --git a/mix.exs b/mix.exs index 22eb1685..c4693fc4 100644 --- a/mix.exs +++ b/mix.exs @@ -9,7 +9,7 @@ defmodule Mobilizon.Mixfile do version: @version, elixir: "~> 1.11", elixirc_paths: elixirc_paths(Mix.env()), - compilers: [:gettext] ++ Mix.compilers(), + compilers: [:gettext, :unused] ++ Mix.compilers(), xref: [exclude: [:eldap]], start_permanent: Mix.env() == :prod, aliases: aliases(), @@ -37,6 +37,44 @@ defmodule Mobilizon.Mixfile do config_providers: [{Mobilizon.ConfigProvider, "/etc/mobilizon/config.exs"}], steps: [:assemble, ©_files/1, ©_config/1] ] + ], + unused: [ + ignore: [ + Mobilizon.Storage.Repo, + Mobilizon.Storage.PostgresTypes, + Mobilizon.Factory, + Mobilizon.Web.Router.Helpers, + Mobilizon.Web.Email.Mailer, + Mobilizon.Web.Auth.Guardian.Plug, + Mobilizon.Web.Gettext, + Mobilizon.Web.Endpoint, + Mobilizon.Web.Auth.Guardian, + Mobilizon.Web, + Mobilizon.GraphQL.Schema.Compiled, + Mobilizon.GraphQL.Schema, + Mobilizon.Web.Router, + Mobilizon.Users.Setting.Location, + {:_, :start_link, 1}, + {:_, :child_spec, 1}, + {:_, :__impl__, 1}, + {:_, :__schema__, :_}, + {:_, :__struct__, 0..1}, + {:_, :__changeset__, 0}, + {:_, :create_type, 0}, + {:_, :drop_type, 0}, + {:_, :schema, 0}, + {:_, :schemaless_type, 0}, + {:_, :valid_value?, 0..1}, + {:_, :__enum_map__, 0}, + {:_, :__absinthe_blueprint__, :_}, + {:_, :__absinthe_function__, :_}, + {~r/^Mobilizon.Web.*Controller/, :_, 2}, + {~r/^Mobilizon.Web.*View/, :_, :_}, + {~r/^Mobilizon.Web.Email.*/, :render, 3}, + {~r/^Mobilizon.Service.HTTP.*Client/, :_, :_}, + {~r/^Mobilizon.Cldr.*/, :_, :_}, + {Mobilizon.Web.GraphQLSocket, :__channel__, 1} + ] ] ] end @@ -183,7 +221,8 @@ defmodule Mobilizon.Mixfile do {:mox, "~> 1.0", only: :test}, {:junit_formatter, "~> 3.1", only: [:test]}, {:sobelow, "~> 0.8", only: [:dev, :test]}, - {:doctor, "~> 0.18.0", only: :dev} + {:doctor, "~> 0.18.0", only: :dev}, + {:mix_unused, "~> 0.2.0"} ] ++ oauth_deps() end diff --git a/mix.lock b/mix.lock index c6e1bddd..6b3969f4 100644 --- a/mix.lock +++ b/mix.lock @@ -94,6 +94,7 @@ "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, "mimetype_parser": {:hex, :mimetype_parser, "0.1.3", "628ac9fe56aa7edcedb534d68397dd66674ab82493c8ebe39acb9a19b666099d", [:mix], [], "hexpm", "7d8f80c567807ce78cd93c938e7f4b0a20b1aaaaab914bf286f68457d9f7a852"}, "mix_test_watch": {:hex, :mix_test_watch, "1.1.0", "330bb91c8ed271fe408c42d07e0773340a7938d8a0d281d57a14243eae9dc8c3", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}], "hexpm", "52b6b1c476cbb70fd899ca5394506482f12e5f6b0d6acff9df95c7f1e0812ec3"}, + "mix_unused": {:hex, :mix_unused, "0.2.0", "430d011f7c86eec8e4824c66fb69127f192ca3b2b2dd0e0f8f58bf535d319167", [:mix], [], "hexpm", "f3eb53bf416d89be1db801865b3f2a6c8c084e138ad290c82b5136a31e5622ad"}, "mmdb2_decoder": {:hex, :mmdb2_decoder, "3.0.0", "54828676a36e75e9a25bc9a0bb0598d4c7fcc767bf0b40674850b22e05b7b6cc", [:mix], [], "hexpm", "359dc9242915538d1dceb9f6d96c72201dca76ce62e49d22e2ed1e86f20bea8e"}, "mock": {:hex, :mock, "0.3.7", "75b3bbf1466d7e486ea2052a73c6e062c6256fb429d6797999ab02fa32f29e03", [:mix], [{:meck, "~> 0.9.2", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "4da49a4609e41fd99b7836945c26f373623ea968cfb6282742bcb94440cf7e5c"}, "mogrify": {:hex, :mogrify, "0.9.1", "a26f107c4987477769f272bd0f7e3ac4b7b75b11ba597fd001b877beffa9c068", [:mix], [], "hexpm", "134edf189337d2125c0948bf0c228fdeef975c594317452d536224069a5b7f05"}, diff --git a/test/mobilizon/actors/actors_test.exs b/test/mobilizon/actors/actors_test.exs index 1a8417c0..0e79e680 100644 --- a/test/mobilizon/actors/actors_test.exs +++ b/test/mobilizon/actors/actors_test.exs @@ -413,12 +413,6 @@ defmodule Mobilizon.ActorsTest do @update_attrs %{source: "some updated source", type: "some updated type"} @invalid_attrs %{source: nil, type: nil} - test "list_bots/0 returns all bots" do - bot = insert(:bot) - bot_found_id = Actors.list_bots() |> hd |> Map.get(:id) - assert bot_found_id == bot.id - end - test "get_bot!/1 returns the bot with given id" do %Bot{id: bot_id} = bot = insert(:bot) assert bot_id == Actors.get_bot!(bot.id).id diff --git a/test/mobilizon/discussions_test.exs b/test/mobilizon/discussions_test.exs index b1801ac7..a86cd95f 100644 --- a/test/mobilizon/discussions_test.exs +++ b/test/mobilizon/discussions_test.exs @@ -12,12 +12,6 @@ defmodule Mobilizon.DiscussionsTest do @update_attrs %{text: "some updated text"} @invalid_attrs %{text: nil, url: nil} - test "list_comments/0 returns all comments" do - %Comment{id: comment_id} = insert(:comment) - comment_ids = Discussions.list_comments() |> Enum.map(& &1.id) - assert comment_ids == [comment_id] - end - test "get_comment!/1 returns the comment with given id" do %Comment{id: comment_id} = insert(:comment) comment_fetched = Discussions.get_comment!(comment_id) diff --git a/test/mobilizon/events/events_test.exs b/test/mobilizon/events/events_test.exs index c9b6e9b5..efc0ae55 100644 --- a/test/mobilizon/events/events_test.exs +++ b/test/mobilizon/events/events_test.exs @@ -301,8 +301,8 @@ defmodule Mobilizon.EventsTest do assert {:ok, %TagRelation{}} = Events.create_tag_relation(%{tag_id: tag1_id, link_id: tag2_id}) - assert Events.are_tags_linked(tag1, tag2) - assert Events.are_tags_linked(tag2, tag1) + assert Events.are_tags_linked?(tag1, tag2) + assert Events.are_tags_linked?(tag2, tag1) end test "create_tag_relation/1 with invalid data returns error changeset", %{ @@ -312,7 +312,7 @@ defmodule Mobilizon.EventsTest do assert {:error, %Ecto.Changeset{}} = Events.create_tag_relation(%{tag_id: nil, link_id: nil}) - refute Events.are_tags_linked(tag1, tag2) + refute Events.are_tags_linked?(tag1, tag2) end test "delete_tag_relation/1 deletes the tag relation" do diff --git a/test/mobilizon/media/media_test.exs b/test/mobilizon/media/media_test.exs index 065ef99b..d6b6bdfd 100644 --- a/test/mobilizon/media/media_test.exs +++ b/test/mobilizon/media/media_test.exs @@ -17,12 +17,6 @@ defmodule Mobilizon.MediaTest do name: "something old" } } - @update_attrs %{ - file: %{ - url: "https://something.tld/media/something_updated", - name: "something new" - } - } test "get_media!/1 returns the media with given id" do media = insert(:media) @@ -36,18 +30,6 @@ defmodule Mobilizon.MediaTest do assert media.file.name == "something old" end - test "update_media/2 with valid data updates the media" do - media = insert(:media) - - assert {:ok, %Media{} = media} = - Medias.update_media( - media, - Map.put(@update_attrs, :actor_id, insert(:actor).id) - ) - - assert media.file.name == "something new" - end - test "delete_media/1 deletes the media" do media = insert(:media) diff --git a/test/mobilizon/users/users_test.exs b/test/mobilizon/users/users_test.exs index 0a1ba31f..f9e878fd 100644 --- a/test/mobilizon/users/users_test.exs +++ b/test/mobilizon/users/users_test.exs @@ -128,12 +128,6 @@ defmodule Mobilizon.UsersTest do setting end - test "get_setting!/1 returns the setting with given id" do - %User{id: user_id} = insert(:user) - setting = setting_fixture(user_id: user_id) - assert Users.get_setting!(setting.user_id) == setting - end - test "create_setting/1 with valid data creates a setting" do %User{id: user_id} = insert(:user) @@ -155,18 +149,5 @@ defmodule Mobilizon.UsersTest do assert setting.timezone == "Atlantic/Cape_Verde" assert setting.notification_each_week == false end - - test "delete_setting/1 deletes the setting" do - %User{id: user_id} = insert(:user) - setting = setting_fixture(user_id: user_id) - assert {:ok, %Setting{}} = Users.delete_setting(setting) - assert_raise Ecto.NoResultsError, fn -> Users.get_setting!(setting.user_id) end - end - - test "change_setting/1 returns a setting changeset" do - %User{id: user_id} = insert(:user) - setting = setting_fixture(user_id: user_id) - assert %Ecto.Changeset{} = Users.change_setting(setting) - end end end diff --git a/test/support/data_case.ex b/test/support/data_case.ex index 0423a977..0da48e94 100644 --- a/test/support/data_case.ex +++ b/test/support/data_case.ex @@ -74,6 +74,21 @@ defmodule Mobilizon.DataCase do :ok end + @doc """ + POSIX-compliant check if command is available in the system + + ## Examples + iex> command_available?("git") + true + iex> command_available?("wrongcmd") + false + + """ + @spec command_available?(String.t()) :: boolean() + def command_available?(command) do + match?({_output, 0}, System.cmd("sh", ["-c", "command -v #{command}"])) + end + Mox.defmock(Mobilizon.Service.HTTP.ActivityPub.Mock, for: Tesla.Adapter) Mox.defmock(Mobilizon.Service.HTTP.GeospatialClient.Mock, diff --git a/test/web/controllers/webfinger_controller_test.exs b/test/web/controllers/webfinger_controller_test.exs index bfbe7d4c..c4d2a894 100644 --- a/test/web/controllers/webfinger_controller_test.exs +++ b/test/web/controllers/webfinger_controller_test.exs @@ -31,7 +31,7 @@ defmodule Mobilizon.Web.WebFingerControllerTest do test "GET /.well-known/webfinger with local actor", %{conn: conn} do %Actor{preferred_username: username} = actor = insert(:actor) conn = get(conn, "/.well-known/webfinger?resource=acct:#{username}@mobilizon.test") - assert json_response(conn, 200) == WebFinger.represent_actor(actor) + assert json_response(conn, 200) == WebFinger.represent_actor(actor, "JSON") end test "GET /.well-known/webfinger with non existent actor", %{conn: conn} do diff --git a/test/web/upload/filter/exiftool_test.exs b/test/web/upload/filter/exiftool_test.exs index 49f770c7..56dc1ce8 100644 --- a/test/web/upload/filter/exiftool_test.exs +++ b/test/web/upload/filter/exiftool_test.exs @@ -8,9 +8,15 @@ defmodule Mobilizon.Web.Upload.Filter.ExiftoolTest do alias Mobilizon.Web.Upload alias Mobilizon.Web.Upload.Filter - test "apply exiftool filter" do - assert Mobilizon.Utils.command_available?("exiftool") + setup do + if command_available?("exiftool") do + {:ok, skip: true} + else + :ok + end + end + test "apply exiftool filter" do File.cp!( "test/fixtures/DSCN0010.jpg", "test/fixtures/DSCN0010_tmp.jpg"