all processing code

This commit is contained in:
byte[] 2019-11-25 22:47:57 -05:00
parent 2159fbd9c7
commit 56db3807aa
6 changed files with 156 additions and 29 deletions

View file

@ -15,6 +15,7 @@ defmodule Philomena.Application do
# Starts a worker by calling: Philomena.Worker.start_link(arg) # Starts a worker by calling: Philomena.Worker.start_link(arg)
# {Philomena.Worker, arg}, # {Philomena.Worker, arg},
Pow.Store.Backend.MnesiaCache, Pow.Store.Backend.MnesiaCache,
Philomena.Servers.ImageProcessor,
{Redix, name: :redix} {Redix, name: :redix}
] ]

View file

@ -8,19 +8,6 @@ defmodule Philomena.ImageIntensities do
alias Philomena.ImageIntensities.ImageIntensity alias Philomena.ImageIntensities.ImageIntensity
@doc """
Returns the list of image_intensities.
## Examples
iex> list_image_intensities()
[%ImageIntensity{}, ...]
"""
def list_image_intensities do
Repo.all(ImageIntensity)
end
@doc """ @doc """
Gets a single image_intensity. Gets a single image_intensity.
@ -49,8 +36,8 @@ defmodule Philomena.ImageIntensities do
{:error, %Ecto.Changeset{}} {:error, %Ecto.Changeset{}}
""" """
def create_image_intensity(attrs \\ %{}) do def create_image_intensity(image, attrs \\ %{}) do
%ImageIntensity{} %ImageIntensity{image_id: image.id}
|> ImageIntensity.changeset(attrs) |> ImageIntensity.changeset(attrs)
|> Repo.insert() |> Repo.insert()
end end

View file

@ -18,7 +18,7 @@ defmodule Philomena.ImageIntensities.ImageIntensity do
@doc false @doc false
def changeset(image_intensity, attrs) do def changeset(image_intensity, attrs) do
image_intensity image_intensity
|> cast(attrs, []) |> cast(attrs, [:nw, :ne, :sw, :se])
|> validate_required([]) |> validate_required([:image_id, :nw, :ne, :sw, :se])
end end
end end

View file

