mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-27 13:47:58 +01:00
all processing code
This commit is contained in:
parent
2159fbd9c7
commit
56db3807aa
6 changed files with 156 additions and 29 deletions
|
@ -15,6 +15,7 @@ defmodule Philomena.Application do
|
|||
# Starts a worker by calling: Philomena.Worker.start_link(arg)
|
||||
# {Philomena.Worker, arg},
|
||||
Pow.Store.Backend.MnesiaCache,
|
||||
Philomena.Servers.ImageProcessor,
|
||||
{Redix, name: :redix}
|
||||
]
|
||||
|
||||
|
|
|
@ -8,19 +8,6 @@ defmodule Philomena.ImageIntensities do
|
|||
|
||||
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 """
|
||||
Gets a single image_intensity.
|
||||
|
||||
|
@ -49,8 +36,8 @@ defmodule Philomena.ImageIntensities do
|
|||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def create_image_intensity(attrs \\ %{}) do
|
||||
%ImageIntensity{}
|
||||
def create_image_intensity(image, attrs \\ %{}) do
|
||||
%ImageIntensity{image_id: image.id}
|
||||
|> ImageIntensity.changeset(attrs)
|
||||
|> Repo.insert()
|
||||
end
|
||||
|
|
|
@ -18,7 +18,7 @@ defmodule Philomena.ImageIntensities.ImageIntensity do
|
|||
@doc false
|
||||
def changeset(image_intensity, attrs) do
|
||||
image_intensity
|
||||
|> cast(attrs, [])
|
||||
|> validate_required([])
|
||||
|> cast(attrs, [:nw, :ne, :sw, :se])
|
||||
|> validate_required([:image_id, :nw, :ne, :sw, :se])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -108,6 +108,12 @@ defmodule Philomena.Images.Image do
|
|||
|> validate_required([])
|
||||
end
|
||||
|
||||
def creation_changeset(image, attrs, attribution) do
|
||||
image
|
||||
|> cast(attrs, [:source_url, :description])
|
||||
|> change(attribution)
|
||||
end
|
||||
|
||||
def image_changeset(image, attrs) do
|
||||
image
|
||||
|> cast(attrs, [
|
||||
|
@ -140,4 +146,16 @@ defmodule Philomena.Images.Image do
|
|||
|> TagDiffer.diff_input(old_tags, new_tags)
|
||||
|> TagValidator.validate_tags()
|
||||
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
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
defmodule Philomena.Processors do
|
||||
# alias Philomena.Images.Image
|
||||
# alias Philomena.Repo
|
||||
alias Philomena.Images.Image
|
||||
alias Philomena.ImageIntensities
|
||||
alias Philomena.Repo
|
||||
alias Philomena.Mime
|
||||
alias Philomena.Sha512
|
||||
alias Philomena.Servers.ImageProcessor
|
||||
|
||||
@mimes %{
|
||||
"image/gif" => "image/gif",
|
||||
|
@ -29,7 +32,90 @@ defmodule Philomena.Processors do
|
|||
"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
|
||||
%{size: size} = File.stat(file)
|
||||
sha512 = Sha512.file(file)
|
||||
|
@ -50,16 +136,20 @@ defmodule Philomena.Processors do
|
|||
}
|
||||
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(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
|
||||
[
|
||||
time_identifier(),
|
||||
time_identifier(DateTime.utc_now()),
|
||||
"/",
|
||||
usec_identifier(),
|
||||
pid_identifier(),
|
||||
|
@ -69,10 +159,8 @@ defmodule Philomena.Processors do
|
|||
|> Enum.join()
|
||||
end
|
||||
|
||||
defp time_identifier do
|
||||
now = DateTime.utc_now()
|
||||
|
||||
Enum.join([now.year, now.month, now.day], "/")
|
||||
defp time_identifier(time) do
|
||||
Enum.join([time.year, time.month, time.day], "/")
|
||||
end
|
||||
|
||||
defp usec_identifier do
|
||||
|
|
33
lib/philomena/servers/image_processor.ex
Normal file
33
lib/philomena/servers/image_processor.ex
Normal 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
|
Loading…
Reference in a new issue