Class: Nozzle::Adapter::Base

Inherits:
Object
  • Object
show all
Includes:
Outlet
Defined in:
lib/nozzle/adapter/base.rb

Direct Known Subclasses

Image

Constant Summary collapse

MIN_PATH_MAX =

minimum filename length for Nozzle to try and fit it to the filesystem.

255

Instance Method Summary collapse

Methods included from Outlet

#cleanup!, included, #outlets, #prepare, #prepare!

Constructor Details

#initialize(record, column, filename, options = {}) ⇒ Base

Initializes internal structure of new adapter.

outlet_class.new( instance, :avatar, 'image.jpg', :fake => true )


16
17
18
19
20
21
22
# File 'lib/nozzle/adapter/base.rb', line 16

def initialize( record, column, filename, options = {} )
  @record = record
  @model = record.class
  @column = column.to_sym
  @filename = filename
  settings.merge! options
end

Instance Method Details

#access_pathObject

Returns intermediate path to the tempfile if the record is not yet saved and file is not yet stored at path.



74
75
76
# File 'lib/nozzle/adapter/base.rb', line 74

def access_path
  @tempfile_path || path
end

#adapter_folderObject

Returns folder name of the adapter relative to application public.

instance.avatar.adapter_folder # => 'uploads'

This MAY be overridden to specify where all the files should be stored.



113
114
115
# File 'lib/nozzle/adapter/base.rb', line 113

def adapter_folder
  'uploads'
end

#adapter_pathObject

Returns filesystem folder path of the adapter relative to adapter root.

instance.avatar.adapter_path # => 'public/uploads'

It is constructed from #root, ‘public’ and #adapter_folder.



120
121
122
# File 'lib/nozzle/adapter/base.rb', line 120

def adapter_path
  File.join root, adapter_folder
end

#as_json(*args) ⇒ Object



208
209
210
# File 'lib/nozzle/adapter/base.rb', line 208

def as_json(*args)
  { :url => url }
end

#content_typeObject

Returns file content_type stored in avatar_content_type column of the record.



80
81
82
# File 'lib/nozzle/adapter/base.rb', line 80

def content_type
  @record.send( :"#{@column}_content_type" )  rescue ''
end

#default_urlObject

Returns nil. This SHOULD be overridden by subclasses of Nozzle::Adapter::Base.

instance.avatar.default_url # => nil


98
99
100
# File 'lib/nozzle/adapter/base.rb', line 98

def default_url
  nil
end

#deleteObject

Sets adapter to delete stored file on #adapеr_after_save.

instance.avatar.delete # => nil


154
155
156
# File 'lib/nozzle/adapter/base.rb', line 154

def delete
  @record.send(:"#{@column}=", nil)
end

#dump(value) ⇒ Object

Fills internal structure of the adapter with new file’s path. It’s used in Nozzle::Adapter#avatar= before sending filename to the object.

Raises:

  • (Errno::ENOENT)


167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/nozzle/adapter/base.rb', line 167

def dump( value )
  reset
  @original_path = path
  return nil  unless value

  new_path, filename_candidate = expand_argument(value)
  raise Errno::ENOENT, "'#{new_path}'"  unless File.exists?(new_path)

  @tempfile_path = File.expand_path(new_path)
  detect_properties
  @filename = fit_to_filesystem(prepare_filename(filename_candidate))
end

#filenameObject

Returns stored filename.

instance.avatar.filename # => 'image.jpg'


91
92
93
# File 'lib/nozzle/adapter/base.rb', line 91

def filename
  @filename
end

#load(value) ⇒ Object

Returns adapter instance. It’s used in Nozzle::Adapter#avatar after retrieving filename from the object.



160
161
162
163
# File 'lib/nozzle/adapter/base.rb', line 160

def load( value )
  @filename = value
  self
end

#pathObject

Constructs a filesustem path which absolutely points to stored file.

instance.avatar.path # => 'public/uploads/Model/avatar/image.jpg'

How it’s constructed:

"/#{system_path}/#{filename}"
"/#{adapter_path}/#{relative_folder}/#{filename}"
"#{root}/#{adapter_folder}/#{@model}/#{@column}/#{filename}"
"public/uploads/#{@model}/#{@column}/#{filename}"
"public/uploads/Model/avatar/image.jpg"

