2019-12-04 01:50:23 +01:00
|
|
|
defmodule PhilomenaWeb.ImageReverse do
|
2024-06-02 06:15:09 +02:00
|
|
|
alias PhilomenaMedia.Analyzers
|
|
|
|
alias PhilomenaMedia.Processors
|
2019-12-04 01:50:23 +01:00
|
|
|
alias Philomena.DuplicateReports
|
|
|
|
alias Philomena.Repo
|
|
|
|
import Ecto.Query
|
|
|
|
|
|
|
|
def images(image_params) do
|
|
|
|
image_params
|
|
|
|
|> Map.get("image")
|
|
|
|
|> analyze()
|
|
|
|
|> intensities()
|
|
|
|
|> case do
|
|
|
|
:error ->
|
|
|
|
[]
|
|
|
|
|
|
|
|
{analysis, intensities} ->
|
|
|
|
{width, height} = analysis.dimensions
|
|
|
|
aspect = width / height
|
2024-07-19 14:50:16 +02:00
|
|
|
dist = parse_dist(image_params)
|
2024-07-19 11:01:27 +02:00
|
|
|
limit = parse_limit(image_params)
|
2019-12-04 01:50:23 +01:00
|
|
|
|
2024-07-19 14:50:16 +02:00
|
|
|
{intensities, aspect}
|
|
|
|
|> DuplicateReports.find_duplicates(dist: dist, aspect_dist: dist, limit: limit)
|
2023-05-29 13:06:41 +02:00
|
|
|
|> preload([:user, :intensity, [:sources, tags: :aliases]])
|
2019-12-04 01:50:23 +01:00
|
|
|
|> Repo.all()
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2019-12-07 06:49:20 +01:00
|
|
|
defp analyze(%Plug.Upload{path: path}) do
|
2020-09-08 06:02:24 +02:00
|
|
|
case Analyzers.analyze(path) do
|
|
|
|
{:ok, analysis} -> {analysis, path}
|
|
|
|
_ -> :error
|
|
|
|
end
|
2019-12-04 01:50:23 +01:00
|
|
|
end
|
2020-01-11 05:20:19 +01:00
|
|
|
|
2019-12-12 16:51:44 +01:00
|
|
|
defp analyze(_upload), do: :error
|
2019-12-04 01:50:23 +01:00
|
|
|
|
|
|
|
defp intensities(:error), do: :error
|
2020-01-11 05:20:19 +01:00
|
|
|
|
2019-12-07 06:49:20 +01:00
|
|
|
defp intensities({analysis, path}) do
|
|
|
|
{analysis, Processors.intensities(analysis, path)}
|
2019-12-04 01:50:23 +01:00
|
|
|
end
|
|
|
|
|
|
|
|
# The distance metric is taxicab distance, not Euclidean,
|
|
|
|
# because this is more efficient to index.
|
2024-07-19 14:50:16 +02:00
|
|
|
defp parse_dist(%{"distance" => distance}) do
|
2019-12-04 01:50:23 +01:00
|
|
|
distance
|
2024-07-19 14:50:16 +02:00
|
|
|
|> Decimal.parse()
|
|
|
|
|> case do
|
|
|
|
{value, _rest} -> Decimal.to_float(value)
|
|
|
|
_ -> 0.25
|
2024-06-03 04:48:24 +02:00
|
|
|
end
|
2024-07-19 14:50:16 +02:00
|
|
|
|> clamp(0.01, 1.0)
|
2024-06-03 04:48:24 +02:00
|
|
|
end
|
2024-07-19 11:01:27 +02:00
|
|
|
|
2024-07-19 14:50:16 +02:00
|
|
|
defp parse_dist(_params), do: 0.25
|
|
|
|
|
2024-07-19 11:01:27 +02:00
|
|
|
defp parse_limit(%{"limit" => limit}) do
|
|
|
|
limit
|
|
|
|
|> Integer.parse()
|
|
|
|
|> case do
|
|
|
|
{limit, _rest} -> limit
|
|
|
|
_ -> 10
|
|
|
|
end
|
2024-07-19 14:50:16 +02:00
|
|
|
|> clamp(1, 50)
|
2024-07-19 11:01:27 +02:00
|
|
|
end
|
|
|
|
|
2024-07-19 14:50:16 +02:00
|
|
|
defp parse_limit(_params), do: 10
|
|
|
|
|
|
|
|
defp clamp(n, min, _max) when n < min, do: min
|
|
|
|
defp clamp(n, _min, max) when n > max, do: max
|
|
|
|
defp clamp(n, _min, _max), do: n
|
2019-12-30 15:18:38 +01:00
|
|
|
end
|