You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

83 lines
1.8 KiB

  1. # frozen_string_literal: true
  2. class MediaAttachment < ApplicationRecord
  3. IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif'].freeze
  4. VIDEO_MIME_TYPES = ['video/webm', 'video/mp4'].freeze
  5. belongs_to :account, inverse_of: :media_attachments
  6. belongs_to :status, inverse_of: :media_attachments
  7. has_attached_file :file,
  8. styles: -> (f) { file_styles f },
  9. processors: -> (f) { f.video? ? [:transcoder] : [:thumbnail] },
  10. convert_options: { all: '-quality 90 -strip' }
  11. validates_attachment_content_type :file, content_type: IMAGE_MIME_TYPES + VIDEO_MIME_TYPES
  12. validates_attachment_size :file, less_than: 8.megabytes
  13. validates :account, presence: true
  14. scope :local, -> { where(remote_url: '') }
  15. default_scope { order('id asc') }
  16. def local?
  17. remote_url.blank?
  18. end
  19. def file_remote_url=(url)
  20. self.file = URI.parse(url)
  21. end
  22. def image?
  23. IMAGE_MIME_TYPES.include? file_content_type
  24. end
  25. def video?
  26. VIDEO_MIME_TYPES.include? file_content_type
  27. end
  28. def type
  29. image? ? 'image' : 'video'
  30. end
  31. def to_param
  32. shortcode
  33. end
  34. before_create :set_shortcode
  35. class << self
  36. private
  37. def file_styles(f)
  38. if f.instance.image?
  39. {
  40. original: '1280x1280>',
  41. small: '400x400>',
  42. }
  43. else
  44. {
  45. small: {
  46. convert_options: {
  47. output: {
  48. vf: 'scale=\'min(400\, iw):min(400\, ih)\':force_original_aspect_ratio=decrease',
  49. },
  50. },
  51. format: 'png',
  52. time: 1,
  53. },
  54. }
  55. end
  56. end
  57. end
  58. private
  59. def set_shortcode
  60. return unless local?
  61. loop do
  62. self.shortcode = SecureRandom.urlsafe_base64(14)
  63. break if MediaAttachment.find_by(shortcode: shortcode).nil?
  64. end
  65. end
  66. end