Module: AttachmentSaver::InstanceMethods

Defined in:
lib/attachment_saver.rb

Instance Method Summary collapse

Instance Method Details

#before_validate_attachmentObject

overridden by the processors (and/or by the class we’re mixed into)



114
115
116
# File 'lib/attachment_saver.rb', line 114

def before_validate_attachment # overridden by the processors (and/or by the class we're mixed into)
  # when you write code in here that needs to access the file, use the uploaded_file method to get it
end

#close_open_fileObject



109
110
111
112
# File 'lib/attachment_saver.rb', line 109

def close_open_file
  @uploaded_file.close if @uploaded_file && @uploaded_file.respond_to?(:close)
  @uploaded_file.tempfile.close if @uploaded_file.respond_to?(:tempfile) && @uploaded_file.tempfile.respond_to?(:close)
end

#file_extensionObject



140
141
142
143
144
145
# File 'lib/attachment_saver.rb', line 140

def file_extension
  extension = @file_extension
  extension = AttachmentSaver::split_filename(original_filename).last if extension.blank? && respond_to?(:original_filename) && !original_filename.blank?
  extension = 'bin' if extension.blank?
  extension
end

#file_extension=(extension) ⇒ Object

used by processors to override the original extension



136
137
138
# File 'lib/attachment_saver.rb', line 136

def file_extension=(extension) # used by processors to override the original extension
  @file_extension = extension
end

#image_sizeObject



152
153
154
# File 'lib/attachment_saver.rb', line 152

def image_size
  width.nil? || height.nil? ? nil : "#{width}x#{height}"
end

#process_attachment?Boolean

called by the datastores, overridden by the processors (and/or by the class we’re mixed into)

Returns:

  • (Boolean)


118
119
120
# File 'lib/attachment_saver.rb', line 118

def process_attachment? # called by the datastores, overridden by the processors (and/or by the class we're mixed into)
  false
end

#process_attachment_with_wrapping(filename) ⇒ Object



122
123
124
125
126
127
128
129
130
# File 'lib/attachment_saver.rb', line 122

def process_attachment_with_wrapping(filename)
  process_attachment(filename)
rescue AttachmentProcessorError
  raise # pass any exceptions of the correct type (which anything eminating from our processors should be) straight
rescue NotImplementedError
  raise
rescue Exception => ex
  raise AttachmentProcessorError, "#{ex.class}: #{ex.message}", ex.backtrace # wrap anything else
end

#save_updated_derived_childrenObject

rails automatically saves children on create, but not on update; when uploading a new image, we don’t want to save them until we’ve finished processing in case that raises & causes a rollback, so we have to save them ourselves later



156
157
158
159
# File 'lib/attachment_saver.rb', line 156

def save_updated_derived_children # rails automatically saves children on create, but not on update; when uploading a new image, we don't want to save them until we've finished processing in case that raises & causes a rollback, so we have to save them ourselves later
  @updated_derived_children.each(&:save!) unless @updated_derived_children.blank?
  @updated_derived_children = nil
end

#tempfile_directoryObject

called by uploaded_file, overridden by the file datastore, which sets it to the base dir that it saves into itself, so that the files are put on the same partition & so can be directly hardlinked rather than copied



132
133
134
# File 'lib/attachment_saver.rb', line 132

def tempfile_directory # called by uploaded_file, overridden by the file datastore, which sets it to the base dir that it saves into itself, so that the files are put on the same partition & so can be directly hardlinked rather than copied
  Dir.tmpdir
end

#trim_original_filename(filename) ⇒ Object



147
148
149
150
# File 'lib/attachment_saver.rb', line 147

def trim_original_filename(filename)
  return filename.strip if attachment_options[:keep_original_filename_path]
  filename.gsub(/^.*(\\|\/)/, '').strip
end

#uploaded_dataObject



69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/attachment_saver.rb', line 69

def uploaded_data
  if @uploaded_data.nil?
    if @uploaded_file.nil?
      nil
    else
      @uploaded_file.rewind
      @uploaded_file.read
    end
  else
    @uploaded_data
  end
end

#uploaded_data=(uploaded) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/attachment_saver.rb', line 43

def uploaded_data=(uploaded)
  # we don't go ahead and process the upload just yet - in particular, we need to wait
  # until we have all the attributes, and then until validation passes - so we just retain
  # the data or file reference for now.
  if uploaded.is_a?(String) # we allow people to upload into the file field using a normal input element (eg. a textarea)
    return if uploaded.empty? # this handles the case when a form has a file field but no file is selected - most browsers submit an empty string then (annoyingly)
    @uploaded_data = uploaded
    @uploaded_file = nil
  elsif uploaded.is_a?(StringIO)
    uploaded.rewind
    @uploaded_data = uploaded.read
    @uploaded_file = nil
  elsif uploaded
    @uploaded_data = nil
    @uploaded_file = uploaded
  else
    @uploaded_data = @uploaded_file = @save_upload = nil
    return
  end
  @save_upload = true

  self.size =              uploaded.respond_to?(:bytesize) ? uploaded.bytesize : uploaded.size if respond_to?(:size=)
  self.content_type =      uploaded.content_type.strip.downcase               if respond_to?(:content_type=) && uploaded.respond_to?(:content_type)
  self.original_filename = trim_original_filename(uploaded.original_filename) if respond_to?(:original_filename=) && uploaded.respond_to?(:original_filename)
end

#uploaded_fileObject



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
# File 'lib/attachment_saver.rb', line 82

def uploaded_file
  unless @uploaded_data.nil?
    # if we have a processor, we need to get the uploaded data into a file at some point
    # so it can be processed.  we take advantage of the fact that our file backend knows
    # how to hardlink temporary files into their final location (rather than copying) to
    # simplify things without introducing an extra file copy (so long as we put the temp
    # file in the right place); of course, for non-file backends, this file will be only
    # temporary in any case - so doing this here represents no extra overhead (remember,
    # uploaded files over the magic size built into the CGI module are saved to files in
    # the first place, so we know that the overhead here is minimal anyway).
    FileUtils.mkdir_p(tempfile_directory)
    temp = Tempfile.new("asutemp", tempfile_directory)
    temp.binmode
    temp.write(@uploaded_data)
    temp.flush
    @uploaded_file = temp
    @uploaded_data = nil
  end
  @uploaded_file
end

#uploaded_file_pathObject



103
104
105
106
107
# File 'lib/attachment_saver.rb', line 103

def uploaded_file_path
  uploaded_file.respond_to?(:tempfile) ?
    uploaded_file.tempfile.path : # rails 3
    uploaded_file.path # rails 2
end