mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-23 20:18:00 +01:00
uploading works
This commit is contained in:
parent
56db3807aa
commit
84abf98b30
9 changed files with 168 additions and 18 deletions
|
@ -14,7 +14,8 @@ config :philomena,
|
|||
otp_secret_key: "Wn7O/8DD+qxL0X4X7bvT90wOkVGcA90bIHww4twR03Ci//zq7PnMw8ypqyyT/b/C",
|
||||
image_url_root: "/img",
|
||||
avatar_url_root: "/avatars",
|
||||
badge_url_root: "/media"
|
||||
badge_url_root: "/media",
|
||||
image_file_root: "priv/static/system/images"
|
||||
|
||||
config :philomena, :pow,
|
||||
user: Philomena.Users.User,
|
||||
|
|
|
@ -62,7 +62,7 @@ defmodule Philomena.Conversations.Conversation do
|
|||
|
||||
defp put_recipient(changeset) do
|
||||
recipient = changeset |> get_field(:recipient)
|
||||
user = Repo.get_by(User, name: recipient) |> IO.inspect()
|
||||
user = Repo.get_by(User, name: recipient)
|
||||
|
||||
changeset
|
||||
|> put_change(:to, user)
|
||||
|
|
|
@ -20,5 +20,6 @@ defmodule Philomena.ImageIntensities.ImageIntensity do
|
|||
image_intensity
|
||||
|> cast(attrs, [:nw, :ne, :sw, :se])
|
||||
|> validate_required([:image_id, :nw, :ne, :sw, :se])
|
||||
|> unique_constraint(:image_id, name: :index_image_intensities_on_image_id)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -13,6 +13,7 @@ defmodule Philomena.Images do
|
|||
alias Philomena.TagChanges.TagChange
|
||||
alias Philomena.Tags
|
||||
alias Philomena.Tags.Tag
|
||||
alias Philomena.Processors
|
||||
|
||||
@doc """
|
||||
Gets a single image.
|
||||
|
@ -44,10 +45,23 @@ defmodule Philomena.Images do
|
|||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def create_image(attrs \\ %{}) do
|
||||
%Image{}
|
||||
|> Image.changeset(attrs)
|
||||
|> Repo.insert()
|
||||
def create_image(attribution, attrs \\ %{}) do
|
||||
tags = Tags.get_or_create_tags(attrs["tag_input"])
|
||||
|
||||
image =
|
||||
%Image{}
|
||||
|> Image.creation_changeset(attrs, attribution)
|
||||
|> Image.tag_changeset(attrs, [], tags)
|
||||
|> Processors.after_upload(attrs)
|
||||
|
||||
Multi.new
|
||||
|> Multi.insert(:image, image)
|
||||
|> Multi.run(:after, fn _repo, %{image: image} ->
|
||||
Processors.after_insert(image)
|
||||
|
||||
{:ok, nil}
|
||||
end)
|
||||
|> Repo.transaction()
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
|
|
@ -109,8 +109,11 @@ defmodule Philomena.Images.Image do
|
|||
end
|
||||
|
||||
def creation_changeset(image, attrs, attribution) do
|
||||
now = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second)
|
||||
|
||||
image
|
||||
|> cast(attrs, [:source_url, :description])
|
||||
|> change(first_seen_at: now)
|
||||
|> change(attribution)
|
||||
end
|
||||
|
||||
|
@ -119,12 +122,14 @@ defmodule Philomena.Images.Image do
|
|||
|> cast(attrs, [
|
||||
:image, :image_name, :image_width, :image_height, :image_size,
|
||||
:image_format, :image_mime_type, :image_aspect_ratio,
|
||||
:image_orig_sha512_hash, :image_sha512_hash, :uploaded_image
|
||||
:image_orig_sha512_hash, :image_sha512_hash, :uploaded_image,
|
||||
:is_animated
|
||||
])
|
||||
|> validate_required([
|
||||
:image, :image_width, :image_height, :image_size,
|
||||
:image_format, :image_mime_type, :image_aspect_ratio,
|
||||
:image_orig_sha512_hash, :image_sha512_hash, :uploaded_image
|
||||
:image_orig_sha512_hash, :image_sha512_hash, :uploaded_image,
|
||||
:is_animated
|
||||
])
|
||||
|> validate_number(:image_size, greater_than: 0, less_than_or_equal_to: 26214400)
|
||||
|> validate_number(:image_width, greater_than: 0, less_than_or_equal_to: 32767)
|
||||
|
|
|
@ -32,10 +32,22 @@ defmodule Philomena.Processors do
|
|||
"video/webm" => Philomena.Processors.Webm
|
||||
}
|
||||
|
||||
@versions [
|
||||
thumb_tiny: {50, 50},
|
||||
thumb_small: {150, 150},
|
||||
thumb: {250, 250},
|
||||
small: {320, 240},
|
||||
medium: {800, 600},
|
||||
large: {1280, 1024},
|
||||
tall: {1024, 4096},
|
||||
full: nil
|
||||
]
|
||||
|
||||
def after_upload(image, params) do
|
||||
with upload when not is_nil(upload) <- params["image"],
|
||||
file <- upload.path,
|
||||
mime <- @mimes[Mime.file(file)],
|
||||
{:ok, mime} <- Mime.file(file),
|
||||
mime <- @mimes[mime],
|
||||
analyzer when not is_nil(analyzer) <- @analyzers[mime],
|
||||
analysis <- analyzer.analyze(file),
|
||||
changes <- analysis_to_changes(analysis, file, upload.filename)
|
||||
|
@ -50,7 +62,10 @@ defmodule Philomena.Processors do
|
|||
end
|
||||
|
||||
def after_insert(image) do
|
||||
File.cp!(image.uploaded_image, Path.join([image_file_root(), image.image]))
|
||||
file = image_file(image)
|
||||
dir = Path.dirname(file)
|
||||
File.mkdir_p!(dir)
|
||||
File.cp!(image.uploaded_image, file)
|
||||
ImageProcessor.cast(self(), image.id)
|
||||
end
|
||||
|
||||
|
@ -62,7 +77,7 @@ defmodule Philomena.Processors do
|
|||
analyzer = @analyzers[mime]
|
||||
analysis = analyzer.analyze(file)
|
||||
processor = @processors[mime]
|
||||
process = processor.process(analysis, file)
|
||||
process = processor.process(analysis, file, @versions)
|
||||
|
||||
apply_edit_script(image, process)
|
||||
sha512 = Sha512.file(file)
|
||||
|
@ -102,22 +117,27 @@ defmodule Philomena.Processors do
|
|||
|
||||
defp apply_thumbnail(_image, thumb_dir, {:copy, new_file, destination}) do
|
||||
new_destination = Path.join([thumb_dir, destination])
|
||||
dir = Path.dirname(new_destination)
|
||||
|
||||
File.cp(new_file, new_destination)
|
||||
File.chmod(new_destination, 0o755)
|
||||
File.mkdir_p!(dir)
|
||||
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)
|
||||
file = Path.absname(image_file(image))
|
||||
new_destination = Path.join([thumb_dir, destination])
|
||||
dir = Path.dirname(new_destination)
|
||||
|
||||
File.ln_s(file, new_destination)
|
||||
File.chmod(new_destination, 0o755)
|
||||
File.mkdir_p!(dir)
|
||||
File.rm(new_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)
|
||||
{:ok, %{size: size}} = File.stat(file)
|
||||
sha512 = Sha512.file(file)
|
||||
filename = build_filename(analysis.extension)
|
||||
|
||||
|
@ -132,6 +152,7 @@ defmodule Philomena.Processors do
|
|||
"image_aspect_ratio" => aspect_ratio(width, height),
|
||||
"image_orig_sha512_hash" => sha512,
|
||||
"image_sha512_hash" => sha512,
|
||||
"is_animated" => analysis.animated?,
|
||||
"uploaded_image" => file
|
||||
}
|
||||
end
|
||||
|
|
|
@ -9,6 +9,10 @@ defmodule PhilomenaWeb.ImageController do
|
|||
|
||||
plug :load_and_authorize_resource, model: Image, only: :show, preload: [:tags, user: [awards: :badge]]
|
||||
|
||||
plug PhilomenaWeb.FilterBannedUsersPlug when action in [:new, :create]
|
||||
plug PhilomenaWeb.UserAttributionPlug when action in [:create]
|
||||
plug PhilomenaWeb.CaptchaPlug when action in [:create]
|
||||
|
||||
def index(conn, _params) do
|
||||
query = conn.assigns.compiled_filter
|
||||
|
||||
|
@ -77,4 +81,29 @@ defmodule PhilomenaWeb.ImageController do
|
|||
layout_class: "layout--wide"
|
||||
)
|
||||
end
|
||||
|
||||
def new(conn, _params) do
|
||||
changeset =
|
||||
%Image{}
|
||||
|> Images.change_image()
|
||||
|
||||
render(conn, "new.html", changeset: changeset)
|
||||
end
|
||||
|
||||
def create(conn, %{"image" => image_params}) do
|
||||
attributes = conn.assigns.attributes
|
||||
|
||||
case Images.create_image(attributes, image_params) do
|
||||
{:ok, %{image: image}} ->
|
||||
Images.reindex_image(image)
|
||||
|
||||
conn
|
||||
|> put_flash(:info, "Image created successfully.")
|
||||
|> redirect(to: Routes.image_path(conn, :show, image))
|
||||
|
||||
{:error, :image, changeset, _} ->
|
||||
conn
|
||||
|> render("new.html", changeset: changeset)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -83,7 +83,7 @@ defmodule PhilomenaWeb.Router do
|
|||
get "/", ActivityController, :index
|
||||
|
||||
resources "/activity", ActivityController, only: [:index]
|
||||
resources "/images", ImageController, only: [:index, :show] do
|
||||
resources "/images", ImageController, only: [:index, :show, :new, :create] do
|
||||
resources "/comments", Image.CommentController, only: [:index, :show, :create]
|
||||
resources "/tags", Image.TagController, only: [:update], singleton: true
|
||||
resources "/sources", Image.SourceController, only: [:update], singleton: true
|
||||
|
|
79
lib/philomena_web/templates/image/new.html.slime
Normal file
79
lib/philomena_web/templates/image/new.html.slime
Normal file
|
@ -0,0 +1,79 @@
|
|||
= form_for @changeset, Routes.image_path(@conn, :create), [multipart: true], fn f ->
|
||||
|
||||
.dnp-warning
|
||||
h4
|
||||
' Read the
|
||||
a> href="/pages/rules" site rules
|
||||
' and check our
|
||||
a> href="/dnp" do-not-post list
|
||||
p
|
||||
' Don't post content the artist doesn't want here (or shared in general),
|
||||
strong including commercial content.
|
||||
|
||||
= if !@conn.assigns.current_user do
|
||||
p
|
||||
strong<> Sorry, but due to spam, anonymous uploaders need to fill this out.
|
||||
| If you're logged in, you can still post anonymously and won't have to deal with captchas!
|
||||
|
||||
.field
|
||||
= checkbox f, :captcha, class: "js-captcha", value: 0
|
||||
= label f, :captcha, "I am not a robot!"
|
||||
|
||||
p
|
||||
strong
|
||||
' Please check it isn't already here with
|
||||
a href="/search/reverse" reverse search.
|
||||
|
||||
/ todo: extract this
|
||||
h4 Select an image
|
||||
.image-other
|
||||
#js-image-upload-previews
|
||||
p Upload a file from your computer
|
||||
.field
|
||||
= file_input f, :image, class: "input js-scraper"
|
||||
= error_tag f, :image_size
|
||||
= error_tag f, :image_width
|
||||
= error_tag f, :image_height
|
||||
= error_tag f, :image_name
|
||||
= error_tag f, :image_mime_type
|
||||
|
||||
.field-error-js.hidden.js-scraper
|
||||
|
||||
h4 About this image
|
||||
.field
|
||||
= label f, :source_url, "The page you found this image on"
|
||||
= url_input f, :source_url, class: "input input--wide js-image-input", placeholder: "Source URL"
|
||||
|
||||
.field
|
||||
label for="image[tag_input]"
|
||||
' Describe with
|
||||
strong> 3+
|
||||
' tags, including ratings and applicable artist tags
|
||||
|
||||
= render PhilomenaWeb.TagView, "_tag_editor.html", f: f, name: :tag_input, type: :upload
|
||||
|
||||
button.button.button--state-success.button--separate-left.button--bold id="tagsinput-save" type="button" title="This button saves the tags listed above to your browser, allowing you to retrieve them again by clicking the Load button" Save
|
||||
button.button.button--state-warning.button--separate-left.button--bold id="tagsinput-load" type="button" title="This button loads any saved tags from your browser" Load
|
||||
button.button.button--state-danger.button--separate-left.button--bold id="tagsinput-clear" type="button" title="This button will clear the list of tags above" Clear
|
||||
|
||||
br
|
||||
|
||||
.field
|
||||
.block
|
||||
.block__header.block__header--js-tabbed
|
||||
= link "Description", to: "#", class: "selected", data: [click_tab: "write"]
|
||||
= link "Preview", to: "#", data: [click_tab: "preview"]
|
||||
|
||||
.block__tab.selected data-tab="write"
|
||||
/= render partial: 'layouts/textile_toolbar'
|
||||
= textarea f, :description, class: "input input--wide input--text js-preview-description js-image-input js-toolbar-input", placeholder: "Describe this image in plain words - this should generally be info about the image that doesn't belong in the tags or source."
|
||||
.block__tab.hidden data-tab="preview"
|
||||
| Loading preview...
|
||||
|
||||
= if @conn.assigns.current_user do
|
||||
.field
|
||||
= label f, :anonymous, "Post anonymously"
|
||||
= checkbox f, :anonymous, class: "checkbox"
|
||||
|
||||
.actions
|
||||
= submit "Upload", class: "button", autocomplete: "off", data: [disable_with: "Please wait..."]
|
Loading…
Reference in a new issue