Skip to content

Commit 37169eb

Browse files
authored
Merge pull request #44 from epochtalk/moderation-log
Moderation Log
2 parents a9cb354 + 7aee216 commit 37169eb

File tree

11 files changed

+3601
-23
lines changed

11 files changed

+3601
-23
lines changed
Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
defmodule EpochtalkServer.Models.ModerationLog do
2+
use Ecto.Schema
3+
import Ecto.Changeset
4+
import Ecto.Query
5+
alias EpochtalkServer.Models.ModerationLog
6+
alias EpochtalkServerWeb.Helpers.ModerationLogHelper
7+
alias EpochtalkServerWeb.Helpers.Pagination
8+
alias EpochtalkServerWeb.Helpers.QueryHelper
9+
alias EpochtalkServer.Repo
10+
11+
@moduledoc """
12+
`ModerationLog` model, for performing actions relating to the moderation log
13+
"""
14+
@type t :: %__MODULE__{
15+
mod_username: String.t() | nil,
16+
mod_id: non_neg_integer | nil,
17+
mod_ip: String.t() | nil,
18+
action_api_url: String.t() | nil,
19+
action_api_method: String.t() | nil,
20+
action_obj: map() | nil,
21+
action_taken_at: NaiveDateTime.t() | nil,
22+
action_type: String.t() | nil,
23+
action_display_text: String.t() | nil,
24+
action_display_url: String.t() | nil
25+
}
26+
@primary_key false
27+
@derive {Jason.Encoder,
28+
only: [
29+
:mod_username,
30+
:mod_id,
31+
:mod_ip,
32+
:action_api_url,
33+
:action_api_method,
34+
:action_obj,
35+
:action_taken_at,
36+
:action_type,
37+
:action_display_text,
38+
:action_display_url
39+
]}
40+
schema "moderation_log" do
41+
field :mod_username, :string
42+
field :mod_id, :integer
43+
field :mod_ip, :string
44+
field :action_api_url, :string
45+
field :action_api_method, :string
46+
field :action_obj, :map
47+
field :action_taken_at, :naive_datetime
48+
field :action_type, :string
49+
field :action_display_text, :string
50+
field :action_display_url, :string
51+
end
52+
53+
## === Changesets Functions ===
54+
55+
@doc """
56+
Create generic changeset for `ModerationLog` model
57+
"""
58+
@spec create_changeset(moderation_log :: t(), attrs :: map() | nil) :: Ecto.Changeset.t()
59+
def create_changeset(moderation_log, attrs) do
60+
now = NaiveDateTime.truncate(NaiveDateTime.utc_now(), :second)
61+
62+
display_data = ModerationLogHelper.get_display_data(get_in(attrs, [:action, :type]))
63+
64+
action_obj =
65+
if Map.has_key?(display_data, :data_query) do
66+
display_data.data_query.(get_in(attrs, [:action, :obj]))
67+
else
68+
get_in(attrs, [:action, :obj])
69+
end
70+
71+
attrs =
72+
attrs
73+
|> Map.put(:action_taken_at, now)
74+
|> Map.put(:mod_username, get_in(attrs, [:mod, :username]))
75+
|> Map.put(:mod_id, get_in(attrs, [:mod, :id]))
76+
|> Map.put(:mod_ip, get_in(attrs, [:mod, :ip]))
77+
|> Map.put(:action_api_url, get_in(attrs, [:action, :api_url]))
78+
|> Map.put(:action_api_method, get_in(attrs, [:action, :api_method]))
79+
|> Map.put(:action_obj, get_in(attrs, [:action, :obj]))
80+
|> Map.put(:action_type, get_in(attrs, [:action, :type]))
81+
|> Map.put(:action_display_text, display_data.get_display_text.(action_obj))
82+
|> Map.put(:action_display_url, display_data.get_display_url.(action_obj))
83+
84+
moderation_log
85+
|> cast(attrs, [
86+
:mod_username,
87+
:mod_id,
88+
:mod_ip,
89+
:action_api_url,
90+
:action_api_method,
91+
:action_obj,
92+
:action_taken_at,
93+
:action_type,
94+
:action_display_text,
95+
:action_display_url
96+
])
97+
end
98+
99+
## === Database Functions ===
100+
101+
@doc """
102+
Creates a new `ModerationLog` in the database
103+
"""
104+
@spec create(attrs :: map()) :: {:ok, moderation_log :: t()} | {:error, Ecto.Changeset.t()}
105+
def create(attrs) do
106+
moderation_log_cs = ModerationLog.create_changeset(%ModerationLog{}, attrs)
107+
108+
case Repo.insert(moderation_log_cs) do
109+
{:ok, moderation_log} ->
110+
{:ok, moderation_log}
111+
112+
# changeset error
113+
{:error, err} ->
114+
{:error, err}
115+
end
116+
end
117+
118+
@doc """
119+
Page `ModerationLog` models
120+
"""
121+
@spec page(attrs :: map(), page :: non_neg_integer, per_page: non_neg_integer) ::
122+
{:ok, moderation_logs :: [t()] | [], pagination_data :: map()}
123+
def page(attrs, page \\ 1, opts \\ []) do
124+
from(ModerationLog)
125+
|> where(^filter_where(attrs))
126+
|> Pagination.page_simple(page, per_page: opts[:per_page])
127+
end
128+
129+
defp filter_where(attrs) do
130+
Enum.reduce(attrs, dynamic(true), fn
131+
{"mod", mod}, dynamic ->
132+
filter_mod(mod, dynamic)
133+
134+
{"action", action}, dynamic ->
135+
QueryHelper.build_and(dynamic, :action_type, action)
136+
137+
{"keyword", keyword}, dynamic ->
138+
like = "%#{keyword}%"
139+
QueryHelper.build_and(dynamic, :action_display_text, %{"like" => like})
140+
141+
{"bdate", bdate}, dynamic ->
142+
{:ok, bdate} = NaiveDateTime.from_iso8601(bdate <> " 00:00:00")
143+
QueryHelper.build_and(dynamic, :action_taken_at, %{"<" => bdate})
144+
145+
{"adate", adate}, dynamic ->
146+
{:ok, adate} = NaiveDateTime.from_iso8601(adate <> " 00:00:00")
147+
QueryHelper.build_and(dynamic, :action_taken_at, %{">" => adate})
148+
149+
{"sdate", sdate}, dynamic ->
150+
{:ok, sdate} = NaiveDateTime.from_iso8601(sdate <> " 00:00:00")
151+
QueryHelper.build_and(dynamic, :action_taken_at, %{">" => sdate})
152+
153+
{"edate", edate}, dynamic ->
154+
{:ok, edate} = NaiveDateTime.from_iso8601(edate <> " 00:00:00")
155+
QueryHelper.build_and(dynamic, :action_taken_at, %{"<" => edate})
156+
157+
{_, _}, dynamic ->
158+
# Not a where parameter
159+
dynamic
160+
end)
161+
end
162+
163+
defp filter_mod(mod, dynamic) do
164+
like = "%#{mod}%"
165+
166+
case Integer.parse(mod) do
167+
{_, ""} ->
168+
QueryHelper.build_and(dynamic, :mod_id, mod)
169+
170+
_ ->
171+
dynamic = QueryHelper.build_and(dynamic, :mod_username, %{"like" => like})
172+
QueryHelper.build_or(dynamic, :mod_ip, %{"like" => like})
173+
end
174+
end
175+
end
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
defmodule EpochtalkServerWeb.ModerationLogController do
2+
use EpochtalkServerWeb, :controller
3+
4+
@moduledoc """
5+
Controller For `ModerationLog` related API requests
6+
"""
7+
alias EpochtalkServer.Auth.Guardian
8+
alias EpochtalkServer.Models.ModerationLog
9+
alias EpochtalkServerWeb.ErrorHelpers
10+
alias EpochtalkServerWeb.Helpers.Validate
11+
12+
@doc """
13+
Used to page `ModerationLog` models for moderation log view`
14+
"""
15+
def page(conn, attrs) do
16+
with {:auth, true} <- {:auth, Guardian.Plug.authenticated?(conn)},
17+
page <- Validate.cast(attrs, "page", :integer, min: 1),
18+
limit <- Validate.cast(attrs, "limit", :integer, min: 1),
19+
{:ok, moderation_logs, data} <- ModerationLog.page(attrs, page, per_page: limit) do
20+
render(conn, "page.json", moderation_logs: moderation_logs, pagination_data: data)
21+
else
22+
{:auth, false} ->
23+
ErrorHelpers.render_json_error(conn, 400, "Not logged in, cannot page moderation log")
24+
25+
{:error, data} ->
26+
ErrorHelpers.render_json_error(conn, 400, data)
27+
28+
_ ->
29+
ErrorHelpers.render_json_error(conn, 500, "There was an issue getting the moderation log")
30+
end
31+
end
32+
end

0 commit comments

Comments
 (0)