mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-24 04:27:59 +01:00
74 lines
1.7 KiB
Elixir
74 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 = parse_dist(image_params)
|
|
limit = parse_limit(image_params)
|
|
|
|
{intensities, aspect}
|
|
|> DuplicateReports.find_duplicates(dist: dist, aspect_dist: dist, limit: 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 parse_dist(%{"distance" => distance}) do
|
|
distance
|
|
|> Decimal.parse()
|
|
|> case do
|
|
{value, _rest} -> Decimal.to_float(value)
|
|
_ -> 0.25
|
|
end
|
|
|> clamp(0.01, 1.0)
|
|
end
|
|
|
|
defp parse_dist(_params), do: 0.25
|
|
|
|
defp parse_limit(%{"limit" => limit}) do
|
|
limit
|
|
|> Integer.parse()
|
|
|> case do
|
|
{limit, _rest} -> limit
|
|
_ -> 10
|
|
end
|
|
|> clamp(1, 50)
|
|
end
|
|
|
|
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
|
|
end
|