The code powering m.abunchtell.com https://m.abunchtell.com
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.
 
 
 
 

105 lines
2.4 KiB

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