miscellaneous fixes

This commit is contained in:
byte[] 2019-11-27 00:51:20 -05:00
parent 2d762e9645
commit 31d05e312c
6 changed files with 90 additions and 48 deletions

View file

@ -56,6 +56,11 @@ defmodule Philomena.Images do
Multi.new Multi.new
|> Multi.insert(:image, image) |> Multi.insert(:image, image)
|> Multi.run(:name_caches, fn repo, %{image: image} ->
image
|> Image.cache_changeset()
|> repo.update()
end)
|> Multi.run(:added_tag_count, fn repo, %{image: image} -> |> Multi.run(:added_tag_count, fn repo, %{image: image} ->
tag_ids = image.added_tags |> Enum.map(& &1.id) tag_ids = image.added_tags |> Enum.map(& &1.id)
tags = Tag |> where([t], t.id in ^tag_ids) tags = Tag |> where([t], t.id in ^tag_ids)

View file

@ -7,6 +7,7 @@ defmodule Philomena.Images.Image do
doc_type: "image" doc_type: "image"
import Ecto.Changeset import Ecto.Changeset
import Ecto.Query
alias Philomena.ImageIntensities.ImageIntensity alias Philomena.ImageIntensities.ImageIntensity
alias Philomena.ImageVotes.ImageVote alias Philomena.ImageVotes.ImageVote
@ -22,6 +23,7 @@ defmodule Philomena.Images.Image do
alias Philomena.Images.TagDiffer alias Philomena.Images.TagDiffer
alias Philomena.Images.TagValidator alias Philomena.Images.TagValidator
alias Philomena.Repo
schema "images" do schema "images" do
belongs_to :user, User belongs_to :user, User
@ -138,7 +140,7 @@ defmodule Philomena.Images.Image do
|> validate_number(:image_height, greater_than: 0, less_than_or_equal_to: 32767) |> validate_number(:image_height, greater_than: 0, less_than_or_equal_to: 32767)
|> validate_length(:image_name, max: 255, count: :bytes) |> validate_length(:image_name, max: 255, count: :bytes)
|> validate_inclusion(:image_mime_type, ~W(image/gif image/jpeg image/png image/svg+xml video/webm)) |> validate_inclusion(:image_mime_type, ~W(image/gif image/jpeg image/png image/svg+xml video/webm))
|> unsafe_validate_unique([:image_sha512_hash], Philomena.Repo) |> unsafe_validate_unique([:image_sha512_hash], Repo)
end end
def source_changeset(image, attrs) do def source_changeset(image, attrs) do
@ -153,6 +155,7 @@ defmodule Philomena.Images.Image do
|> cast(attrs, []) |> cast(attrs, [])
|> TagDiffer.diff_input(old_tags, new_tags) |> TagDiffer.diff_input(old_tags, new_tags)
|> TagValidator.validate_tags() |> TagValidator.validate_tags()
|> cache_changeset()
end end
def thumbnail_changeset(image, attrs) do def thumbnail_changeset(image, attrs) do
@ -166,4 +169,51 @@ defmodule Philomena.Images.Image do
|> cast(attrs, [:image_sha512_hash]) |> cast(attrs, [:image_sha512_hash])
|> change(processed: true) |> change(processed: true)
end end
def cache_changeset(image) do
changeset = change(image)
image = apply_changes(changeset)
{tag_list_cache, tag_list_plus_alias_cache, file_name_cache} =
create_caches(image.id, image.tags)
changeset
|> 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)
end
defp create_caches(image_id, tags) do
tags = Tag.display_order(tags)
tag_list_cache =
tags
|> Enum.map_join(", ", & &1.name)
tag_ids =
tags |> Enum.map(& &1.id)
aliases =
Tag
|> where([t], t.aliased_tag_id in ^tag_ids)
|> Repo.all()
tag_list_plus_alias_cache =
(tags ++ aliases)
|> Tag.display_order()
|> Enum.map_join(", ", & &1.name)
# Truncate 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 end

View file

@ -17,15 +17,9 @@ defmodule Philomena.Images.TagDiffer do
{tags, actually_added, actually_removed} = {tags, actually_added, actually_removed} =
apply_changes(tags, added_tags, removed_tags) apply_changes(tags, added_tags, removed_tags)
{tag_list_cache, tag_list_plus_alias_cache, file_name_cache} =
create_caches(image_id, tags)
changeset changeset
|> put_change(:added_tags, actually_added) |> put_change(:added_tags, actually_added)
|> put_change(:removed_tags, actually_removed) |> 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) |> put_assoc(:tags, tags)
end end
@ -95,38 +89,4 @@ defmodule Philomena.Images.TagDiffer do
{tags, actually_added, actually_removed} {tags, actually_added, actually_removed}
end end
defp create_caches(image_id, tags) do
tags = Tag.display_order(tags)
tag_list_cache =
tags
|> Enum.map_join(", ", & &1.name)
tag_ids =
tags |> Enum.map(& &1.id)
aliases =
Tag
|> where([t], t.aliased_tag_id in ^tag_ids)
|> Repo.all()
tag_list_plus_alias_cache =
(tags ++ aliases)
|> Tag.display_order()
|> Enum.map_join(", ", & &1.name)
# 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 end

