riserva 0.1.6 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 03124d4b9a93979c9b8e9919847e1fa0dd998ea8e836840f1f2fb92112a53aaf
4
- data.tar.gz: 60ee2eeaa93f758a0849014d9dedfe192791a8831d06d090fcf43244ce529063
3
+ metadata.gz: 9d9c1baf7002404750e398f00ffd3c65f66aac5f9405de22a4976bfdc8d6d44e
4
+ data.tar.gz: b93e96cebf3e341dc1b3f40e47efeadc0ec81931ab30774d3da3ade4bed4c20c
5
5
  SHA512:
6
- metadata.gz: 1ddaa5ced52186115bfc5a9d5455a801db4241e904f9914652803bb72fe20df769b77354a8627a8cf30fb4533eb192db3d05d1a17abba278a8dab1c2e02439bd
7
- data.tar.gz: 4af372c7cdc5792f1246d5c1207e64108c7e4282c7a334056e95d2f34a8f10c29029938638e3db5b639f86619cae814ef0acd28fb8ce71b42913a901f78928e6
6
+ metadata.gz: a1def65971f0715dde4fc92b4cede1e995a59631f555889093e62e303d7c26accc7735b05ffc9c4d018113478da61e9ebdf09981fd23dccc045982bde2a68de7
7
+ data.tar.gz: 894fc37b635f4deb25bad08b50db64420c6fb470b76c80d5e9225832c05d2f04fa73371f92a47fc4dd468d4a6d1589b9ae95dfab823d377b65a6be6556b7f492
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
+ --require spec_helper
1
2
  --format documentation
2
3
  --color
data/TODO.md CHANGED
@@ -1,5 +1,6 @@
1
1
  ## TODO
2
2
 
3
+ * encrypt backups
3
4
  * restore from backup
4
5
  * implement deduplication
5
6
  * create archives in `/tmp` folder if location is not specified
@@ -4,6 +4,7 @@ require 'riserva/version'
4
4
  require 'active_support/core_ext/string/inflections'
5
5
  require 'active_support/time'
6
6
  require 'pathname'
7
+ require 'parallel'
7
8
 
8
9
  module Riserva
9
10
  autoload :Config, 'riserva/config'
@@ -34,4 +35,8 @@ module Riserva
34
35
  def self.logger
35
36
  Riserva::Log.new.logger
36
37
  end
38
+
39
+ def self.version
40
+ "Riserva v#{Riserva::VERSION}"
41
+ end
37
42
  end
@@ -31,7 +31,7 @@ Choice.options do
31
31
  long '--version'
32
32
  desc 'Show version'
33
33
  action do
34
- puts "Riserva backup tool v#{Riserva::VERSION}"
34
+ puts Riserva.version
35
35
  exit
36
36
  end
37
37
  end
@@ -1,49 +1,44 @@
1
1
  module Riserva::Commands
2
2
  class Backup < ApplicationCommand
3
- attr_reader :uploaders
3
+ MAX_THREADS = 5
4
4
 
5
5
  def initialize
6
6
  super
7
- @uploaders = {}
8
7
  end
9
8
 
10
9
  def call
11
- create_archives
12
- push_to_cloud
10
+ perform
13
11
 
14
- success? ? broadcast(:ok) : broadcast(:failed)
15
- rescue StandardError => exception
12
+ broadcast(:ok)
13
+ rescue StandardError => e
16
14
  broadcast(:failed)
17
- raise exception
15
+ raise e
18
16
  end
19
17
 
20
18
  private
21
19
 
22
- def success?
23
- @uploaders.values.map { |uploader| uploader.files == archivator.files }.all?
24
- end
25
-
26
- def create_archives
27
- Riserva::Config.folders { |folder| archivator.call(folder) }
20
+ def perform
21
+ Riserva::Config.folders.each do |folder|
22
+ push_to_cloud archivator.call(folder).files
23
+ end
28
24
  end
29
25
 
30
26
  def archivator
31
27
  @archivator ||= Riserva::Commands::CreateArchive.new
32
28
  end
33
29
 
