From d7f5cbcb77d9e5ebe918933e100921735cfe9429 Mon Sep 17 00:00:00 2001 From: "byte[]" Date: Thu, 28 May 2020 20:35:52 -0400 Subject: [PATCH] fixes #124, uploads not blocked for DNP --- lib/philomena/images.ex | 1 + lib/philomena/images/dnp_validator.ex | 72 +++++++++++++++++++ lib/philomena/images/image.ex | 7 ++ lib/philomena/processors/svg.ex | 7 +- .../controllers/gallery_controller.ex | 3 +- .../controllers/image/random_controller.ex | 3 +- lib/philomena_web/image_navigator.ex | 3 +- lib/philomena_web/image_sorter.ex | 2 +- .../templates/image/new.html.slime | 1 + 9 files changed, 91 insertions(+), 8 deletions(-) create mode 100644 lib/philomena/images/dnp_validator.ex diff --git a/lib/philomena/images.ex b/lib/philomena/images.ex index 32327400..403608fb 100644 --- a/lib/philomena/images.ex +++ b/lib/philomena/images.ex @@ -64,6 +64,7 @@ defmodule Philomena.Images do %Image{} |> Image.creation_changeset(attrs, attribution) |> Image.tag_changeset(attrs, [], tags) + |> Image.dnp_changeset(attribution[:user]) |> Uploader.analyze_upload(attrs) Multi.new() diff --git a/lib/philomena/images/dnp_validator.ex b/lib/philomena/images/dnp_validator.ex new file mode 100644 index 00000000..8e7b0333 --- /dev/null +++ b/lib/philomena/images/dnp_validator.ex @@ -0,0 +1,72 @@ +defmodule Philomena.Images.DnpValidator do + import Ecto.Changeset + import Ecto.Query + alias Philomena.Repo + alias Philomena.Tags.Tag + + def validate_dnp(changeset, uploader) do + tags = + changeset + |> get_field(:tags) + |> extract_tags() + + edit_present? = MapSet.member?(tags, "edit") + + tags_with_dnp = + Tag + |> where([t], t.name in ^extract_artists(tags)) + |> preload(dnp_entries: :requesting_user) + |> Repo.all() + |> Enum.filter(&(length(&1.dnp_entries) > 0)) + + changeset + |> validate_artist_only(tags_with_dnp, uploader) + |> validate_no_edits(tags_with_dnp, uploader, edit_present?) + end + + defp validate_artist_only(changeset, tags_with_dnp, uploader) do + Enum.reduce(tags_with_dnp, changeset, fn tag, changeset -> + case Enum.any?( + tag.dnp_entries, + &(&1.dnp_type == "Artist Upload Only" and + not same_user?(&1.requesting_user, uploader)) + ) do + true -> + add_error(changeset, :image, "DNP (Artist upload only)") + + false -> + changeset + end + end) + end + + defp validate_no_edits(changeset, _tags_with_dnp, _uploader, false), do: changeset + + defp validate_no_edits(changeset, tags_with_dnp, uploader, true) do + Enum.reduce(tags_with_dnp, changeset, fn tag, changeset -> + case Enum.any?( + tag.dnp_entries, + &(&1.dnp_type == "No Edits" and not same_user?(&1.requesting_user, uploader)) + ) do + true -> + add_error(changeset, :image, "DNP (No edits)") + + false -> + changeset + end + end) + end + + defp same_user?(%{id: id}, %{id: id}), do: true + defp same_user?(_user1, _user2), do: false + + defp extract_tags(tags) do + tags + |> Enum.map(& &1.name) + |> MapSet.new() + end + + defp extract_artists(tags) do + Enum.filter(tags, &String.starts_with?(&1, "artist:")) + end +end diff --git a/lib/philomena/images/image.ex b/lib/philomena/images/image.ex index 484d5a73..2a37b2d2 100644 --- a/lib/philomena/images/image.ex +++ b/lib/philomena/images/image.ex @@ -18,6 +18,7 @@ defmodule Philomena.Images.Image do alias Philomena.Images.TagDiffer alias Philomena.Images.TagValidator + alias Philomena.Images.DnpValidator alias Philomena.Repo schema "images" do @@ -176,6 +177,12 @@ defmodule Philomena.Images.Image do |> cache_changeset() end + def dnp_changeset(image, user) do + image + |> change() + |> DnpValidator.validate_dnp(user) + end + def thumbnail_changeset(image, attrs) do image |> cast(attrs, [:image_sha512_hash, :image_size]) diff --git a/lib/philomena/processors/svg.ex b/lib/philomena/processors/svg.ex index 663c0519..0a16d795 100644 --- a/lib/philomena/processors/svg.ex +++ b/lib/philomena/processors/svg.ex @@ -33,7 +33,12 @@ defmodule Philomena.Processors.Svg do [{:symlink_original, "full.svg"}, {:copy, preview, "full.png"}] end - defp scale_if_smaller(_file, {width, height}, preview, {thumb_name, {target_width, target_height}}) do + defp scale_if_smaller( + _file, + {width, height}, + preview, + {thumb_name, {target_width, target_height}} + ) do if width > target_width or height > target_height do scaled = scale(preview, {target_width, target_height}) diff --git a/lib/philomena_web/controllers/gallery_controller.ex b/lib/philomena_web/controllers/gallery_controller.ex index 36f2f399..fef4064f 100644 --- a/lib/philomena_web/controllers/gallery_controller.ex +++ b/lib/philomena_web/controllers/gallery_controller.ex @@ -161,8 +161,7 @@ defmodule PhilomenaWeb.GalleryController do defp gallery_image(offset, conn, query) do pagination_params = %{page_number: offset + 1, page_size: 1} - {:ok, {image, _tags}} = - ImageLoader.search_string(conn, query, pagination: pagination_params) + {:ok, {image, _tags}} = ImageLoader.search_string(conn, query, pagination: pagination_params) case Enum.to_list(image) do [image] -> image diff --git a/lib/philomena_web/controllers/image/random_controller.ex b/lib/philomena_web/controllers/image/random_controller.ex index 153078b7..f7668bcc 100644 --- a/lib/philomena_web/controllers/image/random_controller.ex +++ b/lib/philomena_web/controllers/image/random_controller.ex @@ -31,8 +31,7 @@ defmodule PhilomenaWeb.Image.RandomController do defp query(_user, _), do: %{match_all: %{}} defp random_image_id(query, filter) do - %{query: query, sorts: sort} = - ImageSorter.parse_sort(%{"sf" => "random"}, query) + %{query: query, sorts: sort} = ImageSorter.parse_sort(%{"sf" => "random"}, query) Elasticsearch.search_records( Image, diff --git a/lib/philomena_web/image_navigator.ex b/lib/philomena_web/image_navigator.ex index 8276af60..4a7dd105 100644 --- a/lib/philomena_web/image_navigator.ex +++ b/lib/philomena_web/image_navigator.ex @@ -33,8 +33,7 @@ defmodule PhilomenaWeb.ImageNavigator do |> Map.merge(empty_fields()) |> ElasticsearchIndex.as_json() - %{query: compiled_query, sorts: sort} = - ImageSorter.parse_sort(params, compiled_query) + %{query: compiled_query, sorts: sort} = ImageSorter.parse_sort(params, compiled_query) {sorts, filters} = sort diff --git a/lib/philomena_web/image_sorter.ex b/lib/philomena_web/image_sorter.ex index 648f705e..a58a9def 100644 --- a/lib/philomena_web/image_sorter.ex +++ b/lib/philomena_web/image_sorter.ex @@ -64,7 +64,7 @@ defmodule PhilomenaWeb.ImageSorter do } } } - ], + ] } _ -> diff --git a/lib/philomena_web/templates/image/new.html.slime b/lib/philomena_web/templates/image/new.html.slime index 851dc847..10cae856 100644 --- a/lib/philomena_web/templates/image/new.html.slime +++ b/lib/philomena_web/templates/image/new.html.slime @@ -30,6 +30,7 @@ p Upload a file from your computer, or provide a link to the page containing the image and click Fetch. .field = file_input f, :image, class: "input js-scraper" + = error_tag f, :image = error_tag f, :image_size = error_tag f, :image_width = error_tag f, :image_height