2019-08-24 17:35:30 +02:00
|
|
|
defmodule Philomena.Images.Query do
|
2020-05-08 04:43:40 +02:00
|
|
|
alias Philomena.Search.Parser
|
2019-11-02 21:31:55 +01:00
|
|
|
alias Philomena.Repo
|
|
|
|
|
2019-12-30 22:02:25 +01:00
|
|
|
defp gallery_id_transform(_ctx, value),
|
2019-11-02 21:31:55 +01:00
|
|
|
do: {:ok, %{nested: %{path: :galleries, query: %{term: %{"galleries.id" => value}}}}}
|
|
|
|
|
2019-12-30 22:02:25 +01:00
|
|
|
defp user_my_transform(%{user: %{id: id}}, "faves"),
|
2019-11-02 21:31:55 +01:00
|
|
|
do: {:ok, %{term: %{favourited_by_user_ids: id}}}
|
|
|
|
|
2019-12-30 22:02:25 +01:00
|
|
|
defp user_my_transform(%{user: %{id: id}}, "upvotes"),
|
2019-11-02 21:31:55 +01:00
|
|
|
do: {:ok, %{term: %{upvoter_ids: id}}}
|
|
|
|
|
2019-12-30 22:02:25 +01:00
|
|
|
defp user_my_transform(%{user: %{id: id}}, "downvotes"),
|
2019-11-02 21:31:55 +01:00
|
|
|
do: {:ok, %{term: %{downvoter_ids: id}}}
|
|
|
|
|
2019-12-30 22:02:25 +01:00
|
|
|
defp user_my_transform(%{user: %{id: id}}, "uploads"),
|
2019-11-15 16:32:26 +01:00
|
|
|
do: {:ok, %{term: %{true_uploader_id: id}}}
|
|
|
|
|
2019-12-30 22:02:25 +01:00
|
|
|
defp user_my_transform(%{user: %{id: id}}, "hidden"),
|
2019-11-15 19:27:10 +01:00
|
|
|
do: {:ok, %{term: %{hidden_by_user_ids: id}}}
|
|
|
|
|
2019-12-30 22:02:25 +01:00
|
|
|
defp user_my_transform(%{watch: true}, "watched"),
|
2019-11-02 21:31:55 +01:00
|
|
|
do: {:error, "Recursive watchlists are not allowed."}
|
|
|
|
|
2019-12-30 22:02:25 +01:00
|
|
|
defp user_my_transform(%{user: user} = ctx, "watched") do
|
2019-11-02 21:31:55 +01:00
|
|
|
ctx = Map.merge(ctx, %{watch: true})
|
|
|
|
|
|
|
|
tag_include = %{terms: %{tag_ids: user.watched_tag_ids}}
|
|
|
|
|
2019-12-20 19:05:39 +01:00
|
|
|
include_query = invalid_filter_guard(ctx, user.watched_images_query_str)
|
|
|
|
exclude_query = invalid_filter_guard(ctx, user.watched_images_exclude_str)
|
2019-11-02 21:31:55 +01:00
|
|
|
|
|
|
|
should = [tag_include, include_query]
|
|
|
|
must_not = [exclude_query]
|
|
|
|
|
|
|
|
must_not =
|
|
|
|
if user.no_spoilered_in_watched do
|
|
|
|
user = user |> Repo.preload(:current_filter)
|
|
|
|
|
|
|
|
tag_exclude = %{terms: %{tag_ids: user.current_filter.spoilered_tag_ids}}
|
2019-12-20 19:05:39 +01:00
|
|
|
spoiler_query = invalid_filter_guard(ctx, user.current_filter.spoilered_complex_str)
|
2019-11-02 21:31:55 +01:00
|
|
|
|
|
|
|
[tag_exclude, spoiler_query | must_not]
|
|
|
|
else
|
|
|
|
must_not
|
2019-08-27 02:00:39 +02:00
|
|
|
end
|
2019-11-02 21:31:55 +01:00
|
|
|
|
2019-11-13 04:12:46 +01:00
|
|
|
{:ok, %{bool: %{should: should, must_not: must_not}}}
|
2019-11-02 21:31:55 +01:00
|
|
|
end
|
|
|
|
|
2019-12-30 22:02:25 +01:00
|
|
|
defp user_my_transform(_ctx, _value),
|
2019-11-02 21:31:55 +01:00
|
|
|
do: {:error, "Unknown `my' value."}
|
|
|
|
|
2019-12-20 19:05:39 +01:00
|
|
|
defp invalid_filter_guard(ctx, search_string) do
|
2020-05-08 04:43:40 +02:00
|
|
|
case parse(user_fields(), ctx, Philomena.Search.String.normalize(search_string)) do
|
2019-12-20 19:05:39 +01:00
|
|
|
{:ok, query} -> query
|
|
|
|
_error -> %{match_all: %{}}
|
|
|
|
end
|
|
|
|
end
|
2019-11-02 21:31:55 +01:00
|
|
|
|
2019-12-30 22:02:25 +01:00
|
|
|
defp anonymous_fields do
|
|
|
|
[
|
2020-01-11 05:20:19 +01:00
|
|
|
int_fields:
|
|
|
|
~W(id width height comment_count score upvotes downvotes faves uploader_id faved_by_id tag_count),
|
2019-12-30 22:02:25 +01:00
|
|
|
float_fields: ~W(aspect_ratio wilson_score),
|
|
|
|
date_fields: ~W(created_at updated_at first_seen_at),
|
2020-01-11 05:20:19 +01:00
|
|
|
literal_fields:
|
|
|
|
~W(faved_by orig_sha512_hash sha512_hash uploader source_url original_format),
|
2019-12-30 22:02:25 +01:00
|
|
|
ngram_fields: ~W(description),
|
|
|
|
custom_fields: ~W(gallery_id),
|
|
|
|
default_field: {"namespaced_tags.name", :term},
|
|
|
|
transforms: %{"gallery_id" => &gallery_id_transform/2},
|
|
|
|
aliases: %{
|
|
|
|
"faved_by" => "favourited_by_users",
|
|
|
|
"faved_by_id" => "favourited_by_user_ids"
|
|
|
|
}
|
|
|
|
]
|
2019-11-02 21:31:55 +01:00
|
|
|
end
|
|
|
|
|
2019-12-30 22:02:25 +01:00
|
|
|
defp user_fields do
|
|
|
|
fields = anonymous_fields()
|
|
|
|
|
2020-01-11 05:20:19 +01:00
|
|
|
Keyword.merge(fields,
|
2019-12-30 22:02:25 +01:00
|
|
|
custom_fields: fields[:custom_fields] ++ ~W(my),
|
|
|
|
transforms: Map.merge(fields[:transforms], %{"my" => &user_my_transform/2})
|
2020-01-11 05:20:19 +01:00
|
|
|
)
|
2019-12-30 22:02:25 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
defp moderator_fields do
|
|
|
|
fields = user_fields()
|
|
|
|
|
2020-01-11 05:20:19 +01:00
|
|
|
Keyword.merge(fields,
|
|
|
|
int_fields:
|
|
|
|
fields[:int_fields] ++
|
|
|
|
~W(upvoted_by_id downvoted_by_id true_uploader_id hidden_by_id deleted_by_user_id),
|
|
|
|
literal_fields:
|
|
|
|
fields[:literal_fields] ++
|
|
|
|
~W(fingerprint upvoted_by downvoted_by true_uploader hidden_by deleted_by_user),
|
2020-02-01 17:04:11 +01:00
|
|
|
ngram_fields: fields[:ngram_fields] ++ ~W(deletion_reason),
|
2019-12-30 22:02:25 +01:00
|
|
|
ip_fields: ~W(ip),
|
|
|
|
bool_fields: ~W(deleted),
|
2020-01-11 05:20:19 +01:00
|
|
|
aliases:
|
|
|
|
Map.merge(fields[:aliases], %{
|
|
|
|
"upvoted_by" => "upvoters",
|
|
|
|
"downvoted_by" => "downvoters",
|
|
|
|
"upvoted_by_id" => "upvoter_ids",
|
|
|
|
"downvoted_by_id" => "downvoter_ids",
|
|
|
|
"hidden_by" => "hidden_by_users",
|
|
|
|
"hidden_by_id" => "hidden_by_user_ids",
|
|
|
|
"deleted" => "hidden_from_users"
|
|
|
|
})
|
|
|
|
)
|
2019-11-02 21:31:55 +01:00
|
|
|
end
|
|
|
|
|
2019-12-30 22:02:25 +01:00
|
|
|
defp parse(fields, context, query_string) do
|
|
|
|
fields
|
|
|
|
|> Parser.parser()
|
|
|
|
|> Parser.parse(query_string, context)
|
2019-11-02 21:31:55 +01:00
|
|
|
end
|
|
|
|
|
2019-08-29 03:14:54 +02:00
|
|
|
def compile(user, query_string, watch \\ false) do
|
|
|
|
query_string = query_string || ""
|
|
|
|
|
|
|
|
case user do
|
|
|
|
nil ->
|
2019-12-30 22:02:25 +01:00
|
|
|
parse(anonymous_fields(), %{user: nil, watch: watch}, query_string)
|
2019-08-29 03:14:54 +02:00
|
|
|
|
|
|
|
%{role: role} when role in ~W(user assistant) ->
|
2019-12-30 22:02:25 +01:00
|
|
|
parse(user_fields(), %{user: user, watch: watch}, query_string)
|
2019-08-29 03:14:54 +02:00
|
|
|
|
|
|
|
%{role: role} when role in ~W(moderator admin) ->
|
2019-12-30 22:02:25 +01:00
|
|
|
parse(moderator_fields(), %{user: user, watch: watch}, query_string)
|
2019-08-29 03:14:54 +02:00
|
|
|
|
|
|
|
_ ->
|
|
|
|
raise ArgumentError, "Unknown user role."
|
|
|
|
end
|
|
|
|
end
|
2019-08-26 15:57:04 +02:00
|
|
|
end
|