View file

@ -15,10 +15,25 @@ defmodule PhilomenaWeb.AppView do
years: "%d years" years: "%d years"
} }
@months %{
1 => "January",
2 => "February",
3 => "March",
4 => "April",
5 => "May",
6 => "June",
7 => "July",
8 => "August",
9 => "September",
10 => "October",
11 => "November",
12 => "December"
}
def pretty_time(time) do def pretty_time(time) do
seconds = NaiveDateTime.diff(NaiveDateTime.utc_now(), time, :second) seconds = NaiveDateTime.diff(NaiveDateTime.utc_now(), time, :second)
relation = if seconds < 0, do: "from now", else: "ago" relation = if seconds < 0, do: "from now", else: "ago"
time = time |> DateTime.from_naive!("Etc/UTC") |> DateTime.to_iso8601() time = time |> DateTime.from_naive!("Etc/UTC")
seconds = abs(seconds) seconds = abs(seconds)
minutes = abs(div(seconds, 60)) minutes = abs(div(seconds, 60))
@ -42,7 +57,7 @@ defmodule PhilomenaWeb.AppView do
true -> String.replace(@time_strings[:years], "%d", to_string(years)) true -> String.replace(@time_strings[:years], "%d", to_string(years))
end end
content_tag(:time, "#{words} #{relation}", datetime: time, title: time) content_tag(:time, "#{words} #{relation}", datetime: DateTime.to_iso8601(time), title: datetime_string(time))
end end
def can?(conn, action, model) do def can?(conn, action, model) do
@ -76,4 +91,16 @@ defmodule PhilomenaWeb.AppView do
submit text, class: class, data: data submit text, class: class, data: data
end) end)
end end
defp datetime_string(time) do
:io_lib.format("~2..0B:~2..0B:~2..0B, ~s ~B, ~B", [
time.hour,
time.minute,
time.second,
@months[time.month],
time.day,
time.year
])
|> to_string()
end
end end

View file

@ -12,7 +12,7 @@ defmodule PhilomenaWeb.ImageView do
medium: thumb_url(image, show_hidden, :medium), medium: thumb_url(image, show_hidden, :medium),
large: thumb_url(image, show_hidden, :large), large: thumb_url(image, show_hidden, :large),
tall: thumb_url(image, show_hidden, :tall), tall: thumb_url(image, show_hidden, :tall),
full: thumb_url(image, show_hidden, :full) full: pretty_url(image, true, false)
} }
end end
@ -27,7 +27,7 @@ defmodule PhilomenaWeb.ImageView do
id_fragment = id_fragment =
if deleted and show_hidden do if deleted and show_hidden do
"#{image.id}-#{image.hidden_image_Key}" "#{image.id}-#{image.hidden_image_key}"
else else
"#{image.id}" "#{image.id}"
end end
@ -35,12 +35,12 @@ defmodule PhilomenaWeb.ImageView do
"#{root}/#{year}/#{month}/#{day}/#{id_fragment}/#{name}.#{format}" "#{root}/#{year}/#{month}/#{day}/#{id_fragment}/#{name}.#{format}"
end end
def pretty_url(image, _short, download) do def pretty_url(image, short, download) do
%{year: year, month: month, day: day} = image.created_at %{year: year, month: month, day: day} = image.created_at
root = image_url_root() root = image_url_root()
view = if download, do: "download", else: "view" view = if download, do: "download", else: "view"
filename = "#{image.id}" filename = if short, do: image.id, else: image.file_name_cache
format = format =
image.image_format image.image_format
|> String.downcase() |> String.downcase()

View file

@ -11,7 +11,7 @@ server {
location ~ ^/img/view/(.+)/([0-9]+).*\.([A-Za-z]+)$ { location ~ ^/img/view/(.+)/([0-9]+).*\.([A-Za-z]+)$ {
expires max; expires max;
add_header Cache-Control public; add_header Cache-Control public;
alias "APP_DIR/priv/static/images/thumbs/$1/$2/full.$3"; alias "APP_DIR/priv/static/system/images/thumbs/$1/$2/full.$3";
} }
location ~ ^/img/download/(.+)/([0-9]+).*\.([A-Za-z]+)$ { location ~ ^/img/download/(.+)/([0-9]+).*\.([A-Za-z]+)$ {