Note: if filename is not yet stored, nil is returned.



66
67
68
69
70
# File 'lib/nozzle/adapter/base.rb', line 66

def path
  if filename
    File.join system_path, filename
  end
end

#public_pathObject

Returns folder path relative to public folder.

instance.avatar.public_path # => 'uploads/Model/avatar'

It is constructed from #adapter_folder and #relative_folder



142
143
144
# File 'lib/nozzle/adapter/base.rb', line 142

def public_path
  File.join adapter_folder, relative_folder
end

#relative_folderObject

Returns file’s folder relative to #adapter_path.

instance.avatar.relative_folder # => 'Model/avatar'

It is constructed from object’s class name and column name. This MAY be overridden to place files somwhere other than ‘Model/avatar’.



128
129
130
# File 'lib/nozzle/adapter/base.rb', line 128

def relative_folder
  File.join @model.to_s, @column.to_s
end

#rootObject

Returns root path of application’s static assets.

instance.avatar.root # => 'public'

This MAY be overridden to return an application root different from the current folder.



106
107
108
# File 'lib/nozzle/adapter/base.rb', line 106

def root
  'public'
end

#settingsObject

Sets or gets settings provided by options.

if instance.avatar.settings[:fake]
  instance.avatar.settings[:fake] = false
end


28
29
30
# File 'lib/nozzle/adapter/base.rb', line 28

def settings
  @settings ||= {}
end

#sizeObject

Returns file size stored in avatar_size column of the record.



85
86
87
# File 'lib/nozzle/adapter/base.rb', line 85

def size
  @record.send( :"#{@column}_size" )  rescue -1
end

#store!Object

Stores temporary filename by the constructed path. Deletes old file. Note: the file is moved if it’s path contains /tmp/ or /temp/, copied otherwise.



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/nozzle/adapter/base.rb', line 183

def store!
  unlink! @original_path
  return nil  unless @tempfile_path

  new_path = path
  FileUtils.mkdir_p File.dirname(new_path)
  result = if @tempfile_path =~ /\/te?mp\//
    FileUtils.move @tempfile_path, new_path
  else
    FileUtils.copy @tempfile_path, new_path
  end
  File.chmod 0644, new_path
  reset
  result
end

#system_pathObject

Returns filesystem folder path relative to adapter root.

instance.avatar.system_path # => 'public/uploads/Model/avatar'

It is constructed from #adapter_path and #relative_folder



135
136
137
# File 'lib/nozzle/adapter/base.rb', line 135

def system_path
  File.join adapter_path, relative_folder
end

#to_sObject

Inspects class name and url of the object.

instance.avatar.to_s # => 'Model#url: /uploads/Model/avatar/image.jpg'


148
149
150
# File 'lib/nozzle/adapter/base.rb', line 148

def to_s
  "#{self.class}#url: #{url}"
end

#unlink!(target = path) ⇒ Object

Deletes file by path. Do not use, it will break adapter’s integrity. It’s called in #avatar_after_destroy after the object is destroyed.

unlink!                # deletes path
unlink! @original_path # deletes @original_path
unlink! nil            # deletes nothing


204
205
206
# File 'lib/nozzle/adapter/base.rb', line 204

def unlink!( target = path )
  delete_file_and_folder! target  if target
end

#urlObject

Constructs an URL which relatively points to the file.

instance.avatar.url # => '/uploads/Model/avatar/image.jpg'

How it’s constructed:

"#{public_path}/#{filename}"
"/#{adapter_folder}/#{relative_folder}/#{filename}"
"/uploads/#{@model}/#{@column}/#{filename}"
"/uploads/Model/avatar/image.jpg"

Note: if filename is not yet stored, default_url is called.



40
41
42
43
44
45
46
# File 'lib/nozzle/adapter/base.rb', line 40

def url
  if filename
    File.join '', public_path, filename
  else
    default_url
  end
end

#url?Boolean

Gets url and adds a cache busting timestamp to it.

instance.avatar.url? # => '/uploads/Model/avatar/image.jpg?1373369401'

Returns:

  • (Boolean)


50
51
52
53
54
55
# File 'lib/nozzle/adapter/base.rb', line 50

def url?
  result = url
  result && "#{result}?#{File.mtime(path).to_i}"
rescue Errno::ENOENT
  result
end