34
- def push_to_cloud
35
- Riserva::Config.storages do |storage|
36
- archivator.files.each { |file| upload_file(storage, file) }
30
+ def push_to_cloud(files)
31
+ Parallel.map(Riserva::Config.storages, in_threads: MAX_THREADS) do |storage|
32
+ files.map { |file| upload_file(storage, file) }
37
33
  end
38
34
  end
39
35
 
40
36
  def upload_file(storage, file)
41
- Riserva.logger.info("Uploading file #{file} to #{storage.title}...")
42
-
43
37
  uploader(storage).call(file)
44
38
  end
45
39
 
46
40
  def uploader(storage)
41
+ @uploaders ||= {}
47
42
  @uploaders[storage.title] ||= Riserva::Commands::UploadFile.new(storage)
48
43
  end
49
44
  end
@@ -1,11 +1,21 @@
1
1
  module Riserva::Commands
2
2
  class Clean < ApplicationCommand
3
3
  def call
4
- Riserva::Config.storages do |storage|
4
+ storages.each do |storage|
5
5
  broadcast(:start_cleaning, storage)
6
6
 
7
- storage.clean
7
+ if storage.clean
8
+ broadcast(:ok)
9
+ else
10
+ broadcast(:failed, storage)
11
+ end
8
12
  end
9
13
  end
14
+
15
+ private
16
+
17
+ def storages
18
+ Riserva::Config.storages
19
+ end
10
20
  end
11
21
  end
@@ -1,7 +1,8 @@
1
1
  module Riserva::Commands
2
2
  class CreateArchive < ApplicationCommand
3
3
  def call(path)
4
- return broadcast(:invalid) unless super
4
+ broadcast(:start, "folder: #{path}")
5
+ return broadcast(:invalid, "`#{@path}` is not a directory") unless super
5
6
 
6
7
  file = archive_name
7
8
  create_archive(file) ? broadcast(:ok, file) : broadcast(:failed)
@@ -6,9 +6,10 @@ module Riserva::Commands
6
6
  end
7
7
 
8
8
  def call(path)
9
+ broadcast(:start, "file: #{path} to #{@storage.title}...")
9
10
  return broadcast(:invalid) unless super
10
11
 
11
- success? ? broadcast(:ok, @path) : broadcast(:failed, @path)
12
+ success? ? broadcast(:ok, @path, @storage.title) : broadcast(:failed, @path)
12
13
  end
13
14
 
14
15
  private
@@ -20,14 +20,14 @@ module Riserva
20
20
  end
21
21
 
22
22
  def self.folders
23
- read('folders').each { |folder| yield Pathname.new(folder) }
23
+ read('folders').map { |folder| Pathname.new(folder) }
24
24
  end
25
25
 
26
26
  def self.storages
27
- read('storage').keys.each do |storage|
27
+ read('storage').keys.map do |storage|
28
28
  klass = "Riserva::Storage::#{storage.camelize}"
29
- yield(klass.safe_constantize.new) unless klass.nil?
30
- end
29
+ klass.safe_constantize&.new
30
+ end.compact
31
31
  end
32
32
 
33
33
  private
@@ -8,10 +8,18 @@ module Riserva::Listeners
8
8
  @files = Set.new
9
9
  end
10
10
 
11
- def ok(file)
11
+ def start(*args)
12
+ Riserva.logger.info(progname) { ['Starting', *args].join(': ') }
13
+ end
14
+
15
+ def ok(file, *args)
12
16
  @files << Pathname.new(file)
13
17
 
14
- Riserva.logger.info(progname) { "OK: #{file}" }
18
+ Riserva.logger.info(progname) { ["OK: #{file}", *args].join(': ') }
19
+ end
20
+
21
+ def invalid(message = nil)
22
+ Riserva.logger.debug(progname) { ['Invalid', message].compact.join(': ') }
15
23
  end
16
24
 
17
25
  def failed(file = nil)
@@ -21,7 +29,10 @@ module Riserva::Listeners
21
29
  protected
22
30
 
23
31
  def progname
24
- self.class.name.split('::').last
32
+ command = self.class.name.split('::').last
33
+ worker = Parallel.worker_number.presence
34
+
35
+ [command, worker].compact.join(' ')
25
36
  end