@ -108,6 +108,12 @@ defmodule Philomena.Images.Image do
|> validate_required([]) |> validate_required([])
end end
def creation_changeset(image, attrs, attribution) do
image
|> cast(attrs, [:source_url, :description])
|> change(attribution)
end
def image_changeset(image, attrs) do def image_changeset(image, attrs) do
image image
|> cast(attrs, [ |> cast(attrs, [
@ -140,4 +146,16 @@ defmodule Philomena.Images.Image do
|> TagDiffer.diff_input(old_tags, new_tags) |> TagDiffer.diff_input(old_tags, new_tags)
|> TagValidator.validate_tags() |> TagValidator.validate_tags()
end end
def thumbnail_changeset(image, attrs) do
image
|> cast(attrs, [:image_sha512_hash])
|> change(thumbnails_generated: true, duplication_checked: true)
end
def process_changeset(image, attrs) do
image
|> cast(attrs, [:image_sha512_hash])
|> change(processed: true)
end
end end

View file

@ -1,7 +1,10 @@
defmodule Philomena.Processors do defmodule Philomena.Processors do
# alias Philomena.Images.Image alias Philomena.Images.Image
# alias Philomena.Repo alias Philomena.ImageIntensities
alias Philomena.Repo
alias Philomena.Mime
alias Philomena.Sha512 alias Philomena.Sha512
alias Philomena.Servers.ImageProcessor
@mimes %{ @mimes %{
"image/gif" => "image/gif", "image/gif" => "image/gif",
@ -29,7 +32,90 @@ defmodule Philomena.Processors do
"video/webm" => Philomena.Processors.Webm "video/webm" => Philomena.Processors.Webm
} }
def analysis_to_changes(analysis, file, upload_name) do def after_upload(image, params) do
with upload when not is_nil(upload) <- params["image"],
file <- upload.path,
mime <- @mimes[Mime.file(file)],
analyzer when not is_nil(analyzer) <- @analyzers[mime],
analysis <- analyzer.analyze(file),
changes <- analysis_to_changes(analysis, file, upload.filename)
do
image
|> Image.image_changeset(changes)
else
_ ->
image
|> Image.image_changeset(%{})
end
end
def after_insert(image) do
File.cp!(image.uploaded_image, Path.join([image_file_root(), image.image]))
ImageProcessor.cast(self(), image.id)
end
def process_image(image_id) do
image = Repo.get!(Image, image_id)
mime = image.image_mime_type
file = image_file(image)
analyzer = @analyzers[mime]
analysis = analyzer.analyze(file)
processor = @processors[mime]
process = processor.process(analysis, file)
apply_edit_script(image, process)
sha512 = Sha512.file(file)
changeset = Image.thumbnail_changeset(image, %{"image_sha512_hash" => sha512})
image = Repo.update!(changeset)
processor.post_process(analysis, file)
sha512 = Sha512.file(file)
changeset = Image.process_changeset(image, %{"image_sha512_hash" => sha512})
Repo.update!(changeset)
end
defp apply_edit_script(image, changes) do
for change <- changes do
apply_change(image, change)
end
end
defp apply_change(image, {:intensities, intensities}) do
ImageIntensities.create_image_intensity(image, intensities)
end
defp apply_change(image, {:replace_original, new_file}) do
file = image_file(image)
File.cp(new_file, file)
File.chmod(file, 0o755)
end
defp apply_change(image, {:thumbnails, thumbnails}) do
thumb_dir = image_thumb_dir(image)
for thumbnail <- thumbnails do
apply_thumbnail(image, thumb_dir, thumbnail)
end
end
defp apply_thumbnail(_image, thumb_dir, {:copy, new_file, destination}) do
new_destination = Path.join([thumb_dir, destination])
File.cp(new_file, new_destination)
File.chmod(new_destination, 0o755)
end
defp apply_thumbnail(image, thumb_dir, {:symlink_original, destination}) do
file = image_file(image)
new_destination = Path.join([thumb_dir, destination])
File.ln_s(file, new_destination)
File.chmod(new_destination, 0o755)
end
defp analysis_to_changes(analysis, file, upload_name) do
{width, height} = analysis.dimensions {width, height} = analysis.dimensions
%{size: size} = File.stat(file) %{size: size} = File.stat(file)
sha512 = Sha512.file(file) sha512 = Sha512.file(file)
@ -50,16 +136,20 @@ defmodule Philomena.Processors do
} }
end end
def after_upload(image) do
File.cp(image.uploaded_image, Path.join([image_file_root(), image.image]))
end
defp aspect_ratio(_, 0), do: 0.0 defp aspect_ratio(_, 0), do: 0.0
defp aspect_ratio(w, h), do: w / h defp aspect_ratio(w, h), do: w / h
defp image_file(image) do
Path.join([image_file_root(), image.image])
end
defp image_thumb_dir(image) do
Path.join([image_thumbnail_root(), time_identifier(image.created_at), to_string(image.id)])
end
defp build_filename(extension) do defp build_filename(extension) do
[ [
time_identifier(), time_identifier(DateTime.utc_now()),
"/", "/",
usec_identifier(), usec_identifier(),
pid_identifier(), pid_identifier(),
@ -69,10 +159,8 @@ defmodule Philomena.Processors do
|> Enum.join() |> Enum.join()
end end
defp time_identifier do defp time_identifier(time) do
now = DateTime.utc_now() Enum.join([time.year, time.month, time.day], "/")
Enum.join([now.year, now.month, now.day], "/")
end end
defp usec_identifier do defp usec_identifier do

View file

@ -0,0 +1,33 @@
defmodule Philomena.Servers.ImageProcessor do
use GenServer
def start_link(default) when is_list(default) do
GenServer.start_link(__MODULE__, default)
end
def cast(pid, image_id) do
GenServer.cast(pid, {:enqueue, image_id})
end
@impl true
def init([]) do
{:ok, []}
end
@impl true
def handle_cast({:enqueue, image_id}, []) do
# Ensure that tempfiles get cleaned up by reaping
# the process after it is done
Task.async(fn -> process(image_id) end)
|> Task.await()
{:noreply, []}
end
defp process(image_id) do
Philomena.Processors.process_image(image_id)
#rescue
# _ ->
# nil
end
end