|
| 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 |
0 commit comments