Class: ErpTechSvcs::FileSupport::S3Manager

Inherits:
Manager
  • Object
show all
Defined in:
lib/erp_tech_svcs/file_support/s3_manager.rb

Constant Summary

Constants inherited from Manager

Manager::FILE_DOES_NOT_EXIST, Manager::FILE_FOLDER_DOES_NOT_EXIST, Manager::FOLDER_IS_NOT_EMPTY

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Manager

#build_file_assets_tree_for_model, find_parent, #insert_folders, #sync

Class Method Details

.add_children(parent_hash, tree) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/erp_tech_svcs/file_support/s3_manager.rb', line 40

def add_children(parent_hash, tree)
  tree.children.each do |child|
    child_hash = {
      :last_modified => '',
      #:last_modified => (child.leaf? ? @@s3_bucket.objects[child.key].last_modified : ''), 
      :text => (child.leaf? ? File.basename(child.key) : File.basename(child.prefix)), 
      :downloadPath => (child.leaf? ? '/'+File.dirname(child.key) : "/#{child.parent.prefix}".sub(%r{/$},'')), 
      :leaf => child.leaf?, 
      :id => (child.leaf? ? '/'+child.key : "/#{child.prefix}".sub(%r{/$},'')), 
      :children => []
    }
    child_hash = add_children(child_hash, child) unless child.leaf?
    unless child_hash[:id].gsub(/\/$/,'') == parent_hash[:id].gsub(/\/$/,'') # resolves s3 issue where empty dir contains itself
      parent_hash[:children] << child_hash unless child_hash[:downloadPath] == '/.'
    end
  end

  parent_hash
end

.build_node_tree(reload = false) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
# File 'lib/erp_tech_svcs/file_support/s3_manager.rb', line 60

def build_node_tree(reload=false)
  node_tree = Rails.cache.read(cache_key)
  if !reload and !node_tree.nil?
    #Rails.logger.info "@@@@@@@@@@@@@@ USING CACHED node_tree: #{node_tree.inspect}"
    return node_tree
  end

  tree_data = {:text => @@s3_bucket.name, :leaf => false, :id => '', :children => []}
  tree_data = [add_children(tree_data, @@s3_bucket.as_tree)]
  cache_node_tree(tree_data)
end

.cache_keyObject



31
32
33
# File 'lib/erp_tech_svcs/file_support/s3_manager.rb', line 31

def cache_key
   Thread.current[:tenant_id].nil? ? 'node_tree' : "tenant_#{Thread.current[:tenant_id]}_node_tree"
end

.cache_node_tree(node_tree) ⇒ Object



35
36
37
38
# File 'lib/erp_tech_svcs/file_support/s3_manager.rb', line 35

def cache_node_tree(node_tree)
  Rails.cache.write(cache_key, node_tree, :expires_in => ErpTechSvcs::Config.s3_cache_expires_in_minutes.minutes)
  node_tree
end

.reloadObject



27
28
29
# File 'lib/erp_tech_svcs/file_support/s3_manager.rb', line 27

def reload
  !@@s3_connection.nil? ? build_node_tree(true) : setup_connection
end

.setup_connectionObject



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/erp_tech_svcs/file_support/s3_manager.rb', line 10

def setup_connection
  @@configuration = YAML::load_file(File.join(Rails.root,'config','s3.yml'))[Rails.env]
  
  # S3 debug logging
  # AWS.config(
  #   :logger => Rails.logger,
  #   :log_level => :info
  # )

  @@s3_connection = AWS::S3.new(
    :access_key_id     => @@configuration['access_key_id'],
    :secret_access_key => @@configuration['secret_access_key']
  )

  @@s3_bucket = @@s3_connection.buckets[@@configuration['bucket'].to_sym]
end

Instance Method Details

#bucketObject



81
82
83
# File 'lib/erp_tech_svcs/file_support/s3_manager.rb', line 81

def bucket
  @@s3_bucket
end

#bucket=(name) ⇒ Object



77
78
79
# File 'lib/erp_tech_svcs/file_support/s3_manager.rb', line 77

def bucket=(name)
  @@s3_bucket = @@s3_connection.buckets[name.to_sym]
end

#bucketsObject



73
74
75
# File 'lib/erp_tech_svcs/file_support/s3_manager.rb', line 73

def buckets
  @@s3_connection.buckets
end

#build_tree(starting_path, options = {}) ⇒ Object



229
230
231
232
233
# File 'lib/erp_tech_svcs/file_support/s3_manager.rb', line 229

def build_tree(starting_path, options={})
  starting_path = "/" + starting_path unless starting_path.first == "/"
  node_tree = find_node(starting_path, options)
  node_tree.nil? ? [] : node_tree
end

#cache_keyObject



89
90
91
# File 'lib/erp_tech_svcs/file_support/s3_manager.rb', line 89

def cache_key
  ErpTechSvcs::FileSupport::S3Manager.cache_key
end

#clear_cache(path) ⇒ Object



93
94
95
96
97
98
# File 'lib/erp_tech_svcs/file_support/s3_manager.rb', line 93

def clear_cache(path)
  path = path.sub(%r{^/},'')
  #Rails.logger.info "deleting cache with key: #{path}"
  Rails.cache.delete(path) # delete template from cache
  Rails.cache.delete(cache_key) # delete node tree from cache
end

#create_file(path, name, content) ⇒ Object



109
110
111
112
113
114
# File 'lib/erp_tech_svcs/file_support/s3_manager.rb', line 109

def create_file(path, name, content)
  path = path.sub(%r{^/},'')
  full_filename = (path.blank? ? name : File.join(path, name))
  bucket.objects[full_filename].write(content, { :acl => :public_read })
  clear_cache(path)
end

#create_folder(path, name) ⇒ Object



