s3mirror 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a5348c6d7c5561d1b3ea19662afe87be9513fd340eda30ee8f8bd7c25c5b6b77
4
+ data.tar.gz: ee3d10e31fb4c899618c1b333906a6497c9e68ef21dc4988e213cb846304a848
5
+ SHA512:
6
+ metadata.gz: 66c57bc3a30e18f1d4ebe6036f2e48e6f9cb1eee1bfef791e3033816807be93190fccefb5f6a0c487dc27554cd44bca9dcdcaa3234100dd27adba5787ecf6025
7
+ data.tar.gz: 615e38ad685f696f9b5ebce4e8675d3aae797aee444d8a6e5a379aeda73b0cacbf06ee405c4166aeb543e0896120d27007c2bfb654a8295466834e08e78de2cc
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in s3mirror.gemspec
4
+ gemspec
5
+
6
+ gem "rake", "~> 12.0"
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2020 TODO: Write your name
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,41 @@
1
+ # S3mirror
2
+
3
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/s3mirror`. To experiment with that code, run `bin/console` for an interactive prompt.
4
+
5
+ TODO: Delete this and the text above, and describe your gem
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 's3mirror'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle install
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install s3mirror
22
+
23
+ ## Usage
24
+
25
+ TODO: Write usage instructions here
26
+
27
+ ## Development
28
+
29
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
30
+
31
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
+
33
+ ## Contributing
34
+
35
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/s3mirror.
36
+
37
+
38
+ ## License
39
+
40
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
41
+ # s3mirror
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+ task :default => :spec
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "s3mirror"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,131 @@
1
+ require "s3mirror/version"
2
+ require "s3mirror/configuration"
3
+
4
+ # usage:
5
+ # s3mirror = S3mirror::Mirror.new({})
6
+ module S3mirror
7
+ class Error < StandardError; end
8
+
9
+ class Mirror
10
+
11
+ def self.configuration
12
+ @configuration ||= Configuration.new
13
+ end
14
+
15
+ def self.configure(&block)
16
+ yield(configuration)
17
+ end
18
+
19
+ def initialize(options={})
20
+ @temp_destination = Mirror.configuration.temp_download_folder #options.delete(:temp_download_folder)
21
+
22
+ if !@temp_destination.blank? && !Pathname.new(@temp_destination).absolute?
23
+ throw 'temp_download_folder should be an absolute path'
24
+ end
25
+
26
+ @s3_main = Mirror.configuration.s3_main #options.delete(:s3_main)
27
+ @s3_mirrors = Mirror.configuration.s3_mirrors #options.delete(:s3_mirrors)
28
+ end
29
+
30
+ def get_s3_bucket(service)
31
+ # create a client that will be used by resource, this help switching between different s3 providers without changing default configuration set in initializer (i.e: Aws.config.update({...}))
32
+ client = Aws::S3::Client.new(
33
+ endpoint: service[:endpoint],
34
+ region: service[:region],
35
+ credentials: Aws::Credentials.new(service[:access_key_id], service[:secret_access_key])
36
+ )
37
+ # https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Resource.html
38
+ # if client not supplied, default configuration will be used
39
+ s3 = Aws::S3::Resource.new(client: client)
40
+ return s3.bucket(service[:bucket_name])
41
+ end
42
+
43
+ def mirror(key)
44
+ unique_prefix = 't' + (Time.now.to_f * 1000000).to_s
45
+
46
+ # filename is the name of file used for our download
47
+ filename = File.basename(key)
48
+
49
+ # add a temporary unique prefix to the filename to prevent collision (i.e: 2 downloaded file with same name)
50
+ prefixed_filename = "#{unique_prefix}_#{filename}"
51
+
52
+ # all files will be downloaded to your app "tmp" folder (otherwise the specified @temp_destination), the unique prefix above will guarantee uniqueness of files names
53
+ if @temp_destination.blank?
54
+ file_path = Rails.root.join('tmp', prefixed_filename)
55
+ else
56
+ file_path = File.join(@temp_destination, prefixed_filename)
57
+ end
58
+
59
+ uploaded_now = 0 # uploaded count for the current mirroring try
60
+ uploaded_total = 0
61
+
62
+ if download(key, file_path)
63
+ begin
64
+ @s3_mirrors.each do |mirror|
65
+ mirror_bucket = get_s3_bucket(mirror)
66
+ if !mirror_has_file?(key, mirror_bucket)
67
+ uploaded = upload(file_path, key, mirror_bucket)
68
+ if uploaded
69
+ uploaded_now += 1
70
+ uploaded_total += 1
71
+ end
72
+ else
73
+ uploaded_total += 1
74
+ end
75
+ end
76
+ ensure
77
+ # remove downloaded file
78
+ File.delete(file_path)
79
+ end
80
+ else
81
+ # throw 'file not downloaded!!'
82
+ end
83
+
84
+ return {
85
+ mirrored_now: uploaded_now,
86
+ total_mirrored: uploaded_total,
87
+ total_failed: @s3_mirrors.size - uploaded_total
88
+ }
89
+ end
90
+
91
+ # get object from main/primary s3 service
92
+ def s3_object(key)
93
+ bucket = get_s3_bucket(@s3_main)
94
+ bucket.object(key)
95
+ end
96
+
97
+ # read note (1) below
98
+ def download(key, destination_on_desk)
99
+ # returns true if downloaded successfully
100
+ begin
101
+ s3_object(key).download_file(destination_on_desk)
102
+ rescue Aws::S3::Errors::NoSuchKey
103
+ return false
104
+ end
105
+ end
106
+
107
+ # read note (2) below
108
+ def upload(file_path, file_key, mirror_bucket)
109
+ object_name = file_key
110
+ # create empty object in the mirror bucket with same name as the original file.
111
+ object = mirror_bucket.object(object_name)
112
+ # upload file to that object.
113
+ object.upload_file(file_path) # return true if uploaded successfully)
114
+ end
115
+
116
+ def mirror_has_file?(file_key, mirror_bucket)
117
+ begin
118
+ object = mirror_bucket.object(file_key)
119
+ if object.exists?
120
+ true
121
+ else
122
+ false
123
+ end
124
+ rescue Aws::S3::Errors::NotFound
125
+ false
126
+ end
127
+ end
128
+
129
+ end
130
+
131
+ end
@@ -0,0 +1,11 @@
1
+ module S3mirror
2
+ class Configuration
3
+
4
+ attr_accessor :temp_download_folder, :s3_main, :s3_mirrors
5
+
6
+ def initialize
7
+
8
+ end
9
+
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module S3mirror
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,31 @@
1
+ require_relative 'lib/s3mirror/version'
2
+
3
+ Gem::Specification.new do |spec|
4
+ spec.name = "s3mirror"
5
+ spec.version = S3mirror::VERSION
6
+ spec.authors = ["scratchoo"]
7
+ spec.email = ["support@scratchoo.com"]
8
+
9
+ spec.summary = %q{Mirror your file to s3 compatible services after uploading it.}
10
+ spec.description = %q{S3mirror allows you to copy an uploaded file to mirror(s) which are basically any s3 compatible storage.}
11
+ spec.homepage = "https://github.com/scratchoo/s3mirror"
12
+ spec.license = "MIT"
13
+ spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
14
+
15
+ spec.metadata["allowed_push_host"] = "https://rubygems.org"
16
+
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = "https://github.com/scratchoo/s3mirror"
19
+
20
+ # Specify which files should be added to the gem when it is released.
21
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
22
+ spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
23
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
+ end
25
+ spec.bindir = "exe"
26
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
27
+ spec.require_paths = ["lib"]
28
+
29
+ spec.add_runtime_dependency 'aws-sdk-s3'
30
+
31
+ end
metadata ADDED
@@ -0,0 +1,72 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: s3mirror
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - scratchoo
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2020-12-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: aws-sdk-s3
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ description: S3mirror allows you to copy an uploaded file to mirror(s) which are basically
28
+ any s3 compatible storage.
29
+ email:
30
+ - support@scratchoo.com
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - ".gitignore"
36
+ - Gemfile
37
+ - LICENSE.txt
38
+ - README.md
39
+ - Rakefile
40
+ - bin/console
41
+ - bin/setup
42
+ - lib/s3mirror.rb
43
+ - lib/s3mirror/configuration.rb
44
+ - lib/s3mirror/version.rb
45
+ - s3mirror.gemspec
46
+ homepage: https://github.com/scratchoo/s3mirror
47
+ licenses:
48
+ - MIT
49
+ metadata:
50
+ allowed_push_host: https://rubygems.org
51
+ homepage_uri: https://github.com/scratchoo/s3mirror
52
+ source_code_uri: https://github.com/scratchoo/s3mirror
53
+ post_install_message:
54
+ rdoc_options: []
55
+ require_paths:
56
+ - lib
57
+ required_ruby_version: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 2.3.0
62
+ required_rubygems_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubygems_version: 3.1.2
69
+ signing_key:
70
+ specification_version: 4
71
+ summary: Mirror your file to s3 compatible services after uploading it.
72
+ test_files: []