diff --git a/lib/mix/tasks/reindex_all.ex b/lib/mix/tasks/reindex_all.ex new file mode 100644 index 00000000..9ed4c10e --- /dev/null +++ b/lib/mix/tasks/reindex_all.ex @@ -0,0 +1,36 @@ +defmodule Mix.Tasks.ReindexAll do + use Mix.Task + + alias Philomena.{Comments.Comment, Galleries.Gallery, Posts.Post, Images.Image, Reports.Report, Tags.Tag} + alias Philomena.{Comments, Galleries, Posts, Images, Tags} + alias Philomena.Polymorphic + alias Philomena.Repo + import Ecto.Query + + @shortdoc "Destroys and recreates all Elasticsearch indices." + def run(_) do + if Mix.env == "prod" do + raise "do not run this task in production" + end + + {:ok, _apps} = Application.ensure_all_started(:philomena) + + for {context, schema} <- [{Images, Image}, {Comments, Comment}, {Galleries, Gallery}, {Tags, Tag}, {Posts, Post}] do + schema.delete_index! + schema.create_index! + + schema.reindex(schema |> preload(^context.indexing_preloads())) + end + + # Reports are a bit special + + Report.delete_index! + Report.create_index! + + Report + |> preload([:user, :admin]) + |> Repo.all() + |> Polymorphic.load_polymorphic(reportable: [reportable_id: :reportable_type]) + |> Enum.map(&Report.index_document/1) + end +end \ No newline at end of file diff --git a/lib/philomena/reports.ex b/lib/philomena/reports.ex index d7e14102..5775c64b 100644 --- a/lib/philomena/reports.ex +++ b/lib/philomena/reports.ex @@ -103,6 +103,24 @@ defmodule Philomena.Reports do Report.changeset(report, %{}) end + def claim_report(%Report{} = report, user) do + report + |> Report.claim_changeset(user) + |> Repo.update() + end + + def unclaim_report(%Report{} = report) do + report + |> Report.unclaim_changeset() + |> Repo.update() + end + + def close_report(%Report{} = report, user) do + report + |> Report.close_changeset(user) + |> Repo.update() + end + def reindex_report(%Report{} = report) do spawn fn -> Report diff --git a/lib/philomena/reports/report.ex b/lib/philomena/reports/report.ex index b95334e2..8199f441 100644 --- a/lib/philomena/reports/report.ex +++ b/lib/philomena/reports/report.ex @@ -38,6 +38,28 @@ defmodule Philomena.Reports.Report do |> validate_required([]) end + # Ensure that the report is not currently claimed before + # attempting to claim + def claim_changeset(report, user) do + change(report) + |> validate_inclusion(:admin_id, []) + |> put_change(:admin_id, user.id) + |> put_change(:state, "in_progress") + end + + def unclaim_changeset(report) do + change(report) + |> put_change(:admin_id, nil) + |> put_change(:state, "open") + end + + def close_changeset(report, user) do + change(report) + |> put_change(:admin_id, user.id) + |> put_change(:open, false) + |> put_change(:state, "closed") + end + @doc false def creation_changeset(report, attrs, attribution) do report diff --git a/lib/philomena_web/controllers/admin/report/claim_controller.ex b/lib/philomena_web/controllers/admin/report/claim_controller.ex new file mode 100644 index 00000000..3ef4d4ac --- /dev/null +++ b/lib/philomena_web/controllers/admin/report/claim_controller.ex @@ -0,0 +1,34 @@ +defmodule PhilomenaWeb.Admin.Report.ClaimController do + use PhilomenaWeb, :controller + + alias Philomena.Reports.Report + alias Philomena.Reports + + plug PhilomenaWeb.CanaryMapPlug, create: :edit, delete: :edit + plug :load_and_authorize_resource, model: Report, id_name: "report_id", persisted: true + + def create(conn, _params) do + case Reports.claim_report(conn.assigns.report, conn.assigns.current_user) do + {:ok, report} -> + Reports.reindex_report(report) + + conn + |> put_flash(:info, "Successfully marked report as in progress") + |> redirect(to: Routes.admin_report_path(conn, :show, report)) + + {:error, _changeset} -> + conn + |> put_flash(:error, "Couldn't claim that report!") + |> redirect(to: Routes.admin_report_path(conn, :show, conn.assigns.report)) + end + end + + def delete(conn, _params) do + {:ok, report} = Reports.unclaim_report(conn.assigns.report) + Reports.reindex_report(report) + + conn + |> put_flash(:info, "Successfully released report.") + |> redirect(to: Routes.admin_report_path(conn, :show, report)) + end +end \ No newline at end of file diff --git a/lib/philomena_web/controllers/admin/report/close_controller.ex b/lib/philomena_web/controllers/admin/report/close_controller.ex new file mode 100644 index 00000000..1558431c --- /dev/null +++ b/lib/philomena_web/controllers/admin/report/close_controller.ex @@ -0,0 +1,18 @@ +defmodule PhilomenaWeb.Admin.Report.CloseController do + use PhilomenaWeb, :controller + + alias Philomena.Reports.Report + alias Philomena.Reports + + plug PhilomenaWeb.CanaryMapPlug, create: :edit, delete: :edit + plug :load_and_authorize_resource, model: Report, id_name: "report_id", persisted: true + + def create(conn, _params) do + {:ok, report} = Reports.close_report(conn.assigns.report, conn.assigns.current_user) + Reports.reindex_report(report) + + conn + |> put_flash(:info, "Successfully closed report") + |> redirect(to: Routes.admin_report_path(conn, :index)) + end +end \ No newline at end of file diff --git a/lib/philomena_web/router.ex b/lib/philomena_web/router.ex index 32653f10..f75b74cd 100644 --- a/lib/philomena_web/router.ex +++ b/lib/philomena_web/router.ex @@ -168,7 +168,10 @@ defmodule PhilomenaWeb.Router do resources "/fingerprint_profiles", FingerprintProfileController, only: [:show] scope "/admin", Admin, as: :admin do - resources "/reports", ReportController, only: [:index, :show] + resources "/reports", ReportController, only: [:index, :show] do + resources "/claim", Report.ClaimController, only: [:create, :delete], singleton: true + resources "/close", Report.CloseController, only: [:create], singleton: true + end end end diff --git a/lib/philomena_web/templates/admin/report/_reports.html.slime b/lib/philomena_web/templates/admin/report/_reports.html.slime index 853620a6..f43f531a 100644 --- a/lib/philomena_web/templates/admin/report/_reports.html.slime +++ b/lib/philomena_web/templates/admin/report/_reports.html.slime @@ -34,19 +34,20 @@ table.table => pretty_state(report) = user_abbrv @conn, report.admin td - = link "Show", to: Routes.admin_report_path(@conn, :show, report) - /- if report.open - - if report.user - ' • - = link_to 'Send PM', new_conversation_path(title: "Your Report of #{reported_thing(report.reportable)}", recipient: report.user.name) - - if report.admin != current_user - ' • - - if report.admin.present? - = link_to 'Claim', admin_report_claim_path(report), method: :post, data: { confirm: t('admin.reports.change_owner') } - - else - = link_to 'Claim', admin_report_claim_path(report), method: :post - - if report.admin == current_user - ' • - = link_to 'Release', admin_report_claim_path(report), method: :delete - ' • - = link_to t('close'), admin_report_close_path(report), data: { confirm: t('are_you_sure') }, method: :post + => link "Show", to: Routes.admin_report_path(@conn, :show, report) + + = if report.open do + = if report.user do + ' • + => link "Send PM", to: Routes.conversation_path(@conn, :new, recipient: report.user.name) + + = if is_nil(report.admin) and not current?(report.admin, @conn.assigns.current_user) do + ' • + => link "Claim", to: Routes.admin_report_claim_path(@conn, :create, report), data: [method: "post"] + + = if current?(report.admin, @conn.assigns.current_user) do + ' • + => link "Release", to: Routes.admin_report_claim_path(@conn, :delete, report), data: [method: "delete"] + + ' • + => link "Close", to: Routes.admin_report_close_path(@conn, :create, report), data: [method: "post", confirm: "Are you really, really sure?"]