Class: Attached::Attachment

Inherits:
Object
  • Object
show all
Defined in:
lib/attached/attachment.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, instance, options = {}) ⇒ Attachment

Initialize a new attachment by providing a name and the instance the attachment is associated with.

Parameters:

  • name - The name for the attachment such as ‘avatar’ or ‘photo’

  • instance - The instance the attachment is attached to

Options:

  • :path - The location where the attachment is stored

  • :styles - A hash containing optional parameters including extension and identifier

  • :credentials - A file, hash, or path used to authenticate with the specified storage medium

  • :medium - A symbol or subclass of ‘Attached::Storage::Base’ to be used

  • :processor - A symbol or subclass of ‘Attached::Processor::Base’ to be used

  • :alias - A string representing a fully qualified host alias

  • :processors - An array of processors

  • :aliases - An array of aliases



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/attached/attachment.rb', line 72

def initialize(name, instance, options = {})
  options      = self.class.options.clone.merge(options)

  options[:styles]     ||= {}
  options[:aliases]    ||= []
  options[:processors] ||= []

  @name        = name
  @instance    = instance

  @queue       = {}
  @purge       = []
  @errors      = []

  @path        = options[:path]
  @missing     = options[:missing]
  @styles      = options[:styles]
  @default     = options[:default]
  @strategy    = options[:strategy]
  @medium      = options[:medium]
  @credentials = options[:credentials]
  @processors  = options[:processors]
  @processor   = options[:processor]
  @aliases     = options[:aliases]
  @alias       = options[:alias]

  @aliases     = self.aliases << self.alias if self.alias
  @processors  = self.processors << self.processor if self.processor

  @storage     = Attached::Storage.storage(self.medium, self.credentials)

  @host        = self.storage.host
end

Instance Attribute Details

#aliasObject (readonly)

Returns the value of attribute alias.



32
33
34
# File 'lib/attached/attachment.rb', line 32

def alias
  @alias
end

#aliasesObject (readonly)

Returns the value of attribute aliases.



31
32
33
# File 'lib/attached/attachment.rb', line 31

def aliases
  @aliases
end

#credentialsObject (readonly)

Returns the value of attribute credentials.



28
29
30
# File 'lib/attached/attachment.rb', line 28

def credentials
  @credentials
end

#defaultObject (readonly)

Returns the value of attribute default.



25
26
27
# File 'lib/attached/attachment.rb', line 25

def default
  @default
end

#errorsObject (readonly)

Returns the value of attribute errors.



21
22
23
# File 'lib/attached/attachment.rb', line 21

def errors
  @errors
end

#fileObject

Returns the value of attribute file.



16
17
18
# File 'lib/attached/attachment.rb', line 16

def file
  @file
end

#hostObject (readonly)

Returns the value of attribute host.



34
35
36
# File 'lib/attached/attachment.rb', line 34

def host
  @host
end

#instanceObject (readonly)

Returns the value of attribute instance.



18
19
20
# File 'lib/attached/attachment.rb', line 18

def instance
  @instance
end

#mediumObject (readonly)

Returns the value of attribute medium.



27
28
29
# File 'lib/attached/attachment.rb', line 27

def medium
  @medium
end

#missingObject (readonly)

Returns the value of attribute missing.



23
24
25
# File 'lib/attached/attachment.rb', line 23

def missing
  @missing
end

#nameObject (readonly)

Returns the value of attribute name.



17
18
19
# File 'lib/attached/attachment.rb', line 17

def name
  @name
end

#path(style = self.default) ⇒ Object (readonly)

Access the path for an attachment.

Usage:

@object.avatar.url
@object.avatar.url(:small)
@object.avatar.url(:large)


263
264
265
# File 'lib/attached/attachment.rb', line 263

def path
  @path
end

#processorObject (readonly)

Returns the value of attribute processor.



30
31
32
# File 'lib/attached/attachment.rb', line 30

def processor
  @processor
end

#processorsObject (readonly)

Returns the value of attribute processors.



29
30
31
# File 'lib/attached/attachment.rb', line 29

def processors
  @processors
end

#purgeObject (readonly)

Returns the value of attribute purge.



20
21
22
# File 'lib/attached/attachment.rb', line 20

def purge
  @purge
end

#queueObject (readonly)

Returns the value of attribute queue.



19
20
21
# File 'lib/attached/attachment.rb', line 19

def queue
  @queue
end

#storageObject (readonly)

Returns the value of attribute storage.



33
34
35
# File 'lib/attached/attachment.rb', line 33

def storage
  @storage
end

#strategyObject (readonly)

Returns the value of attribute strategy.



26
27
28
# File 'lib/attached/attachment.rb', line 26

def strategy
  @strategy
end

#stylesObject (readonly)

Returns the value of attribute styles.



24
25
26
# File 'lib/attached/attachment.rb', line 24

def styles
  @styles
end

Class Method Details

.optionsObject

A default set of options that can be extended to customize the path, storage or credentials.

Usage:

Attached::Attachment.options = { :storage => :fs, :path => ":name/:style/:identifier:extension" }


43
44
45
46
47
48
49
50
51
# File 'lib/attached/attachment.rb', line 43

def self.options
  @options ||= {
    :path        => ":name/:style/:identifier:extension",
    :missing     => ":name/:style/missing:extension",
    :default     => :original,
    :medium      => :local,
    :credentials => {},
  }