116
117
118
119
120
121
122
# File 'lib/erp_tech_svcs/file_support/s3_manager.rb', line 116

def create_folder(path, name)
  path = path.sub(%r{^/},'')
  full_filename = (path.blank? ? name : File.join(path, name))
  folder = full_filename + "/"
  bucket.objects[folder].write('', { :acl => :public_read })
  clear_cache(path)
end

#delete_file(path, options = {}) ⇒ Object



182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
# File 'lib/erp_tech_svcs/file_support/s3_manager.rb', line 182

def delete_file(path, options={})
  is_directory = !path.match(/\/$/).nil?
  path = path.sub(%r{^/},'')
  result = false
  message = nil
  begin
    if options[:force] or bucket.as_tree(:prefix => path).children.count <= 1 # aws-sdk includes the folder itself as a child (like . is current dir), this needs revisited as <= 1 is scary
      bucket.objects.with_prefix(path).delete_all
      message = "File was deleted successfully"
      result = true
      clear_cache(path)
    else
      message = FOLDER_IS_NOT_EMPTY
    end
  rescue Exception => e
   result = false
   message = e
  end    

  return result, message, is_directory    
end

#exists?(path) ⇒ Boolean

Returns:

  • (Boolean)


204
205
206
207
208
209
210
211
# File 'lib/erp_tech_svcs/file_support/s3_manager.rb', line 204

def exists?(path)
  begin
    path = path.sub(%r{^/},'')
    return bucket.objects[path].exists?
  rescue AWS::S3::Errors::NoSuchKey
    return false
  end
end

#find_node(path, options = {}) ⇒ Object



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# File 'lib/erp_tech_svcs/file_support/s3_manager.rb', line 235

def find_node(path, options={})
  parent = if options[:file_asset_holder]
    super
  else
    parent = ErpTechSvcs::FileSupport::S3Manager.build_node_tree(false).first
    unless path.nil?
      path_pieces = path.split('/')
      path_pieces.each do |path_piece|
        next if path_piece.blank?
        parent[:children].each do |child_node|
          if child_node[:text] == path_piece
            parent = child_node
            break
          end
        end
      end
      parent = nil unless parent[:id] == path
    end

    parent
  end

  parent
end

#get_contents(path) ⇒ Object



213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/erp_tech_svcs/file_support/s3_manager.rb', line 213

def get_contents(path)
  contents = nil
  message = nil

  path = path.sub(%r{^/},'')
  begin
    object = bucket.objects[path]
    contents = object.read 
  rescue AWS::S3::Errors::NoSuchKey => error
    contents = ''
    message = FILE_DOES_NOT_EXIST
  end

  return contents, message
end

#rename_file(path, name) ⇒ Object



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/erp_tech_svcs/file_support/s3_manager.rb', line 148

def rename_file(path, name)
  result = false
  old_name = File.basename(path)
  path_pieces = path.split('/')
  path_pieces.delete(path_pieces.last)
  path_pieces.push(name)
  new_path = path_pieces.join('/')
  begin
    file = FileAsset.where(:name => ::File.basename(path)).where(:directory => ::File.dirname(path)).first
    acl = (file.has_capabilities? ? :private : :public_read) unless file.nil?
    options = (file.nil? ? {} : {:acl => acl})
    path = path.sub(%r{^/},'')
    new_path = new_path.sub(%r{^/},'')
#          Rails.logger.info "renaming from #{path} to #{new_path}"
    old_object = bucket.objects[path]
    if new_object = old_object.move_to(new_path, options)
      message = "#{old_name} was renamed to #{name} successfully"
      result = true
      clear_cache(path)
    else
      message = "Error renaming #{old_name}"
    end
  rescue AWS::S3::Errors::NoSuchKey=>ex
    message = FILE_FOLDER_DOES_NOT_EXIST
  end

  return result, message
end

#rootObject



85
86
87
# File 'lib/erp_tech_svcs/file_support/s3_manager.rb', line 85

def root
  ''
end

#save_move(path, new_parent_path) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/erp_tech_svcs/file_support/s3_manager.rb', line 124

def save_move(path, new_parent_path)
  result = false
  unless self.exists? path
    message = FILE_DOES_NOT_EXIST
  else
    file = FileAsset.where(:name => ::File.basename(path)).where(:directory => ::File.dirname(path)).first
    acl = (file.has_capabilities? ? :private : :public_read) unless file.nil?
    options = (file.nil? ? {} : {:acl => acl})
    name = File.basename(path)
    path = path.sub(%r{^/},'')
    new_path = File.join(new_parent_path,name).sub(%r{^/},'')
    old_object = bucket.objects[path]
    if new_object = old_object.move_to(new_path, options)
      message = "#{name} was moved to #{new_path} successfully"
      result = true
      clear_cache(path)
    else
      message = "Error moving file #{path}"
    end
  end

  return result, message
end

#set_permissions(path, canned_acl = :public_read) ⇒ Object



177
178
179
180
# File 'lib/erp_tech_svcs/file_support/s3_manager.rb', line 177

def set_permissions(path, canned_acl=:public_read)
  path = path.sub(%r{^/},'')
  bucket.objects[path].acl = canned_acl
end

#update_file(path, content) ⇒ Object



100
101
102
103
104
105
106
107
# File 'lib/erp_tech_svcs/file_support/s3_manager.rb', line 100

def update_file(path, content)
  file = FileAsset.where(:name => ::File.basename(path)).where(:directory => ::File.dirname(path)).first
  acl = (file.has_capabilities? ? :private : :public_read) unless file.nil?
  options = (file.nil? ? {} : {:acl => acl})
  path = path.sub(%r{^/},'')
  bucket.objects[path].write(content, options)
  clear_cache(path)
end