2019-12-24 22:14:42 +01:00
|
|
|
defmodule Philomena.Images.ElasticsearchIndex do
|
|
|
|
@behaviour Philomena.ElasticsearchIndex
|
|
|
|
|
|
|
|
@impl true
|
|
|
|
def index_name do
|
|
|
|
"images"
|
|
|
|
end
|
|
|
|
|
|
|
|
@impl true
|
2019-08-19 03:43:06 +02:00
|
|
|
def mapping do
|
|
|
|
%{
|
|
|
|
settings: %{
|
|
|
|
index: %{
|
|
|
|
number_of_shards: 5,
|
|
|
|
max_result_window: 10_000_000
|
|
|
|
}
|
|
|
|
},
|
|
|
|
mappings: %{
|
2020-05-04 14:19:42 +02:00
|
|
|
dynamic: false,
|
|
|
|
properties: %{
|
2021-12-20 20:44:52 +01:00
|
|
|
animated: %{type: "boolean"},
|
2020-05-04 14:19:42 +02:00
|
|
|
anonymous: %{type: "boolean"},
|
|
|
|
aspect_ratio: %{type: "float"},
|
|
|
|
comment_count: %{type: "integer"},
|
|
|
|
commenters: %{type: "keyword"},
|
|
|
|
created_at: %{type: "date"},
|
|
|
|
deleted_by_user: %{type: "keyword"},
|
|
|
|
deleted_by_user_id: %{type: "keyword"},
|
|
|
|
deletion_reason: %{type: "text", analyzer: "snowball"},
|
|
|
|
description: %{type: "text", analyzer: "snowball"},
|
|
|
|
downvoter_ids: %{type: "keyword"},
|
|
|
|
downvoters: %{type: "keyword"},
|
|
|
|
downvotes: %{type: "integer"},
|
|
|
|
duplicate_id: %{type: "integer"},
|
2020-07-06 20:00:02 +02:00
|
|
|
duration: %{type: "float"},
|
2020-05-04 14:19:42 +02:00
|
|
|
faves: %{type: "integer"},
|
|
|
|
favourited_by_user_ids: %{type: "keyword"},
|
|
|
|
favourited_by_users: %{type: "keyword"},
|
|
|
|
file_name: %{type: "keyword"},
|
|
|
|
fingerprint: %{type: "keyword"},
|
|
|
|
first_seen_at: %{type: "date"},
|
2021-12-20 20:44:52 +01:00
|
|
|
fps: %{type: "float"},
|
|
|
|
frames: %{type: "integer"},
|
2020-05-04 14:19:42 +02:00
|
|
|
height: %{type: "integer"},
|
|
|
|
hidden_by_user_ids: %{type: "keyword"},
|
|
|
|
hidden_by_users: %{type: "keyword"},
|
|
|
|
hidden_from_users: %{type: "keyword"},
|
|
|
|
id: %{type: "integer"},
|
|
|
|
ip: %{type: "ip"},
|
|
|
|
mime_type: %{type: "keyword"},
|
|
|
|
orig_sha512_hash: %{type: "keyword"},
|
|
|
|
original_format: %{type: "keyword"},
|
2020-07-06 20:00:02 +02:00
|
|
|
pixels: %{type: "integer"},
|
2021-12-20 20:44:52 +01:00
|
|
|
processed: %{type: "boolean"},
|
2020-05-04 14:19:42 +02:00
|
|
|
score: %{type: "integer"},
|
2020-07-06 20:00:02 +02:00
|
|
|
size: %{type: "integer"},
|
2020-05-04 14:19:42 +02:00
|
|
|
sha512_hash: %{type: "keyword"},
|
|
|
|
source_url: %{type: "keyword"},
|
|
|
|
tag_count: %{type: "integer"},
|
|
|
|
tag_ids: %{type: "keyword"},
|
|
|
|
tags: %{type: "text", analyzer: "keyword"},
|
2021-12-20 20:44:52 +01:00
|
|
|
thumbnails_generated: %{type: "boolean"},
|
2020-05-04 14:19:42 +02:00
|
|
|
true_uploader: %{type: "keyword"},
|
|
|
|
true_uploader_id: %{type: "keyword"},
|
|
|
|
updated_at: %{type: "date"},
|
|
|
|
uploader: %{type: "keyword"},
|
|
|
|
uploader_id: %{type: "keyword"},
|
|
|
|
upvoter_ids: %{type: "keyword"},
|
|
|
|
upvoters: %{type: "keyword"},
|
|
|
|
upvotes: %{type: "integer"},
|
|
|
|
user_id: %{type: "keyword"},
|
|
|
|
width: %{type: "integer"},
|
|
|
|
wilson_score: %{type: "float"},
|
|
|
|
galleries: %{
|
|
|
|
type: "nested",
|
|
|
|
properties: %{
|
|
|
|
id: %{type: "integer"},
|
|
|
|
position: %{type: "integer"}
|
|
|
|
}
|
|
|
|
},
|
2020-08-14 07:24:14 +02:00
|
|
|
gallery_id: %{type: "keyword"},
|
|
|
|
gallery_position: %{type: "object", enabled: false},
|
2020-05-04 14:19:42 +02:00
|
|
|
namespaced_tags: %{
|
|
|
|
properties: %{
|
|
|
|
name: %{type: "keyword"},
|
|
|
|
name_in_namespace: %{type: "keyword"},
|
|
|
|
namespace: %{type: "keyword"}
|
2019-08-19 03:43:06 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2019-12-24 22:14:42 +01:00
|
|
|
@impl true
|
2019-08-19 03:43:06 +02:00
|
|
|
def as_json(image) do
|
|
|
|
%{
|
|
|
|
id: image.id,
|
|
|
|
upvotes: image.upvotes_count,
|
|
|
|
downvotes: image.downvotes_count,
|
|
|
|
score: image.score,
|
|
|
|
faves: image.faves_count,
|
|
|
|
comment_count: image.comments_count,
|
|
|
|
width: image.image_width,
|
|
|
|
height: image.image_height,
|
2020-07-06 20:00:02 +02:00
|
|
|
pixels: image.image_width * image.image_height,
|
|
|
|
size: image.image_size,
|
2021-12-20 20:44:52 +01:00
|
|
|
animated: image.image_is_animated,
|
|
|
|
duration: if(image.image_is_animated, do: image.image_duration, else: 0),
|
2019-08-19 03:43:06 +02:00
|
|
|
tag_count: length(image.tags),
|
|
|
|
aspect_ratio: image.image_aspect_ratio,
|
|
|
|
wilson_score: wilson_score(image),
|
|
|
|
created_at: image.created_at,
|
|
|
|
updated_at: image.updated_at,
|
|
|
|
first_seen_at: image.first_seen_at,
|
|
|
|
ip: image.ip |> to_string,
|
|
|
|
tag_ids: image.tags |> Enum.map(& &1.id),
|
|
|
|
mime_type: image.image_mime_type,
|
|
|
|
uploader: if(!!image.user and !image.anonymous, do: String.downcase(image.user.name)),
|
|
|
|
true_uploader: if(!!image.user, do: String.downcase(image.user.name)),
|
|
|
|
source_url: image.source_url |> to_string |> String.downcase(),
|
|
|
|
file_name: image.image_name,
|
|
|
|
original_format: image.image_format,
|
2021-12-20 20:44:52 +01:00
|
|
|
processed: image.processed,
|
|
|
|
thumbnails_generated: image.thumbnails_generated,
|
2019-08-19 03:43:06 +02:00
|
|
|
fingerprint: image.fingerprint,
|
|
|
|
uploader_id: if(!!image.user_id and !image.anonymous, do: image.user_id),
|
|
|
|
true_uploader_id: image.user_id,
|
|
|
|
orig_sha512_hash: image.image_orig_sha512_hash,
|
|
|
|
sha512_hash: image.image_sha512_hash,
|
|
|
|
hidden_from_users: image.hidden_from_users,
|
|
|
|
anonymous: image.anonymous,
|
|
|
|
description: image.description,
|
|
|
|
deletion_reason: image.deletion_reason,
|
|
|
|
favourited_by_user_ids: image.favers |> Enum.map(& &1.id),
|
|
|
|
hidden_by_user_ids: image.hiders |> Enum.map(& &1.id),
|
|
|
|
upvoter_ids: image.upvoters |> Enum.map(& &1.id),
|
|
|
|
downvoter_ids: image.downvoters |> Enum.map(& &1.id),
|
|
|
|
deleted_by_user_id: image.deleter_id,
|
2019-12-19 23:39:34 +01:00
|
|
|
duplicate_id: image.duplicate_id,
|
2019-08-19 03:43:06 +02:00
|
|
|
galleries:
|
|
|
|
image.gallery_interactions |> Enum.map(&%{id: &1.gallery_id, position: &1.position}),
|
|
|
|
namespaced_tags: %{
|
|
|
|
name: image.tags |> Enum.flat_map(&([&1] ++ &1.aliases)) |> Enum.map(& &1.name)
|
|
|
|
},
|
2020-08-14 07:24:14 +02:00
|
|
|
gallery_id: Enum.map(image.gallery_interactions, & &1.gallery_id),
|
|
|
|
gallery_position: Map.new(image.gallery_interactions, &{&1.gallery_id, &1.position}),
|
2019-08-19 03:43:06 +02:00
|
|
|
favourited_by_users: image.favers |> Enum.map(&String.downcase(&1.name)),
|
|
|
|
hidden_by_users: image.hiders |> Enum.map(&String.downcase(&1.name)),
|
|
|
|
upvoters: image.upvoters |> Enum.map(&String.downcase(&1.name)),
|
|
|
|
downvoters: image.downvoters |> Enum.map(&String.downcase(&1.name)),
|
|
|
|
deleted_by_user: if(!!image.deleter, do: image.deleter.name)
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2020-05-03 00:17:55 +02:00
|
|
|
def user_name_update_by_query(old_name, new_name) do
|
|
|
|
old_name = String.downcase(old_name)
|
|
|
|
new_name = String.downcase(new_name)
|
|
|
|
|
|
|
|
%{
|
|
|
|
query: %{
|
|
|
|
bool: %{
|
|
|
|
should: [
|
|
|
|
%{term: %{uploader: old_name}},
|
|
|
|
%{term: %{true_uploader: old_name}},
|
|
|
|
%{term: %{deleted_by_user: old_name}},
|
|
|
|
%{term: %{favourited_by_users: old_name}},
|
|
|
|
%{term: %{hidden_by_users: old_name}},
|
|
|
|
%{term: %{upvoters: old_name}},
|
|
|
|
%{term: %{downvoters: old_name}}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
},
|
|
|
|
replacements: [
|
|
|
|
%{path: ["uploader"], old: old_name, new: new_name},
|
|
|
|
%{path: ["true_uploader"], old: old_name, new: new_name},
|
|
|
|
%{path: ["deleted_by_user"], old: old_name, new: new_name}
|
|
|
|
],
|
|
|
|
set_replacements: [
|
|
|
|
%{path: ["favourited_by_users"], old: old_name, new: new_name},
|
|
|
|
%{path: ["hidden_by_users"], old: old_name, new: new_name},
|
|
|
|
%{path: ["upvoters"], old: old_name, new: new_name},
|
|
|
|
%{path: ["downvoters"], old: old_name, new: new_name}
|
|
|
|
]
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
2019-12-25 09:49:56 +01:00
|
|
|
def wilson_score(%{upvotes_count: upvotes, downvotes_count: downvotes}) when upvotes > 0 do
|
2019-08-19 03:43:06 +02:00
|
|
|
# Population size
|
|
|
|
n = (upvotes + downvotes) / 1
|
|
|
|
|
|
|
|
# Success proportion
|
|
|
|
p_hat = upvotes / n
|
|
|
|
|
|
|
|
# z and z^2 values for CI upper 99.5%
|
|
|
|
z = 2.57583
|
|
|
|
z2 = 6.634900189
|
|
|
|
|
|
|
|
(p_hat + z2 / (2 * n) - z * :math.sqrt((p_hat * (1 - p_hat) + z2 / (4 * n)) / n)) /
|
|
|
|
(1 + z2 / n)
|
|
|
|
end
|
|
|
|
|
|
|
|
def wilson_score(_), do: 0
|
|
|
|
end
|