26
37
  end
27
38
  end
@@ -6,7 +6,7 @@ module Riserva::Listeners
6
6
  class Backup < ApplicationListener
7
7
  def initialize
8
8
  notify('Starting backup...')
9
- Riserva.logger.info('Starting backup...')
9
+ Riserva.logger.info(Riserva.version) { 'Starting backup...' }
10
10
  end
11
11
 
12
12
  def ok
@@ -8,8 +8,8 @@ module Riserva::Listeners
8
8
  Riserva.logger.info('OK')
9
9
  end
10
10
 
11
- def failed
12
- Riserva.logger.info('Failed')
11
+ def failed(storage)
12
+ Riserva.logger.info("Failed: #{storage.title}")
13
13
  end
14
14
 
15
15
  def start_cleaning(storage)
@@ -1,3 +1,3 @@
1
1
  module Riserva
2
- VERSION = '0.1.6'
2
+ VERSION = '0.1.7'
3
3
  end
@@ -21,10 +21,10 @@ Gem::Specification.new do |spec|
21
21
  spec.executables << 'riserva'
22
22
  spec.require_paths = ['lib']
23
23
 
24
- spec.add_development_dependency 'bundler', '~> 1.14'
25
- spec.add_development_dependency 'rake', '~> 10.0'
24
+ spec.add_development_dependency 'bundler'
25
+ spec.add_development_dependency 'pry-byebug'
26
+ spec.add_development_dependency 'rake', '>= 12.3.3'
26
27
  spec.add_development_dependency 'rspec', '~> 3.0'
27
- spec.add_development_dependency 'guard-rspec', '~> 4.7', '>= 4.7.3'
28
28
  spec.add_development_dependency 'wisper-rspec', '~> 0.0.3'
29
29
 
30
30
  spec.add_runtime_dependency 'activesupport', '~> 4.0'
@@ -33,5 +33,6 @@ Gem::Specification.new do |spec|
33
33
  spec.add_runtime_dependency 'dropbox_content_hasher', '~> 0.1.0'
34
34
  spec.add_runtime_dependency 'google_drive', '~> 2.1', '>= 2.1.5'
35
35
  spec.add_runtime_dependency 'notifier', '~> 0.5.2'
36
+ spec.add_runtime_dependency 'parallel', '~> 1.19', '>= 1.19.2'
36
37
  spec.add_runtime_dependency 'wisper', '~> 2.0'
37
38
  end
metadata CHANGED
@@ -1,77 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: riserva
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Igor Malinovskiy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-26 00:00:00.000000000 Z
11
+ date: 2020-10-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.14'
19
+ version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.14'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: pry-byebug
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: '0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rspec
42
+ name: rake
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - "~>"
45
+ - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: '3.0'
47
+ version: 12.3.3
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - "~>"
52
+ - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: '3.0'
54
+ version: 12.3.3
55
55
  - !ruby/object:Gem::Dependency
56
- name: guard-rspec
56
+ name: rspec
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '4.7'
62
- - - ">="
63
- - !ruby/object:Gem::Version
64
- version: 4.7.3
61
+ version: '3.0'
65
62
  type: :development
66
63
  prerelease: false
67
64
  version_requirements: !ruby/object:Gem::Requirement
68
65
  requirements:
69
66
  - - "~>"
70
67
  - !ruby/object:Gem::Version
71
- version: '4.7'
72
- - - ">="
73
- - !ruby/object:Gem::Version
74
- version: 4.7.3
68
+ version: '3.0'
75
69
  - !ruby/object:Gem::Dependency
76
70
  name: wisper-rspec
77
71
  requirement: !ruby/object:Gem::Requirement
@@ -176,6 +170,26 @@ dependencies:
176
170
  - - "~>"
177
171
  - !ruby/object:Gem::Version
178
172
  version: 0.5.2
