mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-27 13:47:58 +01:00
verified uploaders
This commit is contained in:
parent
84abf98b30
commit
ae7f3834fd
24 changed files with 170 additions and 61 deletions
|
@ -18,6 +18,7 @@ config :philomena,
|
|||
anonymous_name_salt: System.get_env("ANONYMOUS_NAME_SALT"),
|
||||
password_pepper: System.get_env("PASSWORD_PEPPER"),
|
||||
avatar_url_root: System.get_env("AVATAR_URL_ROOT"),
|
||||
image_file_root: System.get_env("IMAGE_FILE_ROOT"),
|
||||
otp_secret_key: System.get_env("OTP_SECRET_KEY"),
|
||||
image_url_root: System.get_env("IMAGE_URL_ROOT"),
|
||||
badge_url_root: System.get_env("BADGE_URL_ROOT"),
|
||||
|
|
|
@ -46,6 +46,8 @@ defmodule Philomena.Analyzers.Gif do
|
|||
{output, 0} ->
|
||||
[width, height] =
|
||||
output
|
||||
|> String.split("\n", trim: true)
|
||||
|> hd()
|
||||
|> String.trim()
|
||||
|> String.split(" ")
|
||||
|> Enum.map(&String.to_integer/1)
|
||||
|
|
|
@ -14,8 +14,8 @@ defmodule Philomena.Application do
|
|||
PhilomenaWeb.Endpoint,
|
||||
# Starts a worker by calling: Philomena.Worker.start_link(arg)
|
||||
# {Philomena.Worker, arg},
|
||||
Pow.Store.Backend.MnesiaCache,
|
||||
Philomena.Servers.ImageProcessor,
|
||||
Pow.Store.Backend.MnesiaCache,
|
||||
{Redix, name: :redix}
|
||||
]
|
||||
|
||||
|
|
|
@ -7,18 +7,31 @@ defmodule Philomena.DuplicateReports do
|
|||
alias Philomena.Repo
|
||||
|
||||
alias Philomena.DuplicateReports.DuplicateReport
|
||||
alias Philomena.ImageIntensities.ImageIntensity
|
||||
alias Philomena.Images.Image
|
||||
|
||||
@doc """
|
||||
Returns the list of duplicate_reports.
|
||||
def generate_reports(source) do
|
||||
source = Repo.preload(source, :intensity)
|
||||
|
||||
## Examples
|
||||
duplicates_of(source.intensity, source.image_aspect_ratio, 0.2, 0.05)
|
||||
|> where([i, _it], i.id != ^source.id)
|
||||
|> where([i, _it], i.duplication_checked != true)
|
||||
|> Repo.all()
|
||||
|> Enum.map(fn target ->
|
||||
create_duplicate_report(source, target, %{}, %{"reason" => "Automated Perceptual dedupe match"})
|
||||
end)
|
||||
end
|
||||
|
||||
iex> list_duplicate_reports()
|
||||
[%DuplicateReport{}, ...]
|
||||
|
||||
"""
|
||||
def list_duplicate_reports do
|
||||
Repo.all(DuplicateReport)
|
||||
def duplicates_of(intensities, aspect_ratio, dist \\ 0.25, aspect_dist \\ 0.05) do
|
||||
from i in Image,
|
||||
inner_join: it in ImageIntensity,
|
||||
on: it.image_id == i.id,
|
||||
where: it.nw >= ^(intensities.nw - dist) and it.nw <= ^(intensities.nw + dist),
|
||||
where: it.ne >= ^(intensities.ne - dist) and it.ne <= ^(intensities.ne + dist),
|
||||
where: it.sw >= ^(intensities.sw - dist) and it.sw <= ^(intensities.sw + dist),
|
||||
where: it.se >= ^(intensities.se - dist) and it.se <= ^(intensities.se + dist),
|
||||
where: i.image_aspect_ratio >= ^(aspect_ratio - aspect_dist) and i.image_aspect_ratio >= ^(aspect_ratio + aspect_dist),
|
||||
limit: 20
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
@ -49,9 +62,9 @@ defmodule Philomena.DuplicateReports do
|
|||
{:error, %Ecto.Changeset{}}
|
||||
|
||||
"""
|
||||
def create_duplicate_report(attrs \\ %{}) do
|
||||
%DuplicateReport{}
|
||||
|> DuplicateReport.changeset(attrs)
|
||||
def create_duplicate_report(source, target, attribution, attrs \\ %{}) do
|
||||
%DuplicateReport{image_id: source.id, duplicate_of_image_id: target.id}
|
||||
|> DuplicateReport.creation_changeset(attrs, attribution)
|
||||
|> Repo.insert()
|
||||
end
|
||||
|
||||
|
|
|
@ -23,4 +23,12 @@ defmodule Philomena.DuplicateReports.DuplicateReport do
|
|||
|> cast(attrs, [])
|
||||
|> validate_required([])
|
||||
end
|
||||
|
||||
@doc false
|
||||
def creation_changeset(duplicate_report, attrs, attribution) do
|
||||
duplicate_report
|
||||
|> cast(attrs, [:reason])
|
||||
|> put_assoc(:user, attribution[:user])
|
||||
|> validate_length(:reason, max: 250, count: :bytes)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -56,12 +56,20 @@ defmodule Philomena.Images do
|
|||
|
||||
Multi.new
|
||||
|> Multi.insert(:image, image)
|
||||
|> Multi.run(:added_tag_count, fn repo, %{image: image} ->
|
||||
tag_ids = image.added_tags |> Enum.map(& &1.id)
|
||||
tags = Tag |> where([t], t.id in ^tag_ids)
|
||||
|
||||
{count, nil} = repo.update_all(tags, inc: [images_count: 1])
|
||||
|
||||
{:ok, count}
|
||||
end)
|
||||
|> Multi.run(:after, fn _repo, %{image: image} ->
|
||||
Processors.after_insert(image)
|
||||
|
||||
{:ok, nil}
|
||||
end)
|
||||
|> Repo.transaction()
|
||||
|> Repo.isolated_transaction(:serializable)
|
||||
end
|
||||
|
||||
@doc """
|
||||
|
|
|
@ -8,6 +8,7 @@ defmodule Philomena.Images.Image do
|
|||
|
||||
import Ecto.Changeset
|
||||
|
||||
alias Philomena.ImageIntensities.ImageIntensity
|
||||
alias Philomena.ImageVotes.ImageVote
|
||||
alias Philomena.ImageFaves.ImageFave
|
||||
alias Philomena.ImageHides.ImageHide
|
||||
|
@ -39,6 +40,7 @@ defmodule Philomena.Images.Image do
|
|||
has_many :favers, through: [:faves, :user]
|
||||
has_many :hiders, through: [:hides, :user]
|
||||
many_to_many :tags, Tag, join_through: "image_taggings", on_replace: :delete
|
||||
has_one :intensity, ImageIntensity
|
||||
|
||||
field :image, :string
|
||||
field :image_name, :string
|
||||
|
@ -112,7 +114,7 @@ defmodule Philomena.Images.Image do
|
|||
now = NaiveDateTime.utc_now() |> NaiveDateTime.truncate(:second)
|
||||
|
||||
image
|
||||
|> cast(attrs, [:source_url, :description])
|
||||
|> cast(attrs, [:anonymous, :source_url, :description])
|
||||
|> change(first_seen_at: now)
|
||||
|> change(attribution)
|
||||
end
|
||||
|
|
|
@ -9,6 +9,7 @@ defmodule Philomena.Images.TagDiffer do
|
|||
old_set = to_set(old_tags)
|
||||
new_set = to_set(new_tags)
|
||||
|
||||
image_id = changeset |> get_field(:id)
|
||||
tags = changeset |> get_field(:tags)
|
||||
added_tags = added_set(old_set, new_set)
|
||||
removed_tags = removed_set(old_set, new_set)
|
||||
|
@ -16,14 +17,15 @@ defmodule Philomena.Images.TagDiffer do
|
|||
{tags, actually_added, actually_removed} =
|
||||
apply_changes(tags, added_tags, removed_tags)
|
||||
|
||||
{tag_list_cache, tag_list_plus_alias_cache} =
|
||||
create_caches(tags)
|
||||
{tag_list_cache, tag_list_plus_alias_cache, file_name_cache} =
|
||||
create_caches(image_id, tags)
|
||||
|
||||
changeset
|
||||
|> put_change(:added_tags, actually_added)
|
||||
|> put_change(:removed_tags, actually_removed)
|
||||
|> put_change(:tag_list_cache, tag_list_cache)
|
||||
|> put_change(:tag_list_plus_alias_cache, tag_list_plus_alias_cache)
|
||||
|> put_change(:file_name_cache, file_name_cache)
|
||||
|> put_assoc(:tags, tags)
|
||||
end
|
||||
|
||||
|
@ -94,10 +96,11 @@ defmodule Philomena.Images.TagDiffer do
|
|||
{tags, actually_added, actually_removed}
|
||||
end
|
||||
|
||||
defp create_caches(tags) do
|
||||
defp create_caches(image_id, tags) do
|
||||
tags = Tag.display_order(tags)
|
||||
|
||||
tag_list_cache =
|
||||
tags
|
||||
|> Tag.display_order()
|
||||
|> Enum.map_join(", ", & &1.name)
|
||||
|
||||
tag_ids =
|
||||
|
@ -113,6 +116,17 @@ defmodule Philomena.Images.TagDiffer do
|
|||
|> Tag.display_order()
|
||||
|> Enum.map_join(", ", & &1.name)
|
||||
|
||||
{tag_list_cache, tag_list_plus_alias_cache}
|
||||
# Trunate filename to 150 characters, making room for the path + filename on Windows
|
||||
# https://stackoverflow.com/questions/265769/maximum-filename-length-in-ntfs-windows-xp-and-windows-vista
|
||||
file_name_slug_fragment =
|
||||
tags
|
||||
|> Enum.map_join("_", & &1.slug)
|
||||
|> String.replace("%2F", "")
|
||||
|> String.replace("/", "")
|
||||
|> String.slice(0..150)
|
||||
|
||||
file_name_cache = "#{image_id}__#{file_name_slug_fragment}"
|
||||
|
||||
{tag_list_cache, tag_list_plus_alias_cache, file_name_cache}
|
||||
end
|
||||
end
|
|
@ -1,10 +1,10 @@
|
|||
defmodule Philomena.Processors do
|
||||
alias Philomena.Images.Image
|
||||
alias Philomena.DuplicateReports
|
||||
alias Philomena.ImageIntensities
|
||||
alias Philomena.Repo
|
||||
alias Philomena.Mime
|
||||
alias Philomena.Sha512
|
||||
alias Philomena.Servers.ImageProcessor
|
||||
|
||||
@mimes %{
|
||||
"image/gif" => "image/gif",
|
||||
|
@ -66,7 +66,6 @@ defmodule Philomena.Processors do
|
|||
dir = Path.dirname(file)
|
||||
File.mkdir_p!(dir)
|
||||
File.cp!(image.uploaded_image, file)
|
||||
ImageProcessor.cast(self(), image.id)
|
||||
end
|
||||
|
||||
def process_image(image_id) do
|
||||
|
@ -83,8 +82,11 @@ defmodule Philomena.Processors do
|
|||
sha512 = Sha512.file(file)
|
||||
changeset = Image.thumbnail_changeset(image, %{"image_sha512_hash" => sha512})
|
||||
image = Repo.update!(changeset)
|
||||
spawn fn -> DuplicateReports.generate_reports(image) end
|
||||
|
||||
processor.post_process(analysis, file)
|
||||
process = processor.post_process(analysis, file)
|
||||
|
||||
apply_edit_script(image, process)
|
||||
sha512 = Sha512.file(file)
|
||||
changeset = Image.process_changeset(image, %{"image_sha512_hash" => sha512})
|
||||
Repo.update!(changeset)
|
||||
|
|
|
@ -68,7 +68,7 @@ defmodule Philomena.Processors.Gif do
|
|||
|
||||
scale_filter = "scale=w=#{width}:h=#{height}:force_original_aspect_ratio=decrease"
|
||||
palette_filter = "paletteuse=dither=bayer:bayer_scale=5:diff_mode=rectangle"
|
||||
filter_graph = "#{scale_filter} [x]; [x][1:v] #{palette_filter}"
|
||||
filter_graph = "[0:v] #{scale_filter} [x]; [x][1:v] #{palette_filter}"
|
||||
|
||||
{_output, 0} =
|
||||
System.cmd("ffmpeg", ["-loglevel", "0", "-y", "-i", file, "-i", palette, "-lavfi", filter_graph, scaled])
|
||||
|
|
|
@ -22,22 +22,22 @@ defmodule Philomena.Processors.Png do
|
|||
optimized = Briefly.create!(extname: ".png")
|
||||
|
||||
{_output, 0} =
|
||||
System.cmd("optipng", ["-fix", "-i0", "-o2", file, "-out", optimized])
|
||||
System.cmd("optipng", ["-fix", "-i0", "-o2", "-quiet", "-clobber", file, "-out", optimized])
|
||||
|
||||
optimized
|
||||
end
|
||||
|
||||
defp scale_if_smaller(_file, _dimensions, {:full, _target_dim}) do
|
||||
[{:symlink_original, "full.jpg"}]
|
||||
[{:symlink_original, "full.png"}]
|
||||
end
|
||||
|
||||
defp scale_if_smaller(file, {width, height}, {thumb_name, {target_width, target_height}}) do
|
||||
if width > target_width or height > target_height do
|
||||
scaled = scale(file, {target_width, target_height})
|
||||
|
||||
[{:copy, scaled, "#{thumb_name}.jpg"}]
|
||||
[{:copy, scaled, "#{thumb_name}.png"}]
|
||||
else
|
||||
[{:symlink_original, "#{thumb_name}.jpg"}]
|
||||
[{:symlink_original, "#{thumb_name}.png"}]
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -48,7 +48,7 @@ defmodule Philomena.Processors.Png do
|
|||
{_output, 0} =
|
||||
System.cmd("ffmpeg", ["-loglevel", "0", "-y", "-i", file, "-vf", scale_filter, scaled])
|
||||
{_output, 0} =
|
||||
System.cmd("optipng", ["-i0", "-o1", scaled])
|
||||
System.cmd("optipng", ["-i0", "-o1", "-quiet", "-clobber", scaled])
|
||||
|
||||
scaled
|
||||
end
|
||||
|
|
|
@ -20,7 +20,7 @@ defmodule Philomena.Processors.Svg do
|
|||
preview = Briefly.create!(extname: ".png")
|
||||
|
||||
{_output, 0} =
|
||||
System.cmd("inkscape", [file, "--export-png", preview])
|
||||
System.cmd("safe-rsvg-convert", [file, preview])
|
||||
|
||||
preview
|
||||
end
|
||||
|
@ -40,9 +40,9 @@ defmodule Philomena.Processors.Svg do
|
|||
scale_filter = "scale=w=#{width}:h=#{height}:force_original_aspect_ratio=decrease"
|
||||
|
||||
{_output, 0} =
|
||||
System.cmd("ffmpeg", ["-y", "-i", preview, "-vf", scale_filter, scaled])
|
||||
System.cmd("ffmpeg", ["-loglevel", "0", "-y", "-i", preview, "-vf", scale_filter, scaled])
|
||||
{_output, 0} =
|
||||
System.cmd("optipng", ["-i0", "-o1", scaled])
|
||||
System.cmd("optipng", ["-i0", "-o1", "-quiet", "-clobber", scaled])
|
||||
|
||||
scaled
|
||||
end
|
||||
|
|
|
@ -29,8 +29,8 @@ defmodule Philomena.Processors.Webm do
|
|||
preview
|
||||
end
|
||||
|
||||
defp scale_if_smaller(palette, file, dimensions, {:full, _target_dim}) do
|
||||
{webm, mp4} = scale_videos(file, palette, dimensions)
|
||||
defp scale_if_smaller(file, palette, dimensions, {:full, _target_dim}) do
|
||||
{webm, mp4} = scale_videos(file, palette, dimensions, dimensions)
|
||||
|
||||
[
|
||||
{:copy, webm, "full.webm"},
|
||||
|
@ -38,8 +38,8 @@ defmodule Philomena.Processors.Webm do
|
|||
]
|
||||
end
|
||||
|
||||
defp scale_if_smaller(palette, file, _dimensions, {thumb_name, {target_width, target_height}}) do
|
||||
{webm, mp4} = scale_videos(file, palette, {target_width, target_height})
|
||||
defp scale_if_smaller(file, palette, dimensions, {thumb_name, {target_width, target_height}}) do
|
||||
{webm, mp4} = scale_videos(file, palette, dimensions, {target_width, target_height})
|
||||
|
||||
cond do
|
||||
thumb_name in [:thumb, :thumb_small, :thumb_tiny] ->
|
||||
|
@ -59,14 +59,14 @@ defmodule Philomena.Processors.Webm do
|
|||
end
|
||||
end
|
||||
|
||||
defp scale_videos(file, _palette, dimensions) do
|
||||
{width, height} = normalize_dimensions(dimensions)
|
||||
defp scale_videos(file, _palette, dimensions, target_dimensions) do
|
||||
{width, height} = box_dimensions(dimensions, target_dimensions)
|
||||
webm = Briefly.create!(extname: ".webm")
|
||||
mp4 = Briefly.create!(extname: ".mp4")
|
||||
scale_filter = "scale=w=#{width}:h=#{height}:force_original_aspect_ratio=decrease"
|
||||
scale_filter = "scale=w=#{width}:h=#{height}"
|
||||
|
||||
{_output, 0} =
|
||||
System.cmd("ffmpeg", ["-loglevel", "0", "-y", "-i", file, "-c:v", "libvpx", "-crf", "10", "-b:v", "5M", "-vf", scale_filter, webm])
|
||||
System.cmd("ffmpeg", ["-loglevel", "0", "-y", "-i", file, "-c:v", "libvpx", "-auto-alt-ref", "0", "-crf", "10", "-b:v", "5M", "-vf", scale_filter, webm])
|
||||
{_output, 0} =
|
||||
System.cmd("ffmpeg", ["-loglevel", "0", "-y", "-i", file, "-c:v", "libx264", "-preset", "medium", "-crf", "18", "-b:v", "5M", "-vf", scale_filter, mp4])
|
||||
|
||||
|
@ -77,7 +77,7 @@ defmodule Philomena.Processors.Webm do
|
|||
gif = Briefly.create!(extname: ".gif")
|
||||
scale_filter = "scale=w=#{width}:h=#{height}:force_original_aspect_ratio=decrease"
|
||||
palette_filter = "paletteuse=dither=bayer:bayer_scale=5:diff_mode=rectangle"
|
||||
filter_graph = "#{scale_filter} [x]; [x][1:v] #{palette_filter}"
|
||||
filter_graph = "[0:v] #{scale_filter} [x]; [x][1:v] #{palette_filter}"
|
||||
|
||||
{_output, 0} =
|
||||
System.cmd("ffmpeg", ["-loglevel", "0", "-y", "-i", file, "-i", palette, "-lavfi", filter_graph, gif])
|
||||
|
@ -94,9 +94,13 @@ defmodule Philomena.Processors.Webm do
|
|||
palette
|
||||
end
|
||||
|
||||
# Force dimensions to be a multiple of 2. This is required by the
|
||||
# libvpx and x264 encoders.
|
||||
defp normalize_dimensions({width, height}) do
|
||||
{width &&& (~~~1), height &&& (~~~1)}
|
||||
# x264 requires image dimensions to be a multiple of 2
|
||||
# -2 = ~1
|
||||
def box_dimensions({width, height}, {target_width, target_height}) do
|
||||
ratio = min(target_width / width, target_height / height)
|
||||
new_width = min(max(trunc(width * ratio) &&& -2, 2), target_width)
|
||||
new_height = min(max(trunc(height * ratio) &&& -2, 2), target_height)
|
||||
|
||||
{new_width, new_height}
|
||||
end
|
||||
end
|
|
@ -5,12 +5,14 @@ defmodule Philomena.Servers.ImageProcessor do
|
|||
GenServer.start_link(__MODULE__, default)
|
||||
end
|
||||
|
||||
def cast(pid, image_id) do
|
||||
def cast(image_id) do
|
||||
pid = Process.whereis(:processor)
|
||||
GenServer.cast(pid, {:enqueue, image_id})
|
||||
end
|
||||
|
||||
@impl true
|
||||
def init([]) do
|
||||
Process.register(self(), :processor)
|
||||
{:ok, []}
|
||||
end
|
||||
|
||||
|
@ -19,7 +21,7 @@ defmodule Philomena.Servers.ImageProcessor do
|
|||
# Ensure that tempfiles get cleaned up by reaping
|
||||
# the process after it is done
|
||||
Task.async(fn -> process(image_id) end)
|
||||
|> Task.await()
|
||||
|> Task.await(:infinity)
|
||||
|
||||
{:noreply, []}
|
||||
end
|
||||
|
|
|
@ -2,8 +2,10 @@ defmodule PhilomenaWeb.ImageController do
|
|||
use PhilomenaWeb, :controller
|
||||
|
||||
alias Philomena.{Images, Images.Image, Comments.Comment, Textile.Renderer}
|
||||
alias Philomena.Servers.ImageProcessor
|
||||
alias Philomena.Interactions
|
||||
alias Philomena.Comments
|
||||
alias Philomena.Tags
|
||||
alias Philomena.Repo
|
||||
import Ecto.Query
|
||||
|
||||
|
@ -95,7 +97,9 @@ defmodule PhilomenaWeb.ImageController do
|
|||
|
||||
case Images.create_image(attributes, image_params) do
|
||||
{:ok, %{image: image}} ->
|
||||
ImageProcessor.cast(image.id)
|
||||
Images.reindex_image(image)
|
||||
Tags.reindex_tags(image.added_tags)
|
||||
|
||||
conn
|
||||
|> put_flash(:info, "Image created successfully.")
|
||||
|
|
|
@ -30,7 +30,7 @@ defmodule PhilomenaWeb.Endpoint do
|
|||
plug Plug.Telemetry, event_prefix: [:phoenix, :endpoint]
|
||||
|
||||
plug Plug.Parsers,
|
||||
parsers: [:urlencoded, :multipart, :json],
|
||||
parsers: [:urlencoded, {:multipart, length: 30_000_000}, :json],
|
||||
pass: ["*/*"],
|
||||
json_decoder: Phoenix.json_library()
|
||||
|
||||
|
|
|
@ -13,16 +13,19 @@ div
|
|||
/ | because:
|
||||
/ =<> comment.edit_reason
|
||||
div
|
||||
- link_path = "/images/#{@comment.image.id}#comment_#{@comment.id}"
|
||||
- link_path = Routes.image_path(@conn, :show, @comment.image) <> "#comment_#{@comment.id}"
|
||||
- safe_author = PhilomenaWeb.PostView.textile_safe_author(@comment)
|
||||
- quote_body = if @comment.hidden_from_users, do: "", else: @comment.body
|
||||
|
||||
a.communication__interaction title="Link to comment" href=link_path
|
||||
i.fa.fa-link>
|
||||
' Link
|
||||
/=<> link_to link_path, 'data-author': safe_author(comment), 'data-reply-url': link_path, 'data-post': (comment.hidden_from_users ? '' : comment.body), class: 'communication__interaction post-reply post-reply-quote' do
|
||||
a.communication__interaction.post-reply.post-reply-quote href=link_path data-reply-url=link_path data-author="" data-post=""
|
||||
|
||||
a.communication__interaction.post-reply.post-reply-quote href=link_path data-reply-url=link_path data-author=safe_author data-post=quote_body
|
||||
i.fa.fa-quote-right>
|
||||
' Quote
|
||||
/=<> link_to link_path, 'data-author': safe_author(comment), 'data-reply-url': link_path, class: 'communication__interaction post-reply' do
|
||||
a.communication__interaction.post-reply href=link_path data-reply-url=link_path data-author=""
|
||||
|
||||
a.communication__interaction.post-reply href=link_path data-reply-url=link_path data-author=safe_author
|
||||
i.fa.fa-reply
|
||||
' Reply
|
||||
/span.owner-options.hidden
|
||||
|
|
|
@ -22,4 +22,6 @@
|
|||
' [Loading preview...]
|
||||
|
||||
.block__content.communication-edit__actions
|
||||
= submit "Post", class: "button"
|
||||
=> submit "Post", class: "button"
|
||||
= checkbox f, :anonymous
|
||||
= label f, :anonymous, "Anonymous"
|
|
@ -14,15 +14,18 @@ div
|
|||
/ =<> post.edit_reason
|
||||
div
|
||||
- link_path = Routes.forum_topic_path(@conn, :show, @post.topic.forum, @post.topic, post_id: @post.id) <> "#post_#{@post.id}"
|
||||
- safe_author = textile_safe_author(@post)
|
||||
- quote_body = if @post.hidden_from_users, do: "", else: @post.body
|
||||
|
||||
a.communication__interaction title="Link to post" href=link_path
|
||||
i.fa.fa-link>
|
||||
' Link
|
||||
/=<> link_to link_path, 'data-author': safe_author(post), 'data-reply-url': link_path, 'data-post': (post.hidden_from_users ? '' : post.body), class: 'communication__interaction post-reply post-reply-quote' do
|
||||
a.communication__interaction.post-reply.post-reply-quote href=link_path data-reply-url=link_path data-author="" data-post=""
|
||||
|
||||
a.communication__interaction.post-reply.post-reply-quote href=link_path data-reply-url=link_path data-author=safe_author data-post=quote_body
|
||||
i.fa.fa-quote-right>
|
||||
' Quote
|
||||
/=<> link_to link_path, 'data-author': safe_author(post), 'data-reply-url': link_path, class: 'communication__interaction post-reply' do
|
||||
a.communication__interaction.post-reply href=link_path data-reply-url=link_path data-author=""
|
||||
|
||||
a.communication__interaction.post-reply href=link_path data-reply-url=link_path data-author=safe_author
|
||||
i.fa.fa-reply
|
||||
' Reply
|
||||
/span.owner-options.hidden
|
||||
|
|
|
@ -5,5 +5,4 @@
|
|||
= render PhilomenaWeb.ProfileView, "_awards.html", awards: @object.user.awards
|
||||
- else
|
||||
strong<>
|
||||
| Background Pony #
|
||||
= anonymous_name(@object)
|
|
@ -1,3 +1,31 @@
|
|||
defmodule PhilomenaWeb.PostView do
|
||||
alias Philomena.Attribution
|
||||
alias Textile.Parser
|
||||
|
||||
use PhilomenaWeb, :view
|
||||
|
||||
def textile_safe_author(object) do
|
||||
author_name = author_name(object)
|
||||
|
||||
Parser.parse(%Parser{image_transform: & &1}, author_name)
|
||||
|> case do
|
||||
[{:text, ^author_name}] ->
|
||||
author_name
|
||||
|
||||
_ ->
|
||||
# Cover *all* possibilities.
|
||||
literal =
|
||||
author_name
|
||||
|> String.replace("==]", "==]==][==")
|
||||
|
||||
"[==#{literal}==]"
|
||||
end
|
||||
end
|
||||
|
||||
defp author_name(object) do
|
||||
case Attribution.anonymous?(object) do
|
||||
true -> PhilomenaWeb.UserAttributionView.anonymous_name(object)
|
||||
false -> object.user.name
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,8 +12,11 @@ defmodule PhilomenaWeb.UserAttributionView do
|
|||
id = Attribution.object_identifier(object)
|
||||
user_id = Attribution.best_user_identifier(object)
|
||||
|
||||
(:erlang.crc32(salt <> id <> user_id) &&& 0xffff)
|
||||
|> Integer.to_string(16)
|
||||
hash =
|
||||
(:erlang.crc32(salt <> id <> user_id) &&& 0xffff)
|
||||
|> Integer.to_string(16)
|
||||
|
||||
"Background Pony ##{hash}"
|
||||
end
|
||||
|
||||
def anonymous_avatar(_object, class \\ "avatar--100px") do
|
||||
|
|
1
mix.lock
1
mix.lock
|
@ -44,6 +44,7 @@
|
|||
"plug": {:hex, :plug, "1.8.3", "12d5f9796dc72e8ac9614e94bda5e51c4c028d0d428e9297650d09e15a684478", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"plug_cowboy": {:hex, :plug_cowboy, "2.1.0", "b75768153c3a8a9e8039d4b25bb9b14efbc58e9c4a6e6a270abff1cd30cbe320", [:mix], [{:cowboy, "~> 2.5", [hex: :cowboy, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"},
|
||||
"plug_crypto": {:hex, :plug_crypto, "1.0.0", "18e49317d3fa343f24620ed22795ec29d4a5e602d52d1513ccea0b07d8ea7d4d", [:mix], [], "hexpm"},
|
||||
"porcelain": {:git, "https://github.com/walkr/porcelain.git", "4a497495beb8cab7af0d47ae50f720d31a13f039", [ref: "4a49749"]},
|
||||
"postgrex": {:hex, :postgrex, "0.15.1", "23ce3417de70f4c0e9e7419ad85bdabcc6860a6925fe2c6f3b1b5b1e8e47bf2f", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
"pot": {:hex, :pot, "0.10.1", "af7dc220fd45478719b821fb4c1222975132516478483213507f95026298d8ab", [:rebar3], [], "hexpm"},
|
||||
"pow": {:hex, :pow, "1.0.15", "9267b5c75df2d59968585c042e2a0ec6217b1959d3afd629817461f0a20e903c", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.3.0 or ~> 1.4.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, ">= 2.0.0 and <= 3.0.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:plug, ">= 1.5.0 and < 2.0.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm"},
|
||||
|
|
|
@ -69,6 +69,16 @@ if [ ! -f /usr/local/bin/image-intensities ]; then
|
|||
popd
|
||||
fi
|
||||
|
||||
if [ ! -f /usr/local/bin/safe-rsvg-convert ]; then
|
||||
# passing input on stdin prevents the loading of any
|
||||
# external resources
|
||||
echo '
|
||||
#!/bin/sh
|
||||
rsvg-convert < "$1" -o "$2"
|
||||
' > /usr/local/bin/safe-rsvg-convert
|
||||
chmod +x /usr/local/bin/safe-rsvg-convert
|
||||
fi
|
||||
|
||||
sed -i -e 's/\(-Xm[sx]\)1g/\1256m/' /etc/elasticsearch/jvm.options
|
||||
systemctl enable elasticsearch 2>/dev/null
|
||||
service elasticsearch start
|
||||
|
|
Loading…
Reference in a new issue