Class: CarrierWave::SanitizedFile

Inherits:
Object
  • Object
show all
Defined in:
lib/carrierwave/sanitized_file.rb

Overview

SanitizedFile is a base class which provides a common API around all the different quirky Ruby File libraries. It has support for Tempfile, File, StringIO, Merb-style upload Hashes, as well as paths given as Strings and Pathnames.

It's probably needlessly comprehensive and complex. Help is appreciated.

Class Attribute Summary collapse

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file) ⇒ SanitizedFile

Returns a new instance of SanitizedFile



33
34
35
# File 'lib/carrierwave/sanitized_file.rb', line 33

def initialize(file)
  self.file = file
end

Class Attribute Details

.sanitize_regexpObject



28
29
30
# File 'lib/carrierwave/sanitized_file.rb', line 28

def sanitize_regexp
  @sanitize_regexp ||= /[^[:word:]\.\-\+]/
end

Instance Attribute Details

#fileObject

Returns the value of attribute file



23
24
25
# File 'lib/carrierwave/sanitized_file.rb', line 23

def file
  @file
end

Instance Method Details

#basenameObject

Returns the part of the filename before the extension. So if a file is called 'test.jpeg' this would return 'test'

Returns

String

the first part of the filename



74
75
76
# File 'lib/carrierwave/sanitized_file.rb', line 74

def basename
  split_extension(filename)[0] if filename
end

#content_typeObject

Returns the content type of the file.

Returns

String

the content type of the file



266
267
268
269
270
271
272
273
# File 'lib/carrierwave/sanitized_file.rb', line 266

def content_type
  return @content_type if @content_type
  if @file.respond_to?(:content_type) and @file.content_type
    @content_type = @file.content_type.to_s.chomp
  elsif path
    @content_type = ::MIME::Types.type_for(path).first.to_s
  end
end

#content_type=(type) ⇒ Object

Sets the content type of the file.

Returns

String

the content type of the file



282
283
284
# File 'lib/carrierwave/sanitized_file.rb', line 282

def content_type=(type)
  @content_type = type
end

#copy!(new_path) ⇒ Object

Helper to create copy of file in new path.



232
233
234
235
236
237
238
# File 'lib/carrierwave/sanitized_file.rb', line 232

def copy!(new_path)
  if exists?
    FileUtils.cp(path, new_path) unless new_path == path
  else
    File.open(new_path, "wb") { |f| f.write(read) }
  end
end

#copy_to(new_path, permissions = nil, directory_permissions = nil) ⇒ CarrierWave::SanitizedFile

Creates a copy of this file and moves it to the given path. Returns the copy.

Parameters

new_path (String)

The path where the file should be copied to.

permissions (Integer)

permissions to set on the copy

directory_permissions (Integer)

permissions to set on created directories.

Returns

Returns:



219
220
221
222
223
224
225
226
227
# File 'lib/carrierwave/sanitized_file.rb', line 219

def copy_to(new_path, permissions=nil, directory_permissions=nil)
  return if self.empty?
  new_path = File.expand_path(new_path)

  mkdir!(new_path, directory_permissions)
  copy!(new_path)
  chmod!(new_path, permissions)
  self.class.new({:tempfile => new_path, :content_type => content_type})
end

#deleteObject

Removes the file from the filesystem.



243
244
245
# File 'lib/carrierwave/sanitized_file.rb', line 243

def delete
  FileUtils.rm(self.path) if exists?
end

#empty?Boolean

Returns

Boolean

whether the file is valid and has a non-zero size

Returns:

  • (Boolean)


139
140
141
# File 'lib/carrierwave/sanitized_file.rb', line 139

def empty?
  @file.nil? || self.size.nil? || (self.size.zero? && ! self.exists?)
end

#exists?Boolean

Returns

Boolean

Whether the file exists

Returns:

  • (Boolean)


148
149
150
# File 'lib/carrierwave/sanitized_file.rb', line 148

def exists?
  self.path.present? && File.exist?(self.path)
end

#extensionObject

Returns the file extension

Returns

String

the extension



