mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-23 20:18:00 +01:00
77 lines
1.7 KiB
Elixir
77 lines
1.7 KiB
Elixir
defmodule PhilomenaWeb.ImageReverse do
|
|
alias PhilomenaMedia.Analyzers
|
|
alias PhilomenaMedia.Processors
|
|
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
|
|
dist = normalize_dist(image_params)
|
|
limit = parse_limit(image_params)
|
|
|
|
DuplicateReports.duplicates_of(intensities, aspect, dist, dist, limit)
|
|
|> preload([:user, :intensity, [:sources, tags: :aliases]])
|
|
|> Repo.all()
|
|
end
|
|
end
|
|
|
|
defp analyze(%Plug.Upload{path: path}) do
|
|
case Analyzers.analyze(path) do
|
|
{:ok, analysis} -> {analysis, path}
|
|
_ -> :error
|
|
end
|
|
end
|
|
|
|
defp analyze(_upload), do: :error
|
|
|
|
defp intensities(:error), do: :error
|
|
|
|
defp intensities({analysis, path}) do
|
|
{analysis, Processors.intensities(analysis, path)}
|
|
end
|
|
|
|
# The distance metric is taxicab distance, not Euclidean,
|
|
# because this is more efficient to index.
|
|
defp normalize_dist(%{"distance" => distance}) do
|
|
distance
|
|
|> parse_dist()
|
|
|> max(0.01)
|
|
|> min(1.0)
|
|
end
|
|
|
|
defp normalize_dist(_dist), do: 0.25
|
|
|
|
defp parse_dist(dist) do
|
|
case Decimal.parse(dist) do
|
|
{value, _rest} ->
|
|
Decimal.to_float(value)
|
|
|
|
_ ->
|
|
0.0
|
|
end
|
|
end
|
|
|
|
defp parse_limit(%{"limit" => limit}) do
|
|
limit
|
|
|> Integer.parse()
|
|
|> case do
|
|
{limit, _rest} -> limit
|
|
_ -> 10
|
|
end
|
|
|> max(1)
|
|
|> min(50)
|
|
end
|
|
|
|
defp parse_limit(_), do: 10
|
|
end
|