173
+ - !ruby/object:Gem::Dependency
174
+ name: parallel
175
+ requirement: !ruby/object:Gem::Requirement
176
+ requirements:
177
+ - - "~>"
178
+ - !ruby/object:Gem::Version
179
+ version: '1.19'
180
+ - - ">="
181
+ - !ruby/object:Gem::Version
182
+ version: 1.19.2
183
+ type: :runtime
184
+ prerelease: false
185
+ version_requirements: !ruby/object:Gem::Requirement
186
+ requirements:
187
+ - - "~>"
188
+ - !ruby/object:Gem::Version
189
+ version: '1.19'
190
+ - - ">="
191
+ - !ruby/object:Gem::Version
192
+ version: 1.19.2
179
193
  - !ruby/object:Gem::Dependency
180
194
  name: wisper
181
195
  requirement: !ruby/object:Gem::Requirement
@@ -203,7 +217,6 @@ files:
203
217
  - ".rubocop.yml"
204
218
  - ".travis.yml"
205
219
  - Gemfile
206
- - Guardfile
207
220
  - LICENSE.txt
208
221
  - README.md
209
222
  - Rakefile
@@ -253,7 +266,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
253
266
  version: '0'
254
267
  requirements: []
255
268
  rubyforge_project:
256
- rubygems_version: 2.7.7
269
+ rubygems_version: 2.7.6.2
257
270
  signing_key:
258
271
  specification_version: 4
259
272
  summary: Backup files to cloud drive
data/Guardfile DELETED
@@ -1,70 +0,0 @@
1
- # A sample Guardfile
2
- # More info at https://github.com/guard/guard#readme
3
-
4
- ## Uncomment and set this to only include directories you want to watch
5
- # directories %w(app lib config test spec features) \
6
- # .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
7
-
8
- ## Note: if you are using the `directories` clause above and you are not
9
- ## watching the project directory ('.'), then you will want to move
10
- ## the Guardfile to a watched dir and symlink it back, e.g.
11
- #
12
- # $ mkdir config
13
- # $ mv Guardfile config/
14
- # $ ln -s config/Guardfile .
15
- #
16
- # and, you'll have to watch "config/Guardfile" instead of "Guardfile"
17
-
18
- # Note: The cmd option is now required due to the increasing number of ways
19
- # rspec may be run, below are examples of the most common uses.
20
- # * bundler: 'bundle exec rspec'
21
- # * bundler binstubs: 'bin/rspec'
22
- # * spring: 'bin/rspec' (This will use spring if running and you have
23
- # installed the spring binstubs per the docs)
24
- # * zeus: 'zeus rspec' (requires the server to be started separately)
25
- # * 'just' rspec: 'rspec'
26
-
27
- guard :rspec, cmd: "bundle exec rspec" do
28
- require "guard/rspec/dsl"
29
- dsl = Guard::RSpec::Dsl.new(self)
30
-
31
- # Feel free to open issues for suggestions and improvements
32
-
33
- # RSpec files
34
- rspec = dsl.rspec
35
- watch(rspec.spec_helper) { rspec.spec_dir }
36
- watch(rspec.spec_support) { rspec.spec_dir }
37
- watch(rspec.spec_files)
38
-
39
- # Ruby files
40
- ruby = dsl.ruby
41
- dsl.watch_spec_files_for(ruby.lib_files)
42
-
43
- # Rails files
44
- rails = dsl.rails(view_extensions: %w(erb haml slim))
45
- dsl.watch_spec_files_for(rails.app_files)
46
- dsl.watch_spec_files_for(rails.views)
47
-
48
- watch(rails.controllers) do |m|
49
- [
50
- rspec.spec.call("routing/#{m[1]}_routing"),
51
- rspec.spec.call("controllers/#{m[1]}_controller"),
52
- rspec.spec.call("acceptance/#{m[1]}")
53
- ]
54
- end
55
-
56
- # Rails config changes
57
- watch(rails.spec_helper) { rspec.spec_dir }
58
- watch(rails.routes) { "#{rspec.spec_dir}/routing" }
59
- watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
60
-
61
- # Capybara features specs
62
- watch(rails.view_dirs) { |m| rspec.spec.call("features/#{m[1]}") }
63
- watch(rails.layouts) { |m| rspec.spec.call("features/#{m[1]}") }
64
-
65
- # Turnip features and steps
66
- watch(%r{^spec/acceptance/(.+)\.feature$})
67
- watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
68
- Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
69
- end
70
- end