Class: OnlyofficeS3Wrapper::AmazonS3Wrapper

Inherits:
Object
  • Object
show all
Includes:
PathHelper
Defined in:
lib/onlyoffice_s3_wrapper.rb

Overview

Class for working with amazon s3

Constant Summary collapse

DEFAULT_CONTENT_TYPE =

Returns default content type for uploaded files.

Returns:

  • (String)

    default content type for uploaded files

'binary/octet-stream'

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from PathHelper

#bucket_file_path

Constructor Details

#initialize(bucket_name: 'nct-data-share', region: 'us-west-2') ⇒ AmazonS3Wrapper

Returns a new instance of AmazonS3Wrapper.



24
25
26
27
28
29
30
31
# File 'lib/onlyoffice_s3_wrapper.rb', line 24

def initialize(bucket_name: 'nct-data-share', region: 'us-west-2')
  read_keys
  Aws.config = { access_key_id: @access_key_id,
                 secret_access_key: @secret_access_key,
                 region: region }
  @bucket = Aws::S3::Resource.new.bucket(bucket_name)
  @download_folder = Dir.mktmpdir('amazon-s3-downloads')
end

Instance Attribute Details

#access_key_id=(value) ⇒ Object (writeonly)

String

Amazon key



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

def access_key_id=(value)
  @access_key_id = value
end

#bucketObject

Returns the value of attribute bucket.



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

def bucket
  @bucket
end

#download_folderObject

Returns the value of attribute download_folder.



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

def download_folder
  @download_folder
end

#secret_access_key=(value) ⇒ Object (writeonly)

String

Amazon secret key



22
23
24
# File 'lib/onlyoffice_s3_wrapper.rb', line 22

def secret_access_key=(value)
  @secret_access_key = value
end

Instance Method Details

#delete_file(file_path) ⇒ nil

Delete file by name

Parameters:

  • file_path (String)

    name of file

Returns:

  • (nil)


149
150
151
152
# File 'lib/onlyoffice_s3_wrapper.rb', line 149

def delete_file(file_path)
  file_path = file_path.sub('/', '') if file_path[0] == '/'
  get_object(file_path).delete
end

#download_file_by_name(file_name, download_location = nil) ⇒ String

Returns full path to file.

Parameters:

  • file_name (String)

    path to file in S3 bucket

  • download_location (String) (defaults to: nil)

    path to save file. Can be full path to file, or just the directory to save

Returns:

  • (String)

    full path to file



78
79
80
81
82
83
84
85
86
87
88
# File 'lib/onlyoffice_s3_wrapper.rb', line 78

def download_file_by_name(file_name, download_location = nil)
  object = get_object(file_name)
  temp_location = download_object(object, @download_folder)
  OnlyofficeLoggerHelper.log("Temp downloaded file: #{temp_location}")

  return temp_location unless download_location

  download_location = "#{download_location}/#{File.basename(file_name)}" if File.directory?(download_location)
  FileUtils.mv(temp_location, download_location)
  download_location
end

#download_object(object, download_folder = @download_folder) ⇒ String

Download object

Parameters:

  • object (Object)

    to download

  • download_folder (String) (defaults to: @download_folder)

    path to save

Returns:

  • (String)

    path to downloaded file



94
95
96
97
98
99
100
101
102
103
# File 'lib/onlyoffice_s3_wrapper.rb', line 94

def download_object(object, download_folder = @download_folder)
  file_name = "#{download_folder}/#{File.basename(object.key)}"
  link = object.presigned_url(:get, expires_in: 3600)
  File.open(file_name, 'w') do |f|
    IO.copy_stream(URI.parse(link).open, f)
  end
  file_name
rescue StandardError => e
  raise("File #{file_name} download failed with: #{e}")
end

#files_from_folder(folder = nil) ⇒ Array<Object>

Get list of files from specific folder Will not use folder name as prefix, will always try to look at folder with exact specified name

Parameters:

  • folder (String) (defaults to: nil)

    to get files

Returns:

  • (Array<Object>)

    result set



48
49
50
51
# File 'lib/onlyoffice_s3_wrapper.rb', line 48

def files_from_folder(folder = nil)
  folder = "#{folder}/" unless folder.end_with?('/')
  get_files_by_prefix(folder)
end

#folder?(str) ⇒ True, False

Is string path to folder

Parameters:

  • str (String)

    path

Returns:

  • (True, False)


63
64
65
# File 'lib/onlyoffice_s3_wrapper.rb', line 63

def folder?(str)
  str.end_with? '/'
end

#get_elements_by_prefix(prefix = nil) ⇒ Object

param [String] prefix return [Array] of folder names with ‘/’ in end and filenames with fullpath (started ad prefix)



56
57
58
# File 'lib/onlyoffice_s3_wrapper.rb', line 56

def get_elements_by_prefix(prefix = nil)
  @bucket.objects(prefix: prefix).collect(&:key)
end

#get_files_by_prefix(prefix = nil, field: :key) ⇒ Array<Object>

Get files by prefix

Parameters:

  • prefix (String) (defaults to: nil)

    prefix to filter

  • field (Symbol) (defaults to: :key)

    field to get

Returns:

  • (Array<Object>)

    result set



37
38
39
40
41
# File 'lib/onlyoffice_s3_wrapper.rb', line 37

def get_files_by_prefix(prefix = nil, field: :key)
  @bucket.objects(prefix: prefix)
         .collect(&field)
         .reject { |file| folder?(file) }
end

#get_object(obj_name) ⇒ Object

Get object by name

Parameters:

  • obj_name (String)

    name of object

Returns:

  • (Object)


70
71
72
# File 'lib/onlyoffice_s3_wrapper.rb', line 70

def get_object(obj_name)
  @bucket.object(obj_name)
end

Get permissions for file

Parameters:

  • file_path (String)

    path to file

Returns:

  • (Aws::S3::ObjectAcl)

    permissions



128
129
130
# File 'lib/onlyoffice_s3_wrapper.rb', line 128

def get_permission_by_link(file_path)
  @bucket.object(file_path).acl
end

#make_public(file_path) ⇒ Array<String, String>

Make file public

Parameters:

  • file_path (String)

    file to make public

Returns:

  • (Array<String, String>)

    public url and permissions



119
120
121
122
123
# File 'lib/onlyoffice_s3_wrapper.rb', line 119

def make_public(file_path)
  @bucket.object(file_path).acl.put(acl: 'public-read')
  permission = @bucket.object(file_path).acl.grants.last.permission
  [@bucket.object(file_path).public_url.to_s, permission]
end

#read_keys(key_location = "#{Dir.home}/.s3") ⇒ nil

Get S3 key and S3 private key

Parameters:

  • key_location (String) (defaults to: "#{Dir.home}/.s3")

    Path to search for key files

Returns:

  • (nil)


157
158
159
160
161
162
163
164
# File 'lib/onlyoffice_s3_wrapper.rb', line 157

def read_keys(key_location = "#{Dir.home}/.s3")
  @access_key_id = File.read("#{key_location}/key").strip
  @secret_access_key = File.read("#{key_location}/private_key").strip
rescue Errno::ENOENT
  raise Errno::ENOENT, "No key or private key found in #{key_location} " \
                       "Please create files #{key_location}/key " \
                       "and #{key_location}/private_key"
end

#upload_file(file_path, upload_folder, content_type = DEFAULT_CONTENT_TYPE) ⇒ nil

Upload file

Parameters:

  • file_path (String)

    file to upload

  • upload_folder (String)

    path to upload

  • content_type (String) (defaults to: DEFAULT_CONTENT_TYPE)

    content type of file to upload

Returns:

  • (nil)


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

def upload_file(file_path, upload_folder, content_type = DEFAULT_CONTENT_TYPE)
  path = bucket_file_path(File.basename(file_path),
                          upload_folder)
  @bucket.object(path).upload_file(file_path, content_type: content_type)
end

#upload_file_and_make_public(file_path, upload_folder = nil, content_type = DEFAULT_CONTENT_TYPE) ⇒ String

Upload file/folder and make public

Parameters:

  • file_path (String)

    file to upload

  • upload_folder (True, False) (defaults to: nil)

    is this a folder

  • content_type (String) (defaults to: DEFAULT_CONTENT_TYPE)

    content type of file to upload

Returns:

  • (String)

    public url



137
138
139
140
141
142
143
144
# File 'lib/onlyoffice_s3_wrapper.rb', line 137

def upload_file_and_make_public(file_path,
                                upload_folder = nil,
                                content_type = DEFAULT_CONTENT_TYPE)
  upload_file(file_path, upload_folder, content_type)
  make_public(bucket_file_path(File.basename(file_path), upload_folder))
  @bucket.object(bucket_file_path(File.basename(file_path),
                                  upload_folder)).public_url
end