Class: Sequel::Plugins::Attachments::Attachment

Inherits:
Object
  • Object
show all
Defined in:
lib/cortex_reaver/support/attachments.rb

Constant Summary collapse

BUFFER_SIZE =

Wraps a file associated with a parent object.

65536
DEFAULT_MODE =
0644

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent, name) ⇒ Attachment

Takes the parent record, and the short name of the file.



118
119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/cortex_reaver/support/attachments.rb', line 118

def initialize(parent, name)
  if parent.nil?
    raise ArgumentError.new("Can't attach a file to nil parent!")
  end
  if name.nil? or name.empty?
    raise ArgumentError.new("Can't create a file with no name!")
  end
  if name =~ /\/\\/
    raise ArgumentError.new("Attachment name #{name.inspect} contains evil characters!")
  end

  @parent = parent
  @name = name
end

Instance Attribute Details

#nameObject (readonly)

Returns the value of attribute name.



115
116
117
# File 'lib/cortex_reaver/support/attachments.rb', line 115

def name
  @name
end

Instance Method Details

#==(other) ⇒ Object



133
134
135
# File 'lib/cortex_reaver/support/attachments.rb', line 133

def ==(other)
  self.class == other.class and self.path == other.path rescue false
end

#deleteObject

Deletes the file on disk, which effectively deletes the attachment.



138
139
140
# File 'lib/cortex_reaver/support/attachments.rb', line 138

def delete
  FileUtils.remove_file local_path
end

#exists?Boolean

Returns true if the associated file exists.

Returns:

  • (Boolean)


143
144
145
# File 'lib/cortex_reaver/support/attachments.rb', line 143

def exists?
  File.exists? local_path
end

#file(how = 'r', mode = nil) ⇒ Object

Returns a File object for this attachment. Optionally specify a mode string, which is passed to File.new. Creates the attachment directory if necessary.



150
151
152
153
154
155
156
157
# File 'lib/cortex_reaver/support/attachments.rb', line 150

def file(how = 'r', mode = nil)
  @parent.create_attachment_directory
  if mode
    File.new local_path, how, mode
  else
    File.new local_path, how
  end
end

#file=(readable, mode = :hard_link) ⇒ Object

Replaces the file for this attachment. Readable should act like an IO object, but doesn’t necessarily have to be a file. If readable supports #path, copies or moves using FileUtils. Creates the attachment directory if necessary. Resets permissions.

If readable is a file mode behaves thus:

:hard_link adds a new hard link to readable's path
:soft_link adds a new symlink to readable's path
:copy copies the file contents using FileUtils.cp
:move moves the file.

Ramaze offers us temporary File objects from form uploads. Creating a hard link is extremely quick, saves disk space, but also doesn’t interfere with the temporary file in case someone else wants access to it.



174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
# File 'lib/cortex_reaver/support/attachments.rb', line 174

def file=(readable, mode = :hard_link)
  # Create attachment directory if necessary.
  @parent.create_attachment_directory

  if readable.respond_to? :path
    ret = case mode
    when :hard_link
      begin
        FileUtils.rm local_path if File.exist? local_path
        FileUtils.ln readable.path, local_path
      rescue
        # Hmm, try copy. Could be a cross-device link, or the FS
        # doesn't support it.
        FileUtils.copy readable.path, local_path
      end
    when :copy
      FileUtils.rm local_path if File.exist? local_path
      FileUtils.copy readable.path, local_path
    when :move
      FileUtils.rm local_path if File.exist? local_path
      FileUtils.move readable.path, local_path
    else
      raise RuntimeError.new("mode must be :hard_link :copy, or :move--got #{mode.inspect}")
    end
    reset_permissions
    ret
  else
    # Use read()

    # Rewind the IO, in case it's been read before.
    readable.rewind

    # Write the file
    buffer = ''
    File.open(local_path, 'w', DEFAULT_MODE) do |output|
      while readable.read BUFFER_SIZE, buffer
        output.write buffer
      end
    end
  end
end

#inspectObject



216
217
218
# File 'lib/cortex_reaver/support/attachments.rb', line 216

def inspect
  "#<CortexReaver::Attachment #{local_path}"
end

#local_pathObject

Returns the local path to this file.



221
222
223
# File 'lib/cortex_reaver/support/attachments.rb', line 221

def local_path
  path :local
end

#path(type = :local) ⇒ Object

Returns the path to this file.



226
227
228
229
230
231
232
233
234
235
# File 'lib/cortex_reaver/support/attachments.rb', line 226

def path(type = :local)
  case type
  when :local
    @parent.attachment_path(type) + File::SEPARATOR + @name
  when :public
    @parent.attachment_path(type) + PUBLIC_PATH_SEPARATOR + @name
  else
    raise ArgumentError.new("Type must be either :local or :public.")
  end
end

#public_pathObject

Returns the public path to this file



238
239
240
# File 'lib/cortex_reaver/support/attachments.rb', line 238

def public_path
  path :public
end

#reset_permissionsObject

Resets permissions to default



243
244
245
# File 'lib/cortex_reaver/support/attachments.rb', line 243

def reset_permissions
  FileUtils.chmod(DEFAULT_MODE, path(:local))
end

#to_sObject



247
248
249
# File 'lib/cortex_reaver/support/attachments.rb', line 247

def to_s
  local_path
end