85
86
87
# File 'lib/carrierwave/sanitized_file.rb', line 85

def extension
  split_extension(filename)[1] if filename
end

#filenameObject Also known as: identifier

Returns the filename, sanitized to strip out any evil characters.

Returns

String

the sanitized filename



60
61
62
# File 'lib/carrierwave/sanitized_file.rb', line 60

def filename
  sanitize(original_filename) if original_filename
end

#is_path?Boolean

Returns

Boolean

whether the file is supplied as a pathname or string.

Returns:

  • (Boolean)


130
131
132
# File 'lib/carrierwave/sanitized_file.rb', line 130

def is_path?
  !!((@file.is_a?(String) || @file.is_a?(Pathname)) && !@file.blank?)
end

#move!(new_path) ⇒ Object

Helper to move file to new path.



198
199
200
201
202
203
204
# File 'lib/carrierwave/sanitized_file.rb', line 198

def move!(new_path)
  if exists?
    FileUtils.mv(path, new_path) unless new_path == path
  else
    File.open(new_path, "wb") { |f| f.write(read) }
  end
end

#move_to(new_path, permissions = nil, directory_permissions = nil, keep_filename = false) ⇒ Object

Moves the file to the given path

Parameters

new_path (String)

The path where the file should be moved.

permissions (Integer)

permissions to set on the file in its new location.

directory_permissions (Integer)

permissions to set on created directories.



181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/carrierwave/sanitized_file.rb', line 181

def move_to(new_path, permissions=nil, directory_permissions=nil, keep_filename=false)
  return if self.empty?
  new_path = File.expand_path(new_path)

  mkdir!(new_path, directory_permissions)
  move!(new_path)
  chmod!(new_path, permissions)
  if keep_filename
    self.file = {:tempfile => new_path, :filename => original_filename}
  else
    self.file = new_path
  end
  self
end

#original_filenameObject

Returns the filename as is, without sanitizing it.

Returns

String

the unsanitized filename



44
45
46
47
48
49
50
51
# File 'lib/carrierwave/sanitized_file.rb', line 44

def original_filename
  return @original_filename if @original_filename
  if @file and @file.respond_to?(:original_filename)
    @file.original_filename
  elsif path
    File.basename(path)
  end
end

#pathObject

Returns the full path to the file. If the file has no path, it will return nil.

Returns

String, nil

the path where the file is located.



115
116
117
118
119
120
121
122
123
# File 'lib/carrierwave/sanitized_file.rb', line 115

def path
  unless @file.blank?
    if is_path?
      File.expand_path(@file)
    elsif @file.respond_to?(:path) and not @file.path.blank?
      File.expand_path(@file.path)
    end
  end
end

#readObject

Returns the contents of the file.

Returns

String

contents of the file



159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/carrierwave/sanitized_file.rb', line 159

def read
  if @content
    @content
  elsif is_path?
    File.open(@file, "rb") {|file| file.read}
  else
    @file.try(:rewind)
    @content = @file.read
    @file.try(:close) unless @file.try(:closed?)
    @content
  end
end

#sanitize_regexpObject

Used to sanitize the file name. Public to allow overriding for non-latin characters.

Returns

Regexp

the regexp for sanitizing the file name



293
294
295
# File 'lib/carrierwave/sanitized_file.rb', line 293

def sanitize_regexp
  CarrierWave::SanitizedFile.sanitize_regexp
end

#sizeObject

Returns the file's size.

Returns

Integer

the file's size in bytes.



96
97
98
99
100
101
102
103
104
105
106
# File 'lib/carrierwave/sanitized_file.rb', line 96

def size
  if is_path?
    exists? ? File.size(path) : 0
  elsif @file.respond_to?(:size)
    @file.size
  elsif path
    exists? ? File.size(path) : 0
  else
    0
  end
end

#to_fileObject

Returns a File object, or nil if it does not exist.

Returns

File

a File object representing the SanitizedFile



254
255
256
257
# File 'lib/carrierwave/sanitized_file.rb', line 254

def to_file
  return @file if @file.is_a?(File)
  File.open(path, "rb") if exists?
end