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)



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

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



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

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



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

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



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

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

#image_sizeObject



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

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)


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

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



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

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 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



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

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



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

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



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

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

#uploaded_dataObject



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

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



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

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



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

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



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

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