diff options
Diffstat (limited to 'app/models/concerns')
| -rw-r--r-- | app/models/concerns/file_attachment.rb | 55 |
1 files changed, 42 insertions, 13 deletions
diff --git a/app/models/concerns/file_attachment.rb b/app/models/concerns/file_attachment.rb index 613a6f0..6221312 100644 --- a/app/models/concerns/file_attachment.rb +++ b/app/models/concerns/file_attachment.rb | |||
| @@ -31,6 +31,7 @@ module FileAttachment | |||
| 31 | 31 | ||
| 32 | IMAGE_CONTENT_TYPES = %w[image/jpeg image/gif image/png image/webp].freeze | 32 | IMAGE_CONTENT_TYPES = %w[image/jpeg image/gif image/png image/webp].freeze |
| 33 | VECTOR_CONTENT_TYPES = %w[image/svg+xml].freeze | 33 | VECTOR_CONTENT_TYPES = %w[image/svg+xml].freeze |
| 34 | RASTERIZED_CONTENT_TYPES = %w[application/pdf].freeze | ||
| 34 | DISPLAYABLE_AS_IMAGE = IMAGE_CONTENT_TYPES + VECTOR_CONTENT_TYPES | 35 | DISPLAYABLE_AS_IMAGE = IMAGE_CONTENT_TYPES + VECTOR_CONTENT_TYPES |
| 35 | 36 | ||
| 36 | included do | 37 | included do |
| @@ -52,29 +53,49 @@ module FileAttachment | |||
| 52 | build_upload_proxy | 53 | build_upload_proxy |
| 53 | end | 54 | end |
| 54 | 55 | ||
| 56 | def has_variant?(style) | ||
| 57 | upload_file_name.present? && File.exist?(file_path(style)) | ||
| 58 | end | ||
| 59 | |||
| 60 | def previewable? | ||
| 61 | has_variant?(:medium) | ||
| 62 | end | ||
| 63 | |||
| 64 | def variant_filename(style) | ||
| 65 | return upload_file_name if style == :original || !RASTERIZED_CONTENT_TYPES.include?(upload_content_type) | ||
| 66 | File.basename(upload_file_name, ".*") + ".png" | ||
| 67 | end | ||
| 68 | |||
| 55 | private | 69 | private |
| 56 | 70 | ||
| 57 | def build_upload_proxy | 71 | def build_upload_proxy |
| 58 | @upload = UploadProxy.new(self) | 72 | @upload = UploadProxy.new(self) |
| 59 | end | 73 | end |
| 60 | 74 | ||
| 75 | class_methods do | ||
| 76 | def upload_root | ||
| 77 | Rails.env.test? ? Rails.root.join("tmp", "test_uploads") : Rails.root.join("public", "system", "uploads") | ||
| 78 | end | ||
| 79 | end | ||
| 80 | |||
| 81 | def upload_root | ||
| 82 | self.class.upload_root | ||
| 83 | end | ||
| 84 | |||
| 61 | def process_upload | 85 | def process_upload |
| 62 | return unless @pending_upload | 86 | return unless @pending_upload |
| 63 | uploaded_file = @pending_upload | 87 | uploaded_file = @pending_upload |
| 64 | @pending_upload = nil | 88 | @pending_upload = nil |
| 65 | 89 | ||
| 66 | old_dir = Rails.root.join("public", "system", "uploads", id.to_s) | 90 | old_dir = upload_root.join(id.to_s) |
| 91 | |||
| 67 | FileUtils.rm_rf(old_dir) if Dir.exist?(old_dir) | 92 | FileUtils.rm_rf(old_dir) if Dir.exist?(old_dir) |
| 68 | 93 | ||
| 69 | original_path = file_path(:original) | 94 | original_path = file_path(:original) |
| 70 | FileUtils.mkdir_p(File.dirname(original_path)) | 95 | FileUtils.mkdir_p(File.dirname(original_path)) |
| 71 | FileUtils.cp(uploaded_file.tempfile.path, original_path) | 96 | FileUtils.cp(uploaded_file.tempfile.path, original_path) |
| 72 | 97 | ||
| 73 | if IMAGE_CONTENT_TYPES.include?(upload_content_type) | 98 | generate_all_variants(original_path) |
| 74 | generate_variants(original_path) | ||
| 75 | elsif VECTOR_CONTENT_TYPES.include?(upload_content_type) | ||
| 76 | generate_svg_variants(original_path) | ||
| 77 | end | ||
| 78 | end | 99 | end |
| 79 | 100 | ||
| 80 | def generate_variants(original_path) | 101 | def generate_variants(original_path) |
| @@ -93,20 +114,28 @@ module FileAttachment | |||
| 93 | end | 114 | end |
| 94 | end | 115 | end |
| 95 | 116 | ||
| 117 | def generate_all_variants(original_path) | ||
| 118 | if IMAGE_CONTENT_TYPES.include?(upload_content_type) | ||
| 119 | generate_variants(original_path) | ||
| 120 | elsif VECTOR_CONTENT_TYPES.include?(upload_content_type) | ||
| 121 | generate_svg_variants(original_path) | ||
| 122 | elsif RASTERIZED_CONTENT_TYPES.include?(upload_content_type) | ||
| 123 | generate_variants("#{original_path}[0]") | ||
| 124 | end | ||
| 125 | end | ||
| 126 | |||
| 96 | def delete_upload_files | 127 | def delete_upload_files |
| 97 | dir = Rails.root.join("public", "system", "uploads", id.to_s) | 128 | dir = upload_root.join(id.to_s) |
| 98 | FileUtils.rm_rf(dir) if Dir.exist?(dir) | 129 | FileUtils.rm_rf(dir) if Dir.exist?(dir) |
| 99 | end | 130 | end |
| 100 | 131 | ||
| 101 | def file_path(style) | 132 | def file_path(style) |
| 102 | Rails.root.join( | 133 | upload_root.join(id.to_s, style.to_s, variant_filename(style)).to_s |
| 103 | "public", "system", "uploads", | ||
| 104 | id.to_s, style.to_s, upload_file_name | ||
| 105 | ).to_s | ||
| 106 | end | 134 | end |
| 107 | 135 | ||
| 108 | def sanitize_filename(filename) | 136 | def sanitize_filename(filename) |
| 109 | File.basename(filename).gsub(/[^\w\.\-]/, '_') | 137 | name = File.basename(filename).unicode_normalize(:nfc) |
| 138 | name.gsub(/(?u)[^\w\.\-]/, '_') | ||
| 110 | end | 139 | end |
| 111 | 140 | ||
| 112 | # Proxy object returned by asset.upload, providing the Paperclip-compatible | 141 | # Proxy object returned by asset.upload, providing the Paperclip-compatible |
| @@ -118,7 +147,7 @@ module FileAttachment | |||
| 118 | 147 | ||
| 119 | def url(style = :original) | 148 | def url(style = :original) |
| 120 | return "" if @record.upload_file_name.blank? | 149 | return "" if @record.upload_file_name.blank? |
| 121 | "/system/uploads/#{@record.id}/#{style}/#{@record.upload_file_name}" | 150 | "/system/uploads/#{@record.id}/#{style}/#{@record.variant_filename(style)}" |
| 122 | end | 151 | end |
| 123 | 152 | ||
| 124 | def content_type | 153 | def content_type |
