diff --git a/lib/philomena/duplicate_reports.ex b/lib/philomena/duplicate_reports.ex index 55b468ce..798ba04c 100644 --- a/lib/philomena/duplicate_reports.ex +++ b/lib/philomena/duplicate_reports.ex @@ -4,6 +4,7 @@ defmodule Philomena.DuplicateReports do """ import Ecto.Query, warn: false + alias Ecto.Multi alias Philomena.Repo alias Philomena.DuplicateReports.DuplicateReport @@ -71,19 +72,34 @@ defmodule Philomena.DuplicateReports do # TODO: can we get this in a single transaction? def accept_duplicate_report(%DuplicateReport{} = duplicate_report, user) do - result = + changeset = duplicate_report |> DuplicateReport.accept_changeset(user) - |> Repo.update() - case result do - {:ok, duplicate_report} -> + Multi.new() + |> Multi.update(:duplicate_report, changeset) + |> Multi.run(:other_reports, fn repo, %{duplicate_report: duplicate_report} -> + {count, nil} = + DuplicateReport + |> where( + [dr], + (dr.image_id == ^duplicate_report.image_id and dr.duplicate_of_image_id == ^duplicate_report.duplicate_of_image_id) or + (dr.image_id == ^duplicate_report.duplicate_of_image_id and dr.duplicate_of_image_id == ^duplicate_report.image_id) + ) + |> where([dr], dr.id != ^duplicate_report.id) + |> repo.update_all(set: [state: "rejected"]) + + {:ok, count} + end) + |> Repo.isolated_transaction(:serializable) + |> case do + {:ok, %{duplicate_report: duplicate_report}} -> duplicate_report = Repo.preload(duplicate_report, [:image, :duplicate_of_image]) Images.merge_image(duplicate_report.image, duplicate_report.duplicate_of_image) - _error -> - result + error -> + error end end diff --git a/lib/philomena/images.ex b/lib/philomena/images.ex index 9d8bcd53..eb529172 100644 --- a/lib/philomena/images.ex +++ b/lib/philomena/images.ex @@ -261,21 +261,29 @@ defmodule Philomena.Images do {:ok, count} end) - |> Multi.run(:added_tag_count, fn repo, %{image: {_image, added_tags, _removed}} -> - tag_ids = added_tags |> Enum.map(& &1.id) - tags = Tag |> where([t], t.id in ^tag_ids) + |> Multi.run(:added_tag_count, fn + _repo, %{image: {%{hidden_from_users: true}, _added, _removed}} -> + {:ok, 0} - {count, nil} = repo.update_all(tags, inc: [images_count: 1]) + repo, %{image: {_image, added_tags, _removed}} -> + tag_ids = added_tags |> Enum.map(& &1.id) + tags = Tag |> where([t], t.id in ^tag_ids) - {:ok, count} + {count, nil} = repo.update_all(tags, inc: [images_count: 1]) + + {:ok, count} end) - |> Multi.run(:removed_tag_count, fn repo, %{image: {_image, _added, removed_tags}} -> - tag_ids = removed_tags |> Enum.map(& &1.id) - tags = Tag |> where([t], t.id in ^tag_ids) + |> Multi.run(:removed_tag_count, fn + _repo, %{image: {%{hidden_from_users: true}, _added, _removed}} -> + {:ok, 0} - {count, nil} = repo.update_all(tags, inc: [images_count: -1]) + repo, %{image: {_image, _added, removed_tags}} -> + tag_ids = removed_tags |> Enum.map(& &1.id) + tags = Tag |> where([t], t.id in ^tag_ids) - {:ok, count} + {count, nil} = repo.update_all(tags, inc: [images_count: -1]) + + {:ok, count} end) |> Repo.isolated_transaction(:serializable) end @@ -388,6 +396,12 @@ defmodule Philomena.Images do def unhide_image(image), do: {:ok, image} def batch_update(image_ids, added_tags, removed_tags, tag_change_attributes) do + image_ids = + Image + |> where([i], i.id in ^image_ids and i.hidden_from_users == false) + |> select([i], i.id) + |> Repo.all() + added_tags = Enum.map(added_tags, & &1.id) removed_tags = Enum.map(removed_tags, & &1.id) diff --git a/lib/philomena/users/ability.ex b/lib/philomena/users/ability.ex index 691d8ea7..2337dd48 100644 --- a/lib/philomena/users/ability.ex +++ b/lib/philomena/users/ability.ex @@ -43,9 +43,8 @@ defimpl Canada.Can, for: [Atom, Philomena.Users.User] do def can?(%User{role: "moderator"}, :show, %Filter{}), do: true # Manage images - def can?(%User{role: "moderator"}, :show, %Image{}), do: true - def can?(%User{role: "moderator"}, :hide, %Image{}), do: true - def can?(%User{role: "moderator"}, :edit_description, %Image{}), do: true + def can?(%User{role: "moderator"}, _action, Image), do: true + def can?(%User{role: "moderator"}, _action, %Image{}), do: true # View comments def can?(%User{role: "moderator"}, :show, %Comment{}), do: true