2013-11-05 19:04:47 +01:00
require 'file_store/base_store'
2013-07-31 23:26:34 +02:00
2013-11-05 19:04:47 +01:00
module FileStore
2013-07-31 23:26:34 +02:00
2013-11-05 19:04:47 +01:00
class LocalStore < BaseStore
2013-07-31 23:26:34 +02:00
2014-04-15 13:04:14 +02:00
def store_upload ( file , upload , content_type = nil )
2013-11-05 19:04:47 +01:00
path = get_path_for_upload ( file , upload )
store_file ( file , path )
end
2013-08-13 22:08:29 +02:00
2013-11-05 19:04:47 +01:00
def store_optimized_image ( file , optimized_image )
path = get_path_for_optimized_image ( file , optimized_image )
store_file ( file , path )
end
2013-08-13 22:08:29 +02:00
2013-11-05 19:04:47 +01:00
def remove_upload ( upload )
remove_file ( upload . url )
end
2013-07-31 23:26:34 +02:00
2013-11-05 19:04:47 +01:00
def remove_optimized_image ( optimized_image )
remove_file ( optimized_image . url )
end
2013-07-31 23:26:34 +02:00
2013-11-05 19:04:47 +01:00
def has_been_uploaded? ( url )
2014-07-18 17:54:18 +02:00
url . present? && ( is_relative? ( url ) || is_local? ( url ) )
2013-11-05 19:04:47 +01:00
end
2013-07-31 23:26:34 +02:00
2013-11-05 19:04:47 +01:00
def absolute_base_url
" #{ Discourse . base_url_no_prefix } #{ relative_base_url } "
end
2013-07-31 23:26:34 +02:00
2013-11-05 19:04:47 +01:00
def relative_base_url
" /uploads/ #{ RailsMultisite :: ConnectionManagement . current_db } "
end
2013-07-31 23:26:34 +02:00
2014-10-15 19:20:04 +02:00
def download_url ( upload )
return unless upload
" #{ relative_base_url } / #{ upload . sha1 } "
end
2013-11-05 19:04:47 +01:00
def external?
! internal?
end
2013-07-31 23:26:34 +02:00
2013-11-05 19:04:47 +01:00
def internal?
true
end
2013-07-31 23:26:34 +02:00
2013-11-05 19:04:47 +01:00
def path_for ( upload )
" #{ public_dir } #{ upload . url } "
end
2013-08-13 22:08:29 +02:00
2013-11-27 22:01:41 +01:00
def purge_tombstone ( grace_period )
` find #{ tombstone_dir } -mtime + #{ grace_period } -type f -delete `
end
2013-11-05 19:04:47 +01:00
private
2013-08-13 22:08:29 +02:00
2013-11-05 19:04:47 +01:00
def get_path_for_upload ( file , upload )
2015-05-19 12:31:12 +02:00
get_path_for ( " original " . freeze , upload . sha1 , upload . extension )
2013-11-05 19:04:47 +01:00
end
2013-08-13 22:08:29 +02:00
2013-11-05 19:04:47 +01:00
def get_path_for_optimized_image ( file , optimized_image )
2015-05-19 12:31:12 +02:00
extension = " _ #{ optimized_image . width } x #{ optimized_image . height } #{ optimized_image . extension } "
get_path_for ( " optimized " . freeze , optimized_image . sha1 , extension )
end
def get_path_for ( type , sha , extension )
" #{ relative_base_url } / #{ type } / #{ sha [ 0 ] } / #{ sha [ 1 ] } / #{ sha } #{ extension } "
2013-11-05 19:04:47 +01:00
end
2013-08-13 22:08:29 +02:00
2013-11-05 19:04:47 +01:00
def store_file ( file , path )
# copy the file to the right location
copy_file ( file , " #{ public_dir } #{ path } " )
# url
" #{ Discourse . base_uri } #{ path } "
2013-07-31 23:26:34 +02:00
end
2013-11-05 19:04:47 +01:00
def copy_file ( file , path )
FileUtils . mkdir_p ( Pathname . new ( path ) . dirname )
# move the file to the right location
2013-11-27 22:01:41 +01:00
# not using mv, cause permissions are no good on move
File . open ( path , " wb " ) { | f | f . write ( file . read ) }
2013-11-05 19:04:47 +01:00
end
2013-08-13 22:08:29 +02:00
2013-11-05 19:04:47 +01:00
def remove_file ( url )
2013-11-27 22:01:41 +01:00
return unless is_relative? ( url )
path = public_dir + url
tombstone = public_dir + url . gsub ( " /uploads/ " , " /tombstone/ " )
FileUtils . mkdir_p ( Pathname . new ( tombstone ) . dirname )
FileUtils . move ( path , tombstone )
2013-11-05 19:04:47 +01:00
rescue Errno :: ENOENT
# don't care if the file isn't there
end
2013-08-13 22:08:29 +02:00
2013-11-05 19:04:47 +01:00
def is_relative? ( url )
2014-07-18 17:54:18 +02:00
url . present? && url . start_with? ( relative_base_url )
2013-11-05 19:04:47 +01:00
end
2013-07-31 23:26:34 +02:00
2013-11-05 19:04:47 +01:00
def is_local? ( url )
2014-07-18 17:54:18 +02:00
return false if url . blank?
2013-12-16 11:44:59 +01:00
absolute_url = url . start_with? ( " // " ) ? SiteSetting . scheme + " : " + url : url
2013-11-05 19:04:47 +01:00
absolute_url . start_with? ( absolute_base_url ) || absolute_url . start_with? ( absolute_base_cdn_url )
end
2013-07-31 23:26:34 +02:00
2013-11-05 19:04:47 +01:00
def absolute_base_cdn_url
" #{ Discourse . asset_host } #{ relative_base_url } "
end
def public_dir
" #{ Rails . root } /public "
end
2013-07-31 23:26:34 +02:00
2013-11-27 22:01:41 +01:00
def tombstone_dir
public_dir + relative_base_url . gsub ( " /uploads/ " , " /tombstone/ " )
end
2013-07-31 23:26:34 +02:00
end
end