end

Instance Method Details

#assign(file, identifier = Identifier.generate) ⇒ Object

Assign an attachment to a file.

Usage:

@object.avatar.assign(...)


157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/attached/attachment.rb', line 157

def assign(file, identifier = Identifier.generate)
  self.file = file

  if file
    extension ||= file.extension if file.respond_to? :extension
    extension ||= File.extname(file.original_filename) if file.respond_to? :original_filename
    extension ||= File.extname(file.path) if file.respond_to? :path

    size ||= file.size if file.respond_to? :size
    size ||= File.size(file.path) if file.respond_to? :path
  end

  @purge = [self.path, *self.styles.map { |style, options| self.path(style) }] if attached?

  self.size       = file ? size       : nil
  self.extension  = file ? extension  : nil
  self.identifier = file ? identifier : nil

  process if file
end

#attached?Boolean

Check if an attachment is present.

Usage:

@object.avatar.attached?

Returns:

  • (Boolean)


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

def attached?
  not identifier.blank?
end

#changed?Boolean

Check if an attachment has been modified.

Usage:

@object.avatar.changed?

Returns:

  • (Boolean)


113
114
115
# File 'lib/attached/attachment.rb', line 113

def changed?
  instance.changed.include? "#{name}_identifier"
end

#destroyObject

Destroy an attachment.

Usage:

@object.avatar.destroy


224
225
226
227
228
229
230
231
232
233
234
# File 'lib/attached/attachment.rb', line 224

def destroy
  if attached?
    self.storage.destroy(self.path)
    self.styles.each do |style, options|
      self.storage.destroy(self.path(style))
    end
  end

  @purge = []
  @queue = {}
end

#extension(style = nil) ⇒ Object

Access the extension for an attachment. It will first check the styles to see if one is specified before checking the instance.

Usage:



304
305
306
307
308
309
310
# File 'lib/attached/attachment.rb', line 304

def extension(style = nil)
  style and
  self.styles and
  self.styles[style] and
  self.styles[style][:extension] or
  instance_get(:extension)
end

#extension=(extension) ⇒ Object

Set the extension for an attachment. It will act independently of the defined style.

Usage:



358
359
360
# File 'lib/attached/attachment.rb', line 358

def extension=(extension)
  instance_set(:extension, extension)
end

#file?Boolean

Check if an attachment is present.

Usage:

@object.avatar.file?

Returns:

  • (Boolean)


124
125
126
# File 'lib/attached/attachment.rb', line 124

def file?
  not identifier.blank?
end

#identifier(style = nil) ⇒ Object

Access the identifier for an attachment. It will first check the styles to see if one is specified before checking the instance.

Usage:



320
321
322
323
324
325
326
# File 'lib/attached/attachment.rb', line 320

def identifier(style = nil)
  style and
  self.styles and
  self.styles[style] and
  self.styles[style][:identifier] or
  instance_get(:identifier)
end

#identifier=(identifier) ⇒ Object

Set the identifier for an attachment. It will act independently of the defined style.

Usage:



370
371
372
# File 'lib/attached/attachment.rb', line 370

def identifier=(identifier)
  instance_set(:identifier, identifier)
end

#reprocess!Object

Access the original file .



377
378
379
380
381
# File 'lib/attached/attachment.rb', line 377

def reprocess!
  self.file = self.storage.retrieve(self.path)

  process
end

#saveObject

Save an attachment.

Usage:

@object.avatar.save


203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/attached/attachment.rb', line 203

def save
  self.queue.each do |style, file|
    path = self.path(style)
    self.storage.save(file, path) if file and path
  end

  self.purge.each do |path|
    self.storage.destroy(path)
  end

  @purge = []
  @queue = {}
end

#sizeObject

Access the size for an attachment.

Usage:



281
282
283
# File 'lib/attached/attachment.rb', line 281

def size
  return instance_get(:size)
end

#size=(size) ⇒ Object

Set the size for an attachment.

Usage:



335
336
337
# File 'lib/attached/attachment.rb', line 335

def size=(size)
  instance_set(:size, size)
end

#statusObject

Access the status for an attachment.

Usage:



292
293
294
# File 'lib/attached/attachment.rb', line 292

def status
  instance_get(:status)
end

#status=(status) ⇒ Object

Set the status for an attachment.

Usage:



346
347
348
# File 'lib/attached/attachment.rb', line 346

def status=(status)
  instance_set(:size, status)
end

#url(style = self.default) ⇒ Object

Acesss the URL for an attachment.

Usage:

@object.avatar.url
@object.avatar.url(:small)
@object.avatar.url(:large)


245
246
247
248
249
250
251
252
# File 'lib/attached/attachment.rb', line 245

def url(style = self.default)
  path = self.path(style)

  host = self.host
  host = self.aliases[path.hash % self.aliases.count] unless self.aliases.empty?

  return "#{host}#{path}"
end

#url=(url) ⇒ Object

Assign an attachment to a file.

Usage:

@object.avatar.url = "https://.../file"


185
186
187
188
189
190
191
192
193
194
# File 'lib/attached/attachment.rb', line 185

def url=(url)
  extension = File.extname(url)

  file = Tempfile.new(["", extension])
  file.binmode

  file << open(url).read

  self.assign(file)
end