uploads: factor out image dimension and filetype detection code.
* Add MediaFile abstraction. A MediaFile represents an image or video file. * Move filetype detection and dimension parsing code from uploads to MediaFile.
This commit is contained in:
77
app/logical/media_file.rb
Normal file
77
app/logical/media_file.rb
Normal file
@@ -0,0 +1,77 @@
|
||||
class MediaFile
|
||||
extend Memoist
|
||||
attr_accessor :file
|
||||
|
||||
# delegate all File methods to `file`.
|
||||
delegate *(File.instance_methods - MediaFile.instance_methods), to: :file
|
||||
|
||||
def self.open(file)
|
||||
file = Kernel.open(file, "r", binmode: true) unless file.respond_to?(:read)
|
||||
|
||||
case file_ext(file)
|
||||
when :jpg, :gif, :png
|
||||
MediaFile::Image.new(file)
|
||||
when :swf
|
||||
MediaFile::Flash.new(file)
|
||||
when :webm, :mp4
|
||||
MediaFile::Video.new(file)
|
||||
when :zip
|
||||
MediaFile::Ugoira.new(file)
|
||||
else
|
||||
MediaFile.new(file)
|
||||
end
|
||||
end
|
||||
|
||||
def self.file_ext(file)
|
||||
header = file.pread(16, 0)
|
||||
|
||||
case header
|
||||
when /\A\xff\xd8/n
|
||||
:jpg
|
||||
when /\AGIF87a/, /\AGIF89a/
|
||||
:gif
|
||||
when /\A\x89PNG\r\n\x1a\n/n
|
||||
:png
|
||||
when /\ACWS/, /\AFWS/, /\AZWS/
|
||||
:swf
|
||||
when /\x1a\x45\xdf\xa3/n
|
||||
:webm
|
||||
when /\A....ftyp(?:isom|3gp5|mp42|MSNV|avc1)/
|
||||
:mp4
|
||||
when /\APK\x03\x04/
|
||||
:zip
|
||||
else
|
||||
:bin
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(file)
|
||||
@file = file
|
||||
end
|
||||
|
||||
def dimensions
|
||||
[0, 0]
|
||||
end
|
||||
|
||||
def width
|
||||
dimensions.first
|
||||
end
|
||||
|
||||
def height
|
||||
dimensions.second
|
||||
end
|
||||
|
||||
def md5
|
||||
Digest::MD5.file(file.path).hexdigest
|
||||
end
|
||||
|
||||
def file_ext
|
||||
MediaFile.file_ext(file)
|
||||
end
|
||||
|
||||
def file_size
|
||||
file.size
|
||||
end
|
||||
|
||||
memoize :dimensions, :file_ext, :file_size, :md5
|
||||
end
|
||||
Reference in New Issue
Block a user