Merge branch 'master' into refactoring-based-on-credo-and-dialyzer
This commit is contained in:
@@ -42,6 +42,7 @@ defmodule Mobilizon do
|
||||
Mobilizon.Service.Federator,
|
||||
cachex_spec(:feed, 2500, 60, 60, &Feed.create_cache/1),
|
||||
cachex_spec(:ics, 2500, 60, 60, &ICalendar.create_cache/1),
|
||||
cachex_spec(:statistics, 10, 60, 60),
|
||||
cachex_spec(:activity_pub, 2500, 3, 15)
|
||||
]
|
||||
|
||||
|
||||
@@ -65,12 +65,8 @@ defmodule Mobilizon.Addresses.Address do
|
||||
|
||||
@spec set_url(Ecto.Changeset.t()) :: Ecto.Changeset.t()
|
||||
defp set_url(%Ecto.Changeset{changes: changes} = changeset) do
|
||||
url =
|
||||
Map.get(
|
||||
changes,
|
||||
:url,
|
||||
"#{MobilizonWeb.Endpoint.url()}/address/#{Ecto.UUID.generate()}"
|
||||
)
|
||||
uuid = Ecto.UUID.generate()
|
||||
url = Map.get(changes, :url, "#{MobilizonWeb.Endpoint.url()}/address/#{uuid}")
|
||||
|
||||
put_change(changeset, :url, url)
|
||||
end
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
import EctoEnum
|
||||
|
||||
defenum(Mobilizon.Admin.ActionLogAction, [
|
||||
"update",
|
||||
"create",
|
||||
"delete"
|
||||
])
|
||||
|
||||
defmodule Mobilizon.Admin.ActionLog do
|
||||
@moduledoc """
|
||||
Represents an action log entity.
|
||||
@@ -8,6 +16,7 @@ defmodule Mobilizon.Admin.ActionLog do
|
||||
import Ecto.Changeset
|
||||
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Admin.ActionLogAction
|
||||
|
||||
@type t :: %__MODULE__{
|
||||
action: String.t(),
|
||||
@@ -17,12 +26,13 @@ defmodule Mobilizon.Admin.ActionLog do
|
||||
actor: Actor.t()
|
||||
}
|
||||
|
||||
@required_attrs [:action, :target_type, :target_id, :actor_id]
|
||||
@optional_attrs [:changes]
|
||||
@attrs @required_attrs ++ @optional_attrs
|
||||
@required_attrs [:action, :target_type, :target_id, :changes, :actor_id]
|
||||
@attrs @required_attrs
|
||||
|
||||
@timestamps_opts [type: :utc_datetime]
|
||||
|
||||
schema "admin_action_logs" do
|
||||
field(:action, :string)
|
||||
field(:action, ActionLogAction)
|
||||
field(:target_type, :string)
|
||||
field(:target_id, :integer)
|
||||
field(:changes, :map)
|
||||
|
||||
@@ -30,6 +30,6 @@ defmodule Mobilizon.Admin do
|
||||
|
||||
@spec list_action_logs_query :: Ecto.Query.t()
|
||||
defp list_action_logs_query do
|
||||
from(r in ActionLog, preload: [:actor])
|
||||
from(r in ActionLog, preload: [:actor], order_by: [desc: :id])
|
||||
end
|
||||
end
|
||||
|
||||
@@ -36,6 +36,7 @@ defmodule Mobilizon.Events.EventOptions do
|
||||
]
|
||||
|
||||
@primary_key false
|
||||
@derive Jason.Encoder
|
||||
embedded_schema do
|
||||
field(:maximum_attendee_capacity, :integer)
|
||||
field(:remaining_attendee_capacity, :integer)
|
||||
|
||||
@@ -657,6 +657,28 @@ defmodule Mobilizon.Events do
|
||||
|> Repo.all()
|
||||
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 unapproved participants.
|
||||
"""
|
||||
@spec count_unapproved_participants(integer | String.t()) :: integer
|
||||
def count_unapproved_participants(event_id) do
|
||||
event_id
|
||||
|> count_participants_query()
|
||||
|> filter_unapproved_role()
|
||||
|> Repo.aggregate(:count, :id)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets a single session.
|
||||
Raises `Ecto.NoResultsError` if the session does not exist.
|
||||
@@ -1145,6 +1167,11 @@ defmodule Mobilizon.Events do
|
||||
from(p in Participant, where: p.actor_id == ^actor_id and p.role == ^:not_approved)
|
||||
end
|
||||
|
||||
@spec count_participants_query(integer) :: Ecto.Query.t()
|
||||
defp count_participants_query(event_id) do
|
||||
from(p in Participant, where: p.event_id == ^event_id)
|
||||
end
|
||||
|
||||
@spec event_participations_for_actor_query(integer) :: Ecto.Query.t()
|
||||
def event_participations_for_actor_query(actor_id) do
|
||||
from(
|
||||
@@ -1244,11 +1271,18 @@ defmodule Mobilizon.Events do
|
||||
from(q in query, where: q.visibility == ^:public)
|
||||
end
|
||||
|
||||
@spec filter_role(Ecto.Query.t(), boolean) :: Ecto.Query.t()
|
||||
defp filter_role(query, false) do
|
||||
@spec filter_approved_role(Ecto.Query.t()) :: Ecto.Query.t()
|
||||
defp filter_approved_role(query) do
|
||||
from(p in query, where: p.role != ^:not_approved)
|
||||
end
|
||||
|
||||
@spec filter_unapproved_role(Ecto.Query.t()) :: Ecto.Query.t()
|
||||
defp filter_unapproved_role(query) do
|
||||
from(p in query, where: p.role == ^:not_approved)
|
||||
end
|
||||
|
||||
@spec filter_role(Ecto.Query.t(), boolean) :: Ecto.Query.t()
|
||||
defp filter_role(query, false), do: filter_approved_role(query)
|
||||
defp filter_role(query, true), do: query
|
||||
|
||||
@spec preload_for_event(Ecto.Query.t()) :: Ecto.Query.t()
|
||||
|
||||
@@ -13,6 +13,8 @@ defmodule Mobilizon.Reports.Note do
|
||||
@required_attrs [:content, :moderator_id, :report_id]
|
||||
@attrs @required_attrs
|
||||
|
||||
@timestamps_opts [type: :utc_datetime]
|
||||
|
||||
@type t :: %__MODULE__{
|
||||
content: String.t(),
|
||||
report: Report.t(),
|
||||
|
||||
@@ -23,10 +23,12 @@ defmodule Mobilizon.Reports.Report do
|
||||
notes: [Note.t()]
|
||||
}
|
||||
|
||||
@required_attrs [:content, :uri, :reported_id, :reporter_id]
|
||||
@optional_attrs [:status, :manager_id, :event_id]
|
||||
@required_attrs [:uri, :reported_id, :reporter_id]
|
||||
@optional_attrs [:content, :status, :manager_id, :event_id]
|
||||
@attrs @required_attrs ++ @optional_attrs
|
||||
|
||||
@timestamps_opts [type: :utc_datetime]
|
||||
|
||||
@derive {Jason.Encoder, only: [:status, :uri]}
|
||||
schema "reports" do
|
||||
field(:content, :string)
|
||||
|
||||
@@ -76,14 +76,29 @@ defmodule Mobilizon.Reports do
|
||||
@doc """
|
||||
Returns the list of reports.
|
||||
"""
|
||||
@spec list_reports(integer | nil, integer | nil, atom, atom) :: [Report.t()]
|
||||
def list_reports(page \\ nil, limit \\ nil, sort \\ :updated_at, direction \\ :asc) do
|
||||
list_reports_query()
|
||||
@spec list_reports(integer | nil, integer | nil, atom, atom, ReportStatus) :: [Report.t()]
|
||||
def list_reports(
|
||||
page \\ nil,
|
||||
limit \\ nil,
|
||||
sort \\ :updated_at,
|
||||
direction \\ :asc,
|
||||
status \\ :open
|
||||
) do
|
||||
status
|
||||
|> list_reports_query()
|
||||
|> Page.paginate(page, limit)
|
||||
|> sort(sort, direction)
|
||||
|> Repo.all()
|
||||
end
|
||||
|
||||
@doc """
|
||||
Counts opened reports.
|
||||
"""
|
||||
@spec count_opened_reports :: integer
|
||||
def count_opened_reports do
|
||||
Repo.aggregate(count_reports_query(), :count, :id)
|
||||
end
|
||||
|
||||
@doc """
|
||||
Gets a single note.
|
||||
"""
|
||||
@@ -131,14 +146,20 @@ defmodule Mobilizon.Reports do
|
||||
from(r in Report, where: r.uri == ^url)
|
||||
end
|
||||
|
||||
@spec list_reports_query :: Ecto.Query.t()
|
||||
defp list_reports_query do
|
||||
@spec list_reports_query(ReportStatus.t()) :: Ecto.Query.t()
|
||||
defp list_reports_query(status) do
|
||||
from(
|
||||
r in Report,
|
||||
preload: [:reported, :reporter, :manager, :event, :comments, :notes]
|
||||
preload: [:reported, :reporter, :manager, :event, :comments, :notes],
|
||||
where: r.status == ^status
|
||||
)
|
||||
end
|
||||
|
||||
@spec count_reports_query :: Ecto.Query.t()
|
||||
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(
|
||||
|
||||
@@ -135,4 +135,13 @@ defmodule MobilizonWeb.API.Events do
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
@doc """
|
||||
Trigger the deletion of an event
|
||||
|
||||
If the event is deleted by
|
||||
"""
|
||||
def delete_event(%Event{} = event, federate \\ true) do
|
||||
ActivityPub.delete(event, federate)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -22,21 +22,17 @@ defmodule MobilizonWeb.API.Reports do
|
||||
def report(
|
||||
%{
|
||||
reporter_actor_id: reporter_actor_id,
|
||||
reported_actor_id: reported_actor_id,
|
||||
event_id: event_id,
|
||||
comments_ids: comments_ids,
|
||||
report_content: report_content
|
||||
reported_actor_id: reported_actor_id
|
||||
} = args
|
||||
) do
|
||||
with {:reporter, %Actor{url: reporter_url} = _reporter_actor} <-
|
||||
{:reporter, Actors.get_actor!(reporter_actor_id)},
|
||||
{:reported, %Actor{url: reported_actor_url} = reported_actor} <-
|
||||
{:reported, Actors.get_actor!(reported_actor_id)},
|
||||
{:ok, content} <- make_report_content_html(report_content),
|
||||
{:ok, event} <-
|
||||
if(event_id, do: Events.get_event(event_id), else: {:ok, nil}),
|
||||
{:ok, content} <- args |> Map.get(:content, nil) |> make_report_content_text(),
|
||||
{:ok, event} <- args |> Map.get(:event_id, nil) |> get_event(),
|
||||
{:get_report_comments, comments_urls} <-
|
||||
get_report_comments(reported_actor, comments_ids),
|
||||
get_report_comments(reported_actor, Map.get(args, :comments_ids, [])),
|
||||
{:make_activity, {:ok, %Activity{} = activity, %Report{} = report}} <-
|
||||
{:make_activity,
|
||||
ActivityPub.flag(%{
|
||||
@@ -50,6 +46,7 @@ defmodule MobilizonWeb.API.Reports do
|
||||
})} do
|
||||
{:ok, activity, report}
|
||||
else
|
||||
{:make_activity, err} -> {:error, err}
|
||||
{:error, err} -> {:error, err}
|
||||
{:actor_id, %{}} -> {:error, "Valid `actor_id` required"}
|
||||
{:reporter, nil} -> {:error, "Reporter Actor not found"}
|
||||
@@ -57,6 +54,9 @@ defmodule MobilizonWeb.API.Reports do
|
||||
end
|
||||
end
|
||||
|
||||
defp get_event(nil), do: {:ok, nil}
|
||||
defp get_event(event_id), do: Events.get_event(event_id)
|
||||
|
||||
@doc """
|
||||
Update the state of a report
|
||||
"""
|
||||
|
||||
@@ -124,9 +124,9 @@ defmodule MobilizonWeb.API.Utils do
|
||||
# |> Formatter.html_escape("text/html")
|
||||
# end
|
||||
|
||||
def make_report_content_html(nil), do: {:ok, {nil, [], []}}
|
||||
def make_report_content_text(nil), do: {:ok, nil}
|
||||
|
||||
def make_report_content_html(comment) do
|
||||
def make_report_content_text(comment) do
|
||||
max_size = Config.get([:instance, :max_report_comment_size], 1000)
|
||||
|
||||
if String.length(comment) <= max_size do
|
||||
@@ -137,7 +137,7 @@ defmodule MobilizonWeb.API.Utils do
|
||||
end
|
||||
|
||||
def prepare_content(actor, content, visibility, tags, in_reply_to) do
|
||||
with content <- String.trim(content),
|
||||
with content <- String.trim(content || ""),
|
||||
{content_html, mentions, tags} <-
|
||||
make_content_html(
|
||||
content,
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
defmodule MobilizonWeb.NodeInfoController do
|
||||
use MobilizonWeb, :controller
|
||||
|
||||
alias Mobilizon.{Config, Events, Users}
|
||||
alias Mobilizon.Config
|
||||
alias Mobilizon.Service.Statistics
|
||||
|
||||
@node_info_supported_versions ["2.0", "2.1"]
|
||||
@node_info_schema_uri "http://nodeinfo.diaspora.software/ns/schema/"
|
||||
@@ -32,7 +33,7 @@ defmodule MobilizonWeb.NodeInfoController do
|
||||
response = %{
|
||||
version: version,
|
||||
software: %{
|
||||
name: "mobilizon",
|
||||
name: "Mobilizon",
|
||||
version: Config.instance_version()
|
||||
},
|
||||
protocols: ["activitypub"],
|
||||
@@ -43,10 +44,10 @@ defmodule MobilizonWeb.NodeInfoController do
|
||||
openRegistrations: Config.instance_registrations_open?(),
|
||||
usage: %{
|
||||
users: %{
|
||||
total: Users.count_users()
|
||||
total: Statistics.get_cached_value(:local_users)
|
||||
},
|
||||
localPosts: Events.count_local_events(),
|
||||
localComments: Events.count_local_comments()
|
||||
localPosts: Statistics.get_cached_value(:local_events),
|
||||
localComments: Statistics.get_cached_value(:local_comments)
|
||||
},
|
||||
metadata: %{
|
||||
nodeName: Config.instance_name(),
|
||||
|
||||
@@ -2,10 +2,13 @@ defmodule MobilizonWeb.Resolvers.Admin do
|
||||
@moduledoc """
|
||||
Handles the report-related GraphQL calls
|
||||
"""
|
||||
alias Mobilizon.Events
|
||||
alias Mobilizon.Users.User
|
||||
import Mobilizon.Users.Guards
|
||||
alias Mobilizon.Admin.ActionLog
|
||||
alias Mobilizon.Reports.{Report, Note}
|
||||
alias Mobilizon.Events.Event
|
||||
alias Mobilizon.Service.Statistics
|
||||
|
||||
def list_action_logs(_parent, %{page: page, limit: limit}, %{
|
||||
context: %{current_user: %User{role: role}}
|
||||
@@ -17,14 +20,19 @@ defmodule MobilizonWeb.Resolvers.Admin do
|
||||
target_type: target_type,
|
||||
action: action,
|
||||
actor: actor,
|
||||
id: id
|
||||
id: id,
|
||||
inserted_at: inserted_at
|
||||
} = action_log ->
|
||||
transform_action_log(target_type, action, action_log)
|
||||
|> Map.merge(%{
|
||||
actor: actor,
|
||||
id: id
|
||||
})
|
||||
with data when is_map(data) <-
|
||||
transform_action_log(String.to_existing_atom(target_type), action, action_log) do
|
||||
Map.merge(data, %{
|
||||
actor: actor,
|
||||
id: id,
|
||||
inserted_at: inserted_at
|
||||
})
|
||||
end
|
||||
end)
|
||||
|> Enum.filter(& &1)
|
||||
|
||||
{:ok, action_logs}
|
||||
end
|
||||
@@ -35,38 +43,87 @@ defmodule MobilizonWeb.Resolvers.Admin do
|
||||
end
|
||||
|
||||
defp transform_action_log(
|
||||
"Elixir.Mobilizon.Reports.Report",
|
||||
"update",
|
||||
Report,
|
||||
:update,
|
||||
%ActionLog{} = action_log
|
||||
) do
|
||||
with %Report{status: status} = report <- Mobilizon.Reports.get_report(action_log.target_id) do
|
||||
with %Report{} = report <- Mobilizon.Reports.get_report(action_log.target_id) do
|
||||
action =
|
||||
case action_log do
|
||||
%ActionLog{changes: %{"status" => "closed"}} -> :report_update_closed
|
||||
%ActionLog{changes: %{"status" => "open"}} -> :report_update_opened
|
||||
%ActionLog{changes: %{"status" => "resolved"}} -> :report_update_resolved
|
||||
end
|
||||
|
||||
%{
|
||||
action: "report_update_" <> to_string(status),
|
||||
action: action,
|
||||
object: report
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
defp transform_action_log("Elixir.Mobilizon.Reports.Note", "create", %ActionLog{
|
||||
defp transform_action_log(Note, :create, %ActionLog{
|
||||
changes: changes
|
||||
}) do
|
||||
%{
|
||||
action: "note_creation",
|
||||
action: :note_creation,
|
||||
object: convert_changes_to_struct(Note, changes)
|
||||
}
|
||||
end
|
||||
|
||||
defp transform_action_log("Elixir.Mobilizon.Reports.Note", "delete", %ActionLog{
|
||||
defp transform_action_log(Note, :delete, %ActionLog{
|
||||
changes: changes
|
||||
}) do
|
||||
%{
|
||||
action: "note_deletion",
|
||||
action: :note_deletion,
|
||||
object: convert_changes_to_struct(Note, changes)
|
||||
}
|
||||
end
|
||||
|
||||
defp transform_action_log(Event, :delete, %ActionLog{
|
||||
changes: changes
|
||||
}) do
|
||||
%{
|
||||
action: :event_deletion,
|
||||
object: convert_changes_to_struct(Event, changes)
|
||||
}
|
||||
end
|
||||
|
||||
# Changes are stored as %{"key" => "value"} so we need to convert them back as struct
|
||||
defp convert_changes_to_struct(struct, %{"report_id" => _report_id} = changes) do
|
||||
with data <- for({key, val} <- changes, into: %{}, do: {String.to_atom(key), val}),
|
||||
data <- Map.put(data, :report, Mobilizon.Reports.get_report(data.report_id)) do
|
||||
struct(struct, data)
|
||||
end
|
||||
end
|
||||
|
||||
defp convert_changes_to_struct(struct, changes) do
|
||||
struct(struct, for({key, val} <- changes, into: %{}, do: {String.to_atom(key), val}))
|
||||
with data <- for({key, val} <- changes, into: %{}, do: {String.to_atom(key), val}) do
|
||||
struct(struct, data)
|
||||
end
|
||||
end
|
||||
|
||||
def get_dashboard(_parent, _args, %{
|
||||
context: %{current_user: %User{role: role}}
|
||||
})
|
||||
when is_admin(role) do
|
||||
last_public_event_published =
|
||||
case Events.list_events(1, 1, :inserted_at, :desc) do
|
||||
[event | _] -> event
|
||||
_ -> nil
|
||||
end
|
||||
|
||||
{:ok,
|
||||
%{
|
||||
number_of_users: Statistics.get_cached_value(:local_users),
|
||||
number_of_events: Statistics.get_cached_value(:local_events),
|
||||
number_of_comments: Statistics.get_cached_value(:local_comments),
|
||||
number_of_reports: Mobilizon.Reports.count_opened_reports(),
|
||||
last_public_event_published: last_public_event_published
|
||||
}}
|
||||
end
|
||||
|
||||
def get_dashboard(_parent, _args, _resolution) do
|
||||
{:error, "You need to be logged-in and an administrator to access dashboard statistics"}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -9,7 +9,10 @@ defmodule MobilizonWeb.Resolvers.Event do
|
||||
alias Mobilizon.Events.{Activity, Event, Participant}
|
||||
alias Mobilizon.Media.Picture
|
||||
alias Mobilizon.Users.User
|
||||
alias Mobilizon.Actors
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias MobilizonWeb.Resolvers.Person
|
||||
import Mobilizon.Service.Admin.ActionLogService
|
||||
|
||||
# We limit the max number of events that can be retrieved
|
||||
@event_max_limit 100
|
||||
@@ -48,6 +51,14 @@ defmodule MobilizonWeb.Resolvers.Event do
|
||||
{:ok, Mobilizon.Events.list_participants_for_event(uuid, 1, 10)}
|
||||
end
|
||||
|
||||
def stats_participants_for_event(%Event{id: id}, _args, _resolution) do
|
||||
{:ok,
|
||||
%{
|
||||
approved: Mobilizon.Events.count_approved_participants(id),
|
||||
unapproved: Mobilizon.Events.count_unapproved_participants(id)
|
||||
}}
|
||||
end
|
||||
|
||||
@doc """
|
||||
List related events
|
||||
"""
|
||||
@@ -174,10 +185,10 @@ defmodule MobilizonWeb.Resolvers.Event do
|
||||
# See https://github.com/absinthe-graphql/absinthe/issues/490
|
||||
with args <- Map.put(args, :options, args[:options] || %{}),
|
||||
{:is_owned, %Actor{} = organizer_actor} <- User.owns_actor(user, organizer_actor_id),
|
||||
{:ok, args} <- save_attached_picture(args),
|
||||
{:ok, args} <- save_physical_address(args),
|
||||
args_with_organizer <- Map.put(args, :organizer_actor, organizer_actor),
|
||||
{:ok, %Activity{data: %{"object" => %{"type" => "Event"} = _object}}, %Event{} = event} <-
|
||||
{:ok, args_with_organizer} <- save_attached_picture(args_with_organizer),
|
||||
{:ok, args_with_organizer} <- save_physical_address(args_with_organizer),
|
||||
{:ok, %Activity{data: %{"object" => %{"type" => "Event"}}}, %Event{} = event} <-
|
||||
MobilizonWeb.API.Events.create_event(args_with_organizer) do
|
||||
{:ok, event}
|
||||
else
|
||||
@@ -200,13 +211,13 @@ defmodule MobilizonWeb.Resolvers.Event do
|
||||
) do
|
||||
# See https://github.com/absinthe-graphql/absinthe/issues/490
|
||||
with args <- Map.put(args, :options, args[:options] || %{}),
|
||||
{:ok, %Event{} = event} <- Mobilizon.Events.get_event_with_preload(event_id),
|
||||
{:ok, %Event{} = event} <- Events.get_event_with_preload(event_id),
|
||||
{:is_owned, %Actor{} = organizer_actor} <-
|
||||
User.owns_actor(user, event.organizer_actor_id),
|
||||
args <- Map.put(args, :organizer_actor, organizer_actor),
|
||||
{:ok, args} <- save_attached_picture(args),
|
||||
{:ok, args} <- save_physical_address(args),
|
||||
args <- Map.put(args, :organizer_actor, organizer_actor),
|
||||
{:ok, %Activity{data: %{"object" => %{"type" => "Event"} = _object}}, %Event{} = event} <-
|
||||
{:ok, %Activity{data: %{"object" => %{"type" => "Event"}}}, %Event{} = event} <-
|
||||
MobilizonWeb.API.Events.update_event(args, event) do
|
||||
{:ok, event}
|
||||
else
|
||||
@@ -229,7 +240,7 @@ defmodule MobilizonWeb.Resolvers.Event do
|
||||
defp save_attached_picture(
|
||||
%{picture: %{picture: %{file: %Plug.Upload{} = _picture} = all_pic}} = args
|
||||
) do
|
||||
{:ok, Map.put(args, :picture, Map.put(all_pic, :actor_id, args.organizer_actor_id))}
|
||||
{:ok, Map.put(args, :picture, Map.put(all_pic, :actor_id, args.organizer_actor.id))}
|
||||
end
|
||||
|
||||
# Otherwise if we use a previously uploaded picture we need to fetch it from database
|
||||
@@ -253,7 +264,7 @@ defmodule MobilizonWeb.Resolvers.Event do
|
||||
end
|
||||
|
||||
@spec save_physical_address(map()) :: {:ok, map()}
|
||||
defp save_physical_address(%{physical_address: address} = args) do
|
||||
defp save_physical_address(%{physical_address: address} = args) when address != nil do
|
||||
with {:ok, %Address{} = address} <- Addresses.create_address(address),
|
||||
args <- Map.put(args, :physical_address, address.url) do
|
||||
{:ok, args}
|
||||
@@ -269,26 +280,42 @@ defmodule MobilizonWeb.Resolvers.Event do
|
||||
def delete_event(
|
||||
_parent,
|
||||
%{event_id: event_id, actor_id: actor_id},
|
||||
%{context: %{current_user: user}}
|
||||
%{context: %{current_user: %User{role: role} = user}}
|
||||
) do
|
||||
with {:ok, %Event{} = event} <- Mobilizon.Events.get_event(event_id),
|
||||
{:is_owned, %Actor{}} <- User.owns_actor(user, actor_id),
|
||||
{:event_can_be_managed, true} <- Event.can_be_managed_by(event, actor_id),
|
||||
event <- Mobilizon.Events.delete_event!(event) do
|
||||
{:ok, %{id: event.id}}
|
||||
with {:ok, %Event{local: is_local} = event} <- Events.get_event_with_preload(event_id),
|
||||
{actor_id, ""} <- Integer.parse(actor_id),
|
||||
{:is_owned, %Actor{}} <- User.owns_actor(user, actor_id) do
|
||||
cond do
|
||||
{:event_can_be_managed, true} == Event.can_be_managed_by(event, actor_id) ->
|
||||
do_delete_event(event)
|
||||
|
||||
role in [:moderator, :administrator] ->
|
||||
with {:ok, res} <- do_delete_event(event, !is_local),
|
||||
%Actor{} = actor <- Actors.get_actor(actor_id) do
|
||||
log_action(actor, "delete", event)
|
||||
|
||||
{:ok, res}
|
||||
end
|
||||
|
||||
true ->
|
||||
{:error, "You cannot delete this event"}
|
||||
end
|
||||
else
|
||||
{:error, :event_not_found} ->
|
||||
{:error, "Event not found"}
|
||||
|
||||
{:is_owned, nil} ->
|
||||
{:error, "Actor id is not owned by authenticated user"}
|
||||
|
||||
{:event_can_be_managed, false} ->
|
||||
{:error, "You cannot delete this event"}
|
||||
end
|
||||
end
|
||||
|
||||
def delete_event(_parent, _args, _resolution) do
|
||||
{:error, "You need to be logged-in to delete an event"}
|
||||
end
|
||||
|
||||
defp do_delete_event(event, federate \\ true) when is_boolean(federate) do
|
||||
with {:ok, _activity, event} <- MobilizonWeb.API.Events.delete_event(event) do
|
||||
{:ok, %{id: event.id}}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -76,7 +76,9 @@ defmodule MobilizonWeb.Resolvers.Group do
|
||||
%{group_id: group_id, actor_id: actor_id},
|
||||
%{context: %{current_user: user}}
|
||||
) do
|
||||
with {:ok, %Actor{} = group} <- Actors.get_group_by_actor_id(group_id),
|
||||
with {actor_id, ""} <- Integer.parse(actor_id),
|
||||
{group_id, ""} <- Integer.parse(group_id),
|
||||
{:ok, %Actor{} = group} <- Actors.get_group_by_actor_id(group_id),
|
||||
{:is_owned, %Actor{}} <- User.owns_actor(user, actor_id),
|
||||
{:ok, %Member{} = member} <- Actors.get_member(actor_id, group.id),
|
||||
{:is_admin, true} <- Member.is_administrator(member),
|
||||
@@ -109,7 +111,9 @@ defmodule MobilizonWeb.Resolvers.Group do
|
||||
%{group_id: group_id, actor_id: actor_id},
|
||||
%{context: %{current_user: user}}
|
||||
) do
|
||||
with {:is_owned, %Actor{} = actor} <- User.owns_actor(user, actor_id),
|
||||
with {actor_id, ""} <- Integer.parse(actor_id),
|
||||
{group_id, ""} <- Integer.parse(group_id),
|
||||
{:is_owned, %Actor{} = actor} <- User.owns_actor(user, actor_id),
|
||||
{:ok, %Actor{} = group} <- Actors.get_group_by_actor_id(group_id),
|
||||
{:error, :member_not_found} <- Actors.get_member(actor.id, group.id),
|
||||
{:is_able_to_join, true} <- {:is_able_to_join, Member.can_be_joined(group)},
|
||||
@@ -150,7 +154,9 @@ defmodule MobilizonWeb.Resolvers.Group do
|
||||
%{group_id: group_id, actor_id: actor_id},
|
||||
%{context: %{current_user: user}}
|
||||
) do
|
||||
with {:is_owned, %Actor{} = actor} <- User.owns_actor(user, actor_id),
|
||||
with {actor_id, ""} <- Integer.parse(actor_id),
|
||||
{group_id, ""} <- Integer.parse(group_id),
|
||||
{:is_owned, %Actor{} = actor} <- User.owns_actor(user, actor_id),
|
||||
{:ok, %Member{} = member} <- Actors.get_member(actor.id, group_id),
|
||||
{:only_administrator, false} <-
|
||||
{:only_administrator, check_that_member_is_not_last_administrator(group_id, actor_id)},
|
||||
|
||||
@@ -12,11 +12,11 @@ defmodule MobilizonWeb.Resolvers.Report do
|
||||
|
||||
def list_reports(
|
||||
_parent,
|
||||
%{page: page, limit: limit},
|
||||
%{page: page, limit: limit, status: status},
|
||||
%{context: %{current_user: %User{role: role}}}
|
||||
)
|
||||
when is_moderator(role) do
|
||||
{:ok, Mobilizon.Reports.list_reports(page, limit)}
|
||||
{:ok, Mobilizon.Reports.list_reports(page, limit, :updated_at, :desc, status)}
|
||||
end
|
||||
|
||||
def list_reports(_parent, _args, _resolution) do
|
||||
@@ -25,7 +25,13 @@ defmodule MobilizonWeb.Resolvers.Report do
|
||||
|
||||
def get_report(_parent, %{id: id}, %{context: %{current_user: %User{role: role}}})
|
||||
when is_moderator(role) do
|
||||
{:ok, Mobilizon.Reports.get_report(id)}
|
||||
case Mobilizon.Reports.get_report(id) do
|
||||
%Report{} = report ->
|
||||
{:ok, report}
|
||||
|
||||
nil ->
|
||||
{:error, "Report not found"}
|
||||
end
|
||||
end
|
||||
|
||||
def get_report(_parent, _args, _resolution) do
|
||||
|
||||
@@ -78,6 +78,9 @@ defmodule MobilizonWeb.Router do
|
||||
get("/events/create", PageController, :index)
|
||||
get("/events/list", PageController, :index)
|
||||
get("/events/:uuid/edit", PageController, :index)
|
||||
|
||||
# This is a hack to ease link generation into emails
|
||||
get("/moderation/reports/:id", PageController, :index, as: "moderation_report")
|
||||
end
|
||||
|
||||
scope "/", MobilizonWeb do
|
||||
|
||||
@@ -4,7 +4,7 @@ defmodule MobilizonWeb.Schema do
|
||||
"""
|
||||
use Absinthe.Schema
|
||||
|
||||
alias Mobilizon.{Actors, Events, Users, Addresses, Media}
|
||||
alias Mobilizon.{Actors, Events, Users, Addresses, Media, Reports}
|
||||
alias Mobilizon.Actors.{Actor, Follower, Member}
|
||||
alias Mobilizon.Events.{Event, Comment, Participant}
|
||||
alias Mobilizon.Storage.Repo
|
||||
@@ -27,7 +27,7 @@ defmodule MobilizonWeb.Schema do
|
||||
|
||||
@desc "A struct containing the id of the deleted object"
|
||||
object :deleted_object do
|
||||
field(:id, :integer)
|
||||
field(:id, :id)
|
||||
end
|
||||
|
||||
@desc "A JWT and the associated user ID"
|
||||
@@ -45,7 +45,7 @@ defmodule MobilizonWeb.Schema do
|
||||
Represents a notification for an user
|
||||
"""
|
||||
object :notification do
|
||||
field(:id, :integer, description: "The notification ID")
|
||||
field(:id, :id, description: "The notification ID")
|
||||
field(:user, :user, description: "The user to transmit the notification to")
|
||||
field(:actor, :actor, description: "The notification target profile")
|
||||
|
||||
@@ -98,6 +98,7 @@ defmodule MobilizonWeb.Schema do
|
||||
|> Dataloader.add_source(Events, default_source)
|
||||
|> Dataloader.add_source(Addresses, default_source)
|
||||
|> Dataloader.add_source(Media, default_source)
|
||||
|> Dataloader.add_source(Reports, default_source)
|
||||
|
||||
Map.put(ctx, :loader, loader)
|
||||
end
|
||||
|
||||
@@ -13,7 +13,7 @@ defmodule MobilizonWeb.Schema.ActorInterface do
|
||||
|
||||
@desc "An ActivityPub actor"
|
||||
interface :actor do
|
||||
field(:id, :integer, description: "Internal ID for this actor")
|
||||
field(:id, :id, description: "Internal ID for this actor")
|
||||
field(:url, :string, description: "The ActivityPub actor's URL")
|
||||
field(:type, :actor_type, description: "The type of Actor (Person, Group,…)")
|
||||
field(:name, :string, description: "The actor's displayed name")
|
||||
|
||||
@@ -14,7 +14,7 @@ defmodule MobilizonWeb.Schema.Actors.GroupType do
|
||||
object :group do
|
||||
interfaces([:actor])
|
||||
|
||||
field(:id, :integer, description: "Internal ID for this group")
|
||||
field(:id, :id, description: "Internal ID for this group")
|
||||
field(:url, :string, description: "The ActivityPub actor's URL")
|
||||
field(:type, :actor_type, description: "The type of Actor (Person, Group,…)")
|
||||
field(:name, :string, description: "The actor's displayed name")
|
||||
@@ -96,9 +96,7 @@ defmodule MobilizonWeb.Schema.Actors.GroupType do
|
||||
field :create_group, :group do
|
||||
arg(:preferred_username, non_null(:string), description: "The name for the group")
|
||||
|
||||
arg(:creator_actor_id, non_null(:integer),
|
||||
description: "The identity that creates the group"
|
||||
)
|
||||
arg(:creator_actor_id, non_null(:id), description: "The identity that creates the group")
|
||||
|
||||
arg(:name, :string, description: "The displayed name for the group")
|
||||
arg(:summary, :string, description: "The summary for the group", default_value: "")
|
||||
@@ -118,8 +116,8 @@ defmodule MobilizonWeb.Schema.Actors.GroupType do
|
||||
|
||||
@desc "Delete a group"
|
||||
field :delete_group, :deleted_object do
|
||||
arg(:group_id, non_null(:integer))
|
||||
arg(:actor_id, non_null(:integer))
|
||||
arg(:group_id, non_null(:id))
|
||||
arg(:actor_id, non_null(:id))
|
||||
|
||||
resolve(&Group.delete_group/3)
|
||||
end
|
||||
|
||||
@@ -24,16 +24,16 @@ defmodule MobilizonWeb.Schema.Actors.MemberType do
|
||||
object :member_mutations do
|
||||
@desc "Join a group"
|
||||
field :join_group, :member do
|
||||
arg(:group_id, non_null(:integer))
|
||||
arg(:actor_id, non_null(:integer))
|
||||
arg(:group_id, non_null(:id))
|
||||
arg(:actor_id, non_null(:id))
|
||||
|
||||
resolve(&Resolvers.Group.join_group/3)
|
||||
end
|
||||
|
||||
@desc "Leave an event"
|
||||
field :leave_group, :deleted_member do
|
||||
arg(:group_id, non_null(:integer))
|
||||
arg(:actor_id, non_null(:integer))
|
||||
arg(:group_id, non_null(:id))
|
||||
arg(:actor_id, non_null(:id))
|
||||
|
||||
resolve(&Resolvers.Group.leave_group/3)
|
||||
end
|
||||
|
||||
@@ -15,7 +15,7 @@ defmodule MobilizonWeb.Schema.Actors.PersonType do
|
||||
"""
|
||||
object :person do
|
||||
interfaces([:actor])
|
||||
field(:id, :integer, description: "Internal ID for this person")
|
||||
field(:id, :id, description: "Internal ID for this person")
|
||||
field(:user, :user, description: "The user this actor is associated to")
|
||||
|
||||
field(:member_of, list_of(:member), description: "The list of groups this person is member of")
|
||||
|
||||
@@ -15,7 +15,7 @@ defmodule MobilizonWeb.Schema.AddressType do
|
||||
field(:country, :string)
|
||||
field(:description, :string)
|
||||
field(:url, :string)
|
||||
field(:id, :integer)
|
||||
field(:id, :id)
|
||||
field(:origin_id, :string)
|
||||
end
|
||||
|
||||
@@ -40,7 +40,7 @@ defmodule MobilizonWeb.Schema.AddressType do
|
||||
field(:country, :string)
|
||||
field(:description, :string)
|
||||
field(:url, :string)
|
||||
field(:id, :integer)
|
||||
field(:id, :id)
|
||||
field(:origin_id, :string)
|
||||
end
|
||||
|
||||
|
||||
@@ -5,13 +5,25 @@ defmodule MobilizonWeb.Schema.AdminType do
|
||||
use Absinthe.Schema.Notation
|
||||
alias MobilizonWeb.Resolvers.Admin
|
||||
alias Mobilizon.Reports.{Report, Note}
|
||||
alias Mobilizon.Events.Event
|
||||
|
||||
@desc "An action log"
|
||||
object :action_log do
|
||||
field(:id, :id, description: "Internal ID for this comment")
|
||||
field(:actor, :actor, description: "The actor that acted")
|
||||
field(:object, :action_log_object, description: "The object that was acted upon")
|
||||
field(:action, :string, description: "The action that was done")
|
||||
field(:action, :action_log_action, description: "The action that was done")
|
||||
field(:inserted_at, :datetime, description: "The time when the action was performed")
|
||||
end
|
||||
|
||||
enum :action_log_action do
|
||||
value(:report_update_closed)
|
||||
value(:report_update_opened)
|
||||
value(:report_update_resolved)
|
||||
value(:note_creation)
|
||||
value(:note_deletion)
|
||||
value(:event_deletion)
|
||||
value(:event_update)
|
||||
end
|
||||
|
||||
@desc "The objects that can be in an action log"
|
||||
@@ -25,11 +37,22 @@ defmodule MobilizonWeb.Schema.AdminType do
|
||||
%Note{}, _ ->
|
||||
:report_note
|
||||
|
||||
%Event{}, _ ->
|
||||
:event
|
||||
|
||||
_, _ ->
|
||||
nil
|
||||
end)
|
||||
end
|
||||
|
||||
object :dashboard do
|
||||
field(:last_public_event_published, :event, description: "Last public event publish")
|
||||
field(:number_of_users, :integer, description: "The number of local users")
|
||||
field(:number_of_events, :integer, description: "The number of local events")
|
||||
field(:number_of_comments, :integer, description: "The number of local comments")
|
||||
field(:number_of_reports, :integer, description: "The number of current opened reports")
|
||||
end
|
||||
|
||||
object :admin_queries do
|
||||
@desc "Get the list of action logs"
|
||||
field :action_logs, type: list_of(:action_log) do
|
||||
@@ -37,5 +60,9 @@ defmodule MobilizonWeb.Schema.AdminType do
|
||||
arg(:limit, :integer, default_value: 10)
|
||||
resolve(&Admin.list_action_logs/3)
|
||||
end
|
||||
|
||||
field :dashboard, type: :dashboard do
|
||||
resolve(&Admin.get_dashboard/3)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -12,7 +12,8 @@ defmodule MobilizonWeb.Schema.EventType do
|
||||
|
||||
@desc "An event"
|
||||
object :event do
|
||||
field(:id, :integer, description: "Internal ID for this event")
|
||||
interfaces([:action_log_object])
|
||||
field(:id, :id, description: "Internal ID for this event")
|
||||
field(:uuid, :uuid, description: "The Event UUID")
|
||||
field(:url, :string, description: "The ActivityPub Event URL")
|
||||
field(:local, :boolean, description: "Whether the event is local or not")
|
||||
@@ -36,8 +37,8 @@ defmodule MobilizonWeb.Schema.EventType do
|
||||
description: "The type of the event's address"
|
||||
)
|
||||
|
||||
field(:online_address, :online_address, description: "Online address of the event")
|
||||
field(:phone_address, :phone_address, description: "Phone address for the event")
|
||||
field(:online_address, :string, description: "Online address of the event")
|
||||
field(:phone_address, :string, description: "Phone address for the event")
|
||||
|
||||
field(:organizer_actor, :actor,
|
||||
resolve: dataloader(Actors),
|
||||
@@ -53,6 +54,8 @@ defmodule MobilizonWeb.Schema.EventType do
|
||||
|
||||
field(:category, :string, description: "The event's category")
|
||||
|
||||
field(:participant_stats, :participant_stats, resolve: &Event.stats_participants_for_event/3)
|
||||
|
||||
field(:participants, list_of(:participant),
|
||||
resolve: &Event.list_participants_for_event/3,
|
||||
description: "The event's participants"
|
||||
@@ -91,6 +94,11 @@ defmodule MobilizonWeb.Schema.EventType do
|
||||
value(:cancelled, description: "The event is cancelled")
|
||||
end
|
||||
|
||||
object :participant_stats do
|
||||
field(:approved, :integer, description: "The number of approved participants")
|
||||
field(:unapproved, :integer, description: "The number of unapproved participants")
|
||||
end
|
||||
|
||||
object :event_offer do
|
||||
field(:price, :float, description: "The price amount for this offer")
|
||||
field(:price_currency, :string, description: "The currency for this price offer")
|
||||
@@ -208,9 +216,7 @@ defmodule MobilizonWeb.Schema.EventType do
|
||||
arg(:description, non_null(:string))
|
||||
arg(:begins_on, non_null(:datetime))
|
||||
arg(:ends_on, :datetime)
|
||||
arg(:state, :integer)
|
||||
arg(:status, :integer)
|
||||
arg(:public, :boolean)
|
||||
arg(:status, :event_status)
|
||||
arg(:visibility, :event_visibility, default_value: :private)
|
||||
|
||||
arg(:tags, list_of(:string),
|
||||
@@ -242,11 +248,8 @@ defmodule MobilizonWeb.Schema.EventType do
|
||||
arg(:description, :string)
|
||||
arg(:begins_on, :datetime)
|
||||
arg(:ends_on, :datetime)
|
||||
arg(:state, :integer)
|
||||
arg(:status, :integer)
|
||||
arg(:public, :boolean)
|
||||
arg(:status, :event_status)
|
||||
arg(:visibility, :event_visibility)
|
||||
arg(:organizer_actor_id, :id)
|
||||
|
||||
arg(:tags, list_of(:string), description: "The list of tags associated to the event")
|
||||
|
||||
@@ -255,7 +258,6 @@ defmodule MobilizonWeb.Schema.EventType do
|
||||
"The picture for the event, either as an object or directly the ID of an existing Picture"
|
||||
)
|
||||
|
||||
arg(:publish_at, :datetime)
|
||||
arg(:online_address, :string)
|
||||
arg(:phone_address, :string)
|
||||
arg(:category, :string)
|
||||
@@ -267,8 +269,8 @@ defmodule MobilizonWeb.Schema.EventType do
|
||||
|
||||
@desc "Delete an event"
|
||||
field :delete_event, :deleted_object do
|
||||
arg(:event_id, non_null(:integer))
|
||||
arg(:actor_id, non_null(:integer))
|
||||
arg(:event_id, non_null(:id))
|
||||
arg(:actor_id, non_null(:id))
|
||||
|
||||
resolve(&Event.delete_event/3)
|
||||
end
|
||||
|
||||
@@ -36,7 +36,7 @@ defmodule MobilizonWeb.Schema.Events.FeedTokenType do
|
||||
object :feed_token_mutations do
|
||||
@desc "Create a Feed Token"
|
||||
field :create_feed_token, :feed_token do
|
||||
arg(:actor_id, :integer)
|
||||
arg(:actor_id, :id)
|
||||
|
||||
resolve(&Resolvers.FeedToken.create_feed_token/3)
|
||||
end
|
||||
|
||||
@@ -46,16 +46,16 @@ defmodule MobilizonWeb.Schema.Events.ParticipantType do
|
||||
object :participant_mutations do
|
||||
@desc "Join an event"
|
||||
field :join_event, :participant do
|
||||
arg(:event_id, non_null(:integer))
|
||||
arg(:actor_id, non_null(:integer))
|
||||
arg(:event_id, non_null(:id))
|
||||
arg(:actor_id, non_null(:id))
|
||||
|
||||
resolve(&Resolvers.Event.actor_join_event/3)
|
||||
end
|
||||
|
||||
@desc "Leave an event"
|
||||
field :leave_event, :deleted_participant do
|
||||
arg(:event_id, non_null(:integer))
|
||||
arg(:actor_id, non_null(:integer))
|
||||
arg(:event_id, non_null(:id))
|
||||
arg(:actor_id, non_null(:id))
|
||||
|
||||
resolve(&Resolvers.Event.actor_leave_event/3)
|
||||
end
|
||||
|
||||
@@ -3,6 +3,8 @@ defmodule MobilizonWeb.Schema.ReportType do
|
||||
Schema representation for User
|
||||
"""
|
||||
use Absinthe.Schema.Notation
|
||||
import Absinthe.Resolution.Helpers, only: [dataloader: 1]
|
||||
alias Mobilizon.Reports
|
||||
|
||||
alias MobilizonWeb.Resolvers.Report
|
||||
|
||||
@@ -17,6 +19,14 @@ defmodule MobilizonWeb.Schema.ReportType do
|
||||
field(:reporter, :actor, description: "The actor that created the report")
|
||||
field(:event, :event, description: "The event that is being reported")
|
||||
field(:comments, list_of(:comment), description: "The comments that are reported")
|
||||
|
||||
field(:notes, list_of(:report_note),
|
||||
description: "The notes made on the event",
|
||||
resolve: dataloader(Reports)
|
||||
)
|
||||
|
||||
field(:inserted_at, :datetime, description: "When the report was created")
|
||||
field(:updated_at, :datetime, description: "When the report was updated")
|
||||
end
|
||||
|
||||
@desc "A report note object"
|
||||
@@ -24,8 +34,14 @@ defmodule MobilizonWeb.Schema.ReportType do
|
||||
interfaces([:action_log_object])
|
||||
field(:id, :id, description: "The internal ID of the report note")
|
||||
field(:content, :string, description: "The content of the note")
|
||||
field(:moderator, :actor, description: "The moderator who added the note")
|
||||
|
||||
field(:moderator, :actor,
|
||||
description: "The moderator who added the note",
|
||||
resolve: dataloader(Reports)
|
||||
)
|
||||
|
||||
field(:report, :report, description: "The report on which this note is added")
|
||||
field(:inserted_at, :datetime, description: "When the report note was created")
|
||||
end
|
||||
|
||||
@desc "The list of possible statuses for a report object"
|
||||
@@ -40,6 +56,7 @@ defmodule MobilizonWeb.Schema.ReportType do
|
||||
field :reports, list_of(:report) do
|
||||
arg(:page, :integer, default_value: 1)
|
||||
arg(:limit, :integer, default_value: 10)
|
||||
arg(:status, :report_status, default_value: :open)
|
||||
resolve(&Report.list_reports/3)
|
||||
end
|
||||
|
||||
@@ -53,7 +70,7 @@ defmodule MobilizonWeb.Schema.ReportType do
|
||||
object :report_mutations do
|
||||
@desc "Create a report"
|
||||
field :create_report, type: :report do
|
||||
arg(:report_content, :string)
|
||||
arg(:content, :string)
|
||||
arg(:reporter_actor_id, non_null(:id))
|
||||
arg(:reported_actor_id, non_null(:id))
|
||||
arg(:event_id, :id, default_value: nil)
|
||||
|
||||
@@ -43,6 +43,14 @@ defmodule MobilizonWeb.Schema.UserType do
|
||||
resolve: dataloader(Events),
|
||||
description: "A list of the feed tokens for this user"
|
||||
)
|
||||
|
||||
field(:role, :user_role, description: "The role for the user")
|
||||
end
|
||||
|
||||
enum :user_role do
|
||||
value(:administrator)
|
||||
value(:moderator)
|
||||
value(:user)
|
||||
end
|
||||
|
||||
@desc "Token"
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
<h1><%= gettext "New report from %{reporter} on %{instance}", reporter: @report.reporter, instance: @instance %></h1>
|
||||
<h1><%= gettext "New report from %{reporter} on %{instance}", reporter: @report.reporter.preferred_username, instance: @instance %></h1>
|
||||
|
||||
<% if @report.event do %>
|
||||
<p><%= gettext "Event: %{event}", event: @report.event %></p>
|
||||
<p><%= gettext "Event: %{event}", event: @report.event.title %></p>
|
||||
<% end %>
|
||||
|
||||
<%= for comment <- @report.comments do %>
|
||||
<p><%= gettext "Comment: %{comment}", comment: comment %></p>
|
||||
<% end %>
|
||||
|
||||
<% if @content do %>
|
||||
<% if @report.content do %>
|
||||
<p><%= gettext "Reason: %{content}", event: @report.content %></p>
|
||||
<% end %>
|
||||
|
||||
<p><%= link "View the report", to: MobilizonWeb.Endpoint.url() <> "/reports/#{@report.id}", target: "_blank" %></p>
|
||||
<p><%= link "View the report", to: moderation_report_url(MobilizonWeb.Endpoint, :index, @report.id), target: "_blank" %></p>
|
||||
@@ -1,19 +1,19 @@
|
||||
<%= gettext "New report from %{reporter} on %{instance}", reporter: @report.reporter, instance: @instance %>
|
||||
<%= gettext "New report from %{reporter} on %{instance}", reporter: @report.reporter.preferred_username, instance: @instance %>
|
||||
|
||||
--
|
||||
|
||||
<% if @report.event do %>
|
||||
<%= gettext "Event: %{event}", event: @report.event %>
|
||||
<%= gettext "Event: %{event}", event: @report.event.title %>
|
||||
<% end %>
|
||||
|
||||
<%= for comment <- @report.comments do %>
|
||||
<%= gettext "Comment: %{comment}", comment: comment %>
|
||||
<%= gettext "Comment: %{comment}", comment: comment.text %>
|
||||
<% end %>
|
||||
|
||||
<% if @content do %>
|
||||
<% if @report.content do %>
|
||||
<%= gettext "Reason: %{content}", event: @report.content %>
|
||||
<% end %>
|
||||
|
||||
<%= link "View the report", to: MobilizonWeb.Endpoint.url() <> "/reports/#{@report.id}", target: "_blank" %>
|
||||
View the report: <%= moderation_report_url(MobilizonWeb.Endpoint, :index, @report.id) %>
|
||||
|
||||
|
||||
|
||||
@@ -357,9 +357,8 @@ defmodule Mobilizon.Service.ActivityPub do
|
||||
|
||||
with {:ok, _} <- Events.delete_event(event),
|
||||
{:ok, activity} <- create_activity(data, local),
|
||||
{:ok, object} <- insert_full_object(data),
|
||||
:ok <- maybe_federate(activity) do
|
||||
{:ok, activity, object}
|
||||
{:ok, activity, event}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -542,7 +541,7 @@ defmodule Mobilizon.Service.ActivityPub do
|
||||
|
||||
public = is_public?(activity)
|
||||
|
||||
if public && Config.get([:instance, :allow_relay]) do
|
||||
if public && !is_delete_activity?(activity) && Config.get([:instance, :allow_relay]) do
|
||||
Logger.info(fn -> "Relaying #{activity.data["id"]} out" end)
|
||||
Mobilizon.Service.ActivityPub.Relay.publish(activity)
|
||||
end
|
||||
@@ -573,6 +572,9 @@ defmodule Mobilizon.Service.ActivityPub do
|
||||
end)
|
||||
end
|
||||
|
||||
defp is_delete_activity?(%Activity{data: %{"type" => "Delete"}}), do: true
|
||||
defp is_delete_activity?(_), do: false
|
||||
|
||||
@doc """
|
||||
Publish an activity to a specific inbox
|
||||
"""
|
||||
|
||||
@@ -165,14 +165,14 @@ defmodule Mobilizon.Service.ActivityPub.Utils do
|
||||
{:ok, %Report{} = report} <- Reports.create_report(data) do
|
||||
Enum.each(Users.list_moderators(), fn moderator ->
|
||||
moderator
|
||||
|> Email.Admin.report(moderator, report)
|
||||
|> Email.Admin.report(report)
|
||||
|> Email.Mailer.deliver_later()
|
||||
end)
|
||||
|
||||
{:ok, report}
|
||||
else
|
||||
err ->
|
||||
Logger.error("Error while inserting a remote comment inside database")
|
||||
Logger.error("Error while inserting report inside database")
|
||||
Logger.debug(inspect(err))
|
||||
{:error, err}
|
||||
end
|
||||
|
||||
@@ -22,9 +22,19 @@ defmodule Mobilizon.Service.Admin.ActionLogService do
|
||||
"target_type" => to_string(target.__struct__),
|
||||
"target_id" => target.id,
|
||||
"action" => action,
|
||||
"changes" => Map.from_struct(target) |> Map.take([:status, :uri, :content])
|
||||
"changes" => stringify_struct(target)
|
||||
}) do
|
||||
{:ok, create_action_log}
|
||||
end
|
||||
end
|
||||
|
||||
defp stringify_struct(%_{} = struct) do
|
||||
association_fields = struct.__struct__.__schema__(:associations)
|
||||
|
||||
struct
|
||||
|> Map.from_struct()
|
||||
|> Map.drop(association_fields ++ [:__meta__])
|
||||
end
|
||||
|
||||
defp stringify_struct(struct), do: struct
|
||||
end
|
||||
|
||||
31
lib/service/statistics.ex
Normal file
31
lib/service/statistics.ex
Normal file
@@ -0,0 +1,31 @@
|
||||
defmodule Mobilizon.Service.Statistics do
|
||||
@moduledoc """
|
||||
A module that provides cached statistics
|
||||
"""
|
||||
alias Mobilizon.Events
|
||||
alias Mobilizon.Users
|
||||
|
||||
def get_cached_value(key) do
|
||||
case Cachex.fetch(:statistics, key, fn key ->
|
||||
case create_cache(key) do
|
||||
value when not is_nil(value) -> {:commit, value}
|
||||
err -> {:ignore, err}
|
||||
end
|
||||
end) do
|
||||
{status, value} when status in [:ok, :commit] -> value
|
||||
_err -> nil
|
||||
end
|
||||
end
|
||||
|
||||
defp create_cache(:local_users) do
|
||||
Users.count_users()
|
||||
end
|
||||
|
||||
defp create_cache(:local_events) do
|
||||
Events.count_local_events()
|
||||
end
|
||||
|
||||
defp create_cache(:local_comments) do
|
||||
Events.count_local_comments()
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user