From 78fa65264664c590906042910e5bf53d128a6935 Mon Sep 17 00:00:00 2001 From: evazion Date: Sun, 16 Oct 2022 19:41:19 -0500 Subject: [PATCH] media assets: make file storage paths and URLs configurable. Add config options to customize where uploads are stored, and how image URLs are generated. * Add `media_asset_file_path` option to customize where uploads are stored. * Add `media_asset_file_url` option to customize how image URLs are generated. * Remove the `enable_seo_post_urls` config option. The `media_asset_file_url` option should be used instead to include the tags in the image URL. --- app/models/media_asset.rb | 30 ++++++++-------- config/danbooru_default_config.rb | 59 +++++++++++++++++++++++++++---- 2 files changed, 67 insertions(+), 22 deletions(-) diff --git a/app/models/media_asset.rb b/app/models/media_asset.rb index fb093632a..958978cfa 100644 --- a/app/models/media_asset.rb +++ b/app/models/media_asset.rb @@ -11,7 +11,6 @@ class MediaAsset < ApplicationRecord MAX_IMAGE_RESOLUTION = Danbooru.config.max_image_resolution MAX_IMAGE_WIDTH = Danbooru.config.max_image_width MAX_IMAGE_HEIGHT = Danbooru.config.max_image_height - ENABLE_SEO_POST_URLS = Danbooru.config.enable_seo_post_urls LARGE_IMAGE_WIDTH = Danbooru.config.large_image_width STORAGE_SERVICE = Danbooru.config.storage_manager @@ -54,12 +53,12 @@ class MediaAsset < ApplicationRecord include ActiveModel::Serializers::JSON include ActiveModel::Serializers::Xml - attr_reader :media_asset, :variant - delegate :md5, :storage_service, :backup_storage_service, to: :media_asset + attr_reader :media_asset, :type + delegate :id, :md5, :file_key, :storage_service, :backup_storage_service, to: :media_asset - def initialize(media_asset, variant) + def initialize(media_asset, type) @media_asset = media_asset - @variant = variant.to_sym + @type = type.to_sym end def store_file!(original_file) @@ -85,7 +84,7 @@ class MediaAsset < ApplicationRecord end def convert_file(media_file) - case variant + case type in :preview media_file.preview(width, height, format: :jpeg, quality: 85) in :"180x180" @@ -103,19 +102,18 @@ class MediaAsset < ApplicationRecord end end - def file_url(slug = "") - storage_service.file_url(file_path(slug)) + def file_url(custom_filename = "") + url = Danbooru.config.media_asset_file_url(self, custom_filename) + storage_service.file_url(url) end - def file_path(slug = "") - slug = "__#{slug}__" if slug.present? - slug = nil if !ENABLE_SEO_POST_URLS - "/#{variant}/#{md5[0..1]}/#{md5[2..3]}/#{slug}#{file_name}" + def file_path + Danbooru.config.media_asset_file_path(self) end # The file name of this variant. def file_name - case variant + case type when :sample "sample-#{md5}.#{file_ext}" else @@ -125,7 +123,7 @@ class MediaAsset < ApplicationRecord # The file extension of this variant. def file_ext - case variant + case type when :preview, :"180x180", :"360x360" "jpg" when :"720x720" @@ -138,7 +136,7 @@ class MediaAsset < ApplicationRecord end def max_dimensions - case variant + case type when :preview [150, 150] when :"180x180" @@ -167,7 +165,7 @@ class MediaAsset < ApplicationRecord end def serializable_hash(*options) - { variant: variant, url: file_url, width: width, height: height, file_ext: file_ext } + { type: type, url: file_url, width: width, height: height, file_ext: file_ext } end memoize :file_name, :file_ext, :max_dimensions, :dimensions diff --git a/config/danbooru_default_config.rb b/config/danbooru_default_config.rb index fc9ce80a0..5fc898f04 100644 --- a/config/danbooru_default_config.rb +++ b/config/danbooru_default_config.rb @@ -239,7 +239,59 @@ module Danbooru } end - # The method to use for storing image files. + # The path to where uploaded files are stored. You can change this to change where files are + # stored. By default, files are stored like this: + # + # * /original/94/43/944364e77f56183e2ebd75de757488e2.jpg + # * /sample/94/43/sample-944364e77f56183e2ebd75de757488e2.jpg + # * /180x180/94/43/944364e77f56183e2ebd75de757488e2.jpg + # + # A variant is a thumbnail or other alternate version of an uploaded file; see the Variant class + # in app/models/media_asset.rb for details. + # + # This path is relative to the `base_dir` option in the storage manager (see the `storage_manager` option below). + def media_asset_file_path(variant) + md5 = variant.md5 + file_prefix = "sample-" if variant.type == :sample + "/#{variant.type}/#{md5[0..1]}/#{md5[2..3]}/#{file_prefix}#{md5}.#{variant.file_ext}" + + # To store files in this format: `/original/944364e77f56183e2ebd75de757488e2.jpg` + # "/#{variant.type}/#{variant.md5}.#{variant.file_ext}" + # + # To store files in this format: `/original/iuQRl7d7n.jpg` + # "/#{variant.type}/#{variant.file_key}.#{variant.file_ext}" + # + # To store files in this format: `/original/12345.jpg` + # "/#{variant.type}/#{variant.id}.#{variant.file_ext}" + end + + # The URL where uploaded files are served from. You can change this to customize how images are + # served. By default, files are served from the same location where they're stored. + # + # `custom_filename` is an optional tag string that may be included in the URL. It requires Nginx + # rewrites to work (see below), so it's ignored by default. + # + # The URL is relative to the `base_url` option in the storage manager (see the `storage_manager` option below). + def media_asset_file_url(variant, custom_filename) + media_asset_file_path(variant) + + # To serve files in this format: + # + # /original/d3/4e/__kousaka_tamaki_to_heart_2_drawn_by_kyogoku_shin__d34e4cf0a437a5d65f8e82b7bcd02606.jpg. + # + # Uncomment the code below and add the following to Nginx: + # + # # Strip tags from filenames (/original/d3/4e/__kousaka_tamaki_to_heart_2_drawn_by_kyogoku_shin__d34e4cf0a437a5d65f8e82b7bcd02606.jpg => /original/d3/4e/d34e4cf0a437a5d65f8e82b7bcd02606.jpg) + # location ~ (.*)/__.+?__(.+)$ { + # rewrite (.*)/__.+?__(.+)$ $1/$2; + # } + # + # custom_filename = "__#{custom_filename}__" if custom_filename.present? + # file_prefix = "sample-" if variant.type == :sample + # "/#{variant.type}/#{variant.md5[0..1]}/#{variant.md5[2..3]}/#{custom_filename}#{file_prefix}#{variant.md5}.#{variant.file_ext}" + end + + # The method to use for storing uploaded files. By default, uploads are stored under `public/data`. def storage_manager # Store files on the local filesystem. # base_dir - where to store files (default: under public/data) @@ -527,11 +579,6 @@ module Danbooru "https://twitter.com/#{Danbooru.config.twitter_username}" end - # include essential tags in image urls (requires nginx/apache rewrites) - def enable_seo_post_urls - false - end - def http_proxy_host end