Module: S3Index

Extended by:
ActiveSupport::Autoload
Defined in:
lib/s3_index.rb,
lib/s3_index/index.rb,
lib/s3_index/version.rb,
lib/s3_index/accessor.rb

Overview

module

Defined Under Namespace

Modules: Accessor Classes: Index

Constant Summary collapse

VERSION =
'0.2.0'.freeze

Class Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(meth, *args, &block) ⇒ Object (private)

Let the model handle everything else



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

def method_missing(meth, *args, &block)
  super unless Index.respond_to?(meth)
  Index.public_send(meth, *args, &block)
end

Class Method Details

.default_clientObject



85
86
87
# File 'lib/s3_index.rb', line 85

def default_client
  @s3_client ||= new_client
end

.default_client=(client) ⇒ Object



99
100
101
# File 'lib/s3_index.rb', line 99

def default_client=(client)
  @s3_client = client
end

.download!(s3: default_client, src: nil, s3_url: nil, index: nil, dst: nil) ⇒ Object

Download file from s3 bucket back on Index model. src and s3_url are quick options to find an Index model to download.



58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/s3_index.rb', line 58

def download!(s3: default_client, src: nil, s3_url: nil, index: nil, dst: nil)
  src || s3_url || index ||
    raise(ArgumentError, 'src:, s3_url:, or index: must be provided!')

  index ||=
    begin
      finder = src ? { origin_url: src } : { s3_url: s3_url }
      Index.find_by(finder) || raise(ActiveRecord::RecordNotFound, "S3Index::Index not found by #{finder}")
    end

  obj = s3.bucket(index.s3_bucket).object(index.origin_url)
  obj.get(response_target: dst || index.origin_url)
end

.envObject



13
14
15
# File 'lib/s3_index.rb', line 13

def env
  @env ||= ActiveSupport::StringInquirer.new(ENV['S3_INDEX_ENV'])
end

.index_attributes_for(path) ⇒ Object



76
77
78
79
80
81
82
83
# File 'lib/s3_index.rb', line 76

def index_attributes_for(path)
  {
    md5: Digest::MD5.file(path).to_s,
    file_name: File.basename(path),
    content_type: MIME::Types.type_for(path).first.try(:content_type),
    size: File.size(path)
  }
end

.index_for_src(src) ⇒ Object



72
73
74
# File 'lib/s3_index.rb', line 72

def index_for_src(src)
  Index.where(origin_url: src).first_or_initialize
end

.loggerObject



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

def logger
  @logger ||= ActiveRecord::Base.logger
end

.logger=(logger) ⇒ Object



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

def logger=(logger)
  @logger = logger
end

.method_missing(meth, *args, &block) ⇒ Object

Let the model handle everything else



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

def method_missing(meth, *args, &block)
  super unless Index.respond_to?(meth)
  Index.public_send(meth, *args, &block)
end

.new_clientObject



89
90
91
92
93
94
95
96
97
# File 'lib/s3_index.rb', line 89

def new_client
  credentials = Aws::SharedCredentials.new(profile_name: 'default')
  client = Aws::S3::Client.new(
    credentials: credentials,
    http_wire_trace: $DEBUG,
    logger: logger
  )
  Aws::S3::Resource.new(client: client)
end

.rootPathname

Use like ‘Rails.root`

Returns:

  • (Pathname)


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

def root
  @root ||= Pathname(File.expand_path('../..', __FILE__))
end

.upload!(s3: default_client, bucket:, src:, dst: src) ⇒ Object

Upload file to s3 bucket and register it to the Index model.



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/s3_index.rb', line 32

def upload!(s3: default_client, bucket:, src:, dst: src)
  obj = s3.bucket(bucket).object(dst)

  index = index_for_src(src)
  index_attrs = index_attributes_for(src)

  # nothing to do, file is registered and the same as before
  return index if index.md5 == index_attrs[:md5]

  # try to get the data to s3 first, then save in index.
  # order is important, we don't want to make the row until
  # S3 gets the file.
  obj.upload_file(
    src,
    content_type: index_attrs[:content_type],
    content_length: index_attrs[:size]
  )

  index.s3_url = obj.public_url
  index.s3_bucket = obj.bucket_name
  index.update!(index_attrs)
  index
end