2013-02-05 14:16:51 -05:00
require 'digest/sha1'
2013-06-05 00:34:53 +02:00
require 'image_sizer'
require 's3'
require 'local_store'
2013-06-17 01:00:25 +02:00
require 'tempfile'
require 'pathname'
2013-02-05 14:16:51 -05:00
class Upload < ActiveRecord :: Base
belongs_to :user
2013-06-13 23:44:24 +02:00
has_many :post_uploads
has_many :posts , through : :post_uploads
2013-06-13 01:43:50 +02:00
2013-06-21 09:34:02 +02:00
has_many :optimized_images , dependent : :destroy
2013-06-16 10:39:48 +02:00
2013-02-05 14:16:51 -05:00
validates_presence_of :filesize
validates_presence_of :original_filename
2013-06-17 01:00:25 +02:00
def thumbnail
@thumbnail || = optimized_images . where ( width : width , height : height ) . first
end
def thumbnail_url
thumbnail . url if has_thumbnail?
end
def has_thumbnail?
thumbnail . present?
end
def create_thumbnail!
return unless SiteSetting . create_thumbnails?
2013-06-22 13:38:42 +02:00
return if SiteSetting . enable_s3_uploads?
2013-06-17 01:00:25 +02:00
return unless width > SiteSetting . auto_link_images_wider_than
return if has_thumbnail?
2013-06-17 02:46:42 +02:00
thumbnail = OptimizedImage . create_for ( self , width , height )
optimized_images << thumbnail if thumbnail
2013-06-17 01:00:25 +02:00
end
2013-06-21 09:34:02 +02:00
def destroy
2013-06-19 21:51:41 +02:00
Upload . transaction do
Upload . remove_file url
super
end
end
2013-06-15 09:54:49 +02:00
def self . create_for ( user_id , file )
2013-06-15 10:33:57 +02:00
# compute the sha
2013-06-17 22:16:14 +02:00
sha1 = Digest :: SHA1 . file ( file . tempfile ) . hexdigest
2013-06-15 10:33:57 +02:00
# check if the file has already been uploaded
2013-06-17 22:16:14 +02:00
upload = Upload . where ( sha1 : sha1 ) . first
2013-06-15 11:52:40 +02:00
2013-06-15 10:33:57 +02:00
# otherwise, create it
if upload . blank?
2013-06-15 11:52:40 +02:00
# retrieve image info
image_info = FastImage . new ( file . tempfile , raise_on_failure : true )
# compute image aspect ratio
width , height = ImageSizer . resize ( * image_info . size )
# create a db record (so we can use the id)
2013-06-15 10:33:57 +02:00
upload = Upload . create! ( {
user_id : user_id ,
original_filename : file . original_filename ,
filesize : File . size ( file . tempfile ) ,
2013-06-17 22:16:14 +02:00
sha1 : sha1 ,
2013-06-15 10:33:57 +02:00
width : width ,
height : height ,
url : " "
} )
# make sure we're at the beginning of the file (FastImage is moving the pointer)
file . rewind
# store the file and update its url
2013-07-01 02:19:03 +02:00
upload . url = Upload . store_file ( file , sha1 , image_info , upload . id )
2013-06-15 11:52:40 +02:00
# save the url
2013-06-15 10:33:57 +02:00
upload . save
end
2013-06-15 11:52:40 +02:00
# return the uploaded file
2013-04-07 17:52:46 +02:00
upload
end
2013-06-17 22:16:14 +02:00
def self . store_file ( file , sha1 , image_info , upload_id )
return S3 . store_file ( file , sha1 , image_info , upload_id ) if SiteSetting . enable_s3_uploads?
return LocalStore . store_file ( file , sha1 , image_info , upload_id )
2013-06-05 00:34:53 +02:00
end
2013-06-19 21:51:41 +02:00
def self . remove_file ( url )
S3 . remove_file ( url ) if SiteSetting . enable_s3_uploads?
LocalStore . remove_file ( url )
end
2013-06-22 13:38:42 +02:00
def self . has_been_uploaded? ( url )
is_relative? ( url ) || is_local? ( url ) || is_on_s3? ( url )
2013-06-16 10:21:01 +02:00
end
2013-06-22 13:38:42 +02:00
def self . is_relative? ( url )
( url =~ / ^ \/ [^ \/ ] / ) == 0
end
def self . is_local? ( url )
url . start_with? ( base_url )
end
def self . is_on_s3? ( url )
SiteSetting . enable_s3_uploads? && url . start_with? ( S3 . base_url )
2013-06-16 10:21:01 +02:00
end
def self . base_url
asset_host . present? ? asset_host : Discourse . base_url_no_prefix
end
def self . asset_host
ActionController :: Base . asset_host
end
2013-02-05 14:16:51 -05:00
end
2013-05-24 12:48:32 +10:00
# == Schema Information
#
# Table name: uploads
#
# id :integer not null, primary key
# user_id :integer not null
# original_filename :string(255) not null
# filesize :integer not null
# width :integer
# height :integer
# url :string(255) not null
# created_at :datetime not null
# updated_at :datetime not null
2013-06-17 22:16:14 +02:00
# sha1 :string(40)
2013-05-24 12:48:32 +10:00
#
# Indexes
#
2013-06-17 22:16:14 +02:00
# index_uploads_on_sha1 (sha1) UNIQUE
2013-06-22 13:38:42 +02:00
# index_uploads_on_url (url)
2013-06-17 02:48:58 +02:00
# index_uploads_on_user_id (user_id)
2013-05-24 12:48:32 +10:00
#
2013-06-17 02:48:58 +02:00