Class: CarrierWave::SanitizedFile

Inherits:
Object
  • Object
show all
Includes:
Utilities::FileName
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

Methods included from Utilities::FileName

#basename, #extension

Constructor Details

#initialize(file) ⇒ SanitizedFile

Returns a new instance of SanitizedFile.



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

def initialize(file)
  self.file = file
  @content = @content_type = nil
end

Class Attribute Details

.sanitize_regexpObject



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

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

Instance Attribute Details

#fileObject

Returns the value of attribute file.



17
18
19
# File 'lib/carrierwave/sanitized_file.rb', line 17

def file
  @file
end

Instance Method Details

#content_typeObject

Returns the content type of the file.

Returns

String

the content type of the file



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

def content_type
  @content_type ||=
    identified_content_type ||
    declared_content_type ||
    guessed_safe_content_type ||
    Marcel::MimeType::BINARY
end

#content_type=(type) ⇒ Object

Sets the content type of the file.

Returns

String

the content type of the file



266
267
268
# File 'lib/carrierwave/sanitized_file.rb', line 266

def content_type=(type)
  @content_type = type
end

#copy!(new_path) ⇒ Object

Helper to create copy of file in new path.



217
218
219
220
221
222
223
# File 'lib/carrierwave/sanitized_file.rb', line 217

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:



204
205
206
207
208
209
210
211
212
# File 'lib/carrierwave/sanitized_file.rb', line 204

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: declared_content_type})
end

#deleteObject

Removes the file from the filesystem.



228
229
230
# File 'lib/carrierwave/sanitized_file.rb', line 228

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)


110
111
112
# File 'lib/carrierwave/sanitized_file.rb', line 110

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

#exists?Boolean

Returns

Boolean

Whether the file exists

Returns:

  • (Boolean)


119
120
121
# File 'lib/carrierwave/sanitized_file.rb', line 119

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

#filenameObject Also known as: identifier

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

Returns

String

the sanitized filename



55
56
57
# File 'lib/carrierwave/sanitized_file.rb', line 55

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)


101
102
103
# File 'lib/carrierwave/sanitized_file.rb', line 101

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.



183
184
185
186
187
188
189
# File 'lib/carrierwave/sanitized_file.rb', line 183

def move!(new_path)
  if exists?
    FileUtils.mv(path, new_path) unless File.identical?(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.



169
170
171
172
173
174
175
176
177
178
# File 'lib/carrierwave/sanitized_file.rb', line 169

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)
  self.file = {tempfile: new_path, filename: keep_filename ? original_filename : nil, content_type: declared_content_type}
  self
end

#original_filenameObject

Returns the filename as is, without sanitizing it.

Returns

String

the unsanitized filename



39
40
41
42
43
44
45
46
# File 'lib/carrierwave/sanitized_file.rb', line 39

def original_filename
  return @original_filename if @original_filename
  if @file && @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.



87
88
89
90
91
92
93
94
# File 'lib/carrierwave/sanitized_file.rb', line 87

def path
  return if @file.blank?
  if is_path?
    File.expand_path(@file)
  elsif @file.respond_to?(:path) && !@file.path.blank?
    File.expand_path(@file.path)
  end
end

#read(*args) ⇒ Object

Returns the contents of the file.

Returns

String

contents of the file



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/carrierwave/sanitized_file.rb', line 130

def read(*args)
  if args.empty?
    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.class.ancestors.include?(::StringIO) || @file.try(:closed?)
      @content
    end
  else
    if is_path?
      @file = File.open(path, "rb")
    elsif @file.is_a?(CarrierWave::Uploader::Base)
      @file = StringIO.new(@file.read)
    end

    @file.read(*args)
  end
end

#rewindObject

Rewinds the underlying file.



156
157
158
# File 'lib/carrierwave/sanitized_file.rb', line 156

def rewind
  @file.rewind if @file.respond_to?(:rewind)
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



277
278
279
# File 'lib/carrierwave/sanitized_file.rb', line 277

def sanitize_regexp
  CarrierWave::SanitizedFile.sanitize_regexp
end

#sizeObject

Returns the file’s size.

Returns

Integer

the file’s size in bytes.



68
69
70
71
72
73
74
75
76
77
78
# File 'lib/carrierwave/sanitized_file.rb', line 68

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



239
240
241
242
# File 'lib/carrierwave/sanitized_file.rb', line 239

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