storazzo 0.6.1 โ†’ 0.7.3

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: e82c96fbdff7b8d2f78556899257b431ec1e58ec255321bae2afb4ba3b1ac309
4
- data.tar.gz: f343d195bce5121d18f456b3fd90f8032a41427ae41e4248f5b8628aca1b0a3e
3
+ metadata.gz: 6948ac6219b8540a46f7a2c0a155e097168656ed6b09f0adc9b2601b62bc466d
4
+ data.tar.gz: b6f40f0dd0c025c0a03b59a11ba75b9a6ed0f398f93fb6ce1bf18538ef9ebdbf
5
5
  SHA512:
6
- metadata.gz: d9aa08e7fcc62e0d8a3510db4d26f27e227aa778f8e9d8e6d7831676936c282e97f72f57f08febdc7383dec2f1e4c66beb42eb94dae3638f422fc6073292f204
7
- data.tar.gz: e75cb487f55943dbae3d23242909ca61a83c39aaf5ef793225c074181f6914290d7f11aa3fa537f43010db4feab239efb14e88c5f30d91f737465081ad825309
6
+ metadata.gz: e2133288626b087aa3ec75c95626b7f23cb09b3073589bef4582837b12f7a1559b96afc0a7d42c4422c9fae61372143673170fcfca6ad6bfc9a509b3f1cef404
7
+ data.tar.gz: 1dc88ed96a2d77e5b38f68528315cecc409263bd350acb657ed643eb8e451247db28a23319816f2cfe3a65dc81b43a04fb90b059be36e6e289507a95b23ce49f
data/Gemfile CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  source 'https://rubygems.org'
4
4
 
5
+ gemspec
6
+
5
7
  # to troubleshoot/debug things
6
8
  gem 'rake'
7
9
  gem 'rubocop'
@@ -9,4 +11,17 @@ gem 'ruby-lsp', '~> 0.0.4', group: :development
9
11
 
10
12
  # gem 'pry'
11
13
  gem 'pry', group: :development
12
- # gem 'after_do' # To allow AFTER calling instance to do LOAD() automagically. Naah I can do without :)
14
+ gem 'minitest', group: :development
15
+
16
+ gem 'sqlite3'
17
+ gem 'thor'
18
+ gem 'google-cloud-storage'
19
+
20
+ group :test do
21
+ gem 'minitest'
22
+ gem 'minitest-reporters'
23
+ gem 'mocha'
24
+ gem 'rspec'
25
+ gem 'cucumber'
26
+ gem 'aruba' # For testing CLI applications
27
+ end
data/README.md CHANGED
@@ -3,35 +3,34 @@
3
3
 
4
4
  ๐Ÿ“ฆ Storazzo ๐Ÿ’Ž gem - a Gem to automatically parse your FS for mounts (๐Ÿ’ฝ ๐Ÿ’พ ๐Ÿ’ฟ ) and compute MD5 (๐Ÿค) of all files therein and then collect in central DB ๐Ÿ”‹ through ๐Ÿ“ฆ StorazzoApp๐Ÿ“ฆ (TM).
5
5
 
6
+ ![Storazzo logo](assets/storazzo-logo.png)
7
+
6
8
  # INSTALL
7
9
 
8
10
  `gem install storazzo`
9
11
 
10
12
  (Latest version is hosted in https://rubygems.org/gems/storazzo)
11
13
 
12
- # Tests
13
-
14
- I still struggle to enforce the include of LOCAL unchecked code rather than latest required system gem (cmon Ruby!)
15
- but I found loads of interesting ways to test my code by googling and StoackOverflowing:
16
-
17
- * `rake test TEST="test/sum_test.rb"`
18
- * test-gcs-bucket: `ruby -I test test/test_gcs_bucket.rb` (meh - see below)
19
- * test-media-subfolder: `rake test TEST="test/media/*.rb"`
14
+ # Development & Testing
20
15
 
21
- Single test in single file:
16
+ To run the tools locally without installing the gem, use `just` (recommended) or standard Ruby flags.
22
17
 
23
- * `rake test TEST="test/sum_test.rb" TESTOPTS="--name=test_returns_two"` (sample)
24
- * `rake test TEST="test/media/test_local_folder.rb" TESTOPTS="--name=test_1_first_directory_parsing_actually_works"`
25
- * `ruby -I test test/test_local_folder.rb -n test_first_directory_parsing_actually_works` (note this includes `storazzo` latest gem
26
- and doesnt benefit from LATEST code so its NOT good for testing: use RAKE for that).
18
+ ### Using `just` (Recommended)
19
+ This repository includes a `justfile` with common development commands:
20
+ * `just setup` - Install dependencies
21
+ * `just test` - Run all tests
22
+ * `just run scan /path` - Run the local `storazzo` CLI
23
+ * `just hello` - Run the local `hello-storazzo` script
27
24
 
28
- **Testing binary files** is hard: by default they 'require storazzo' and use the GEM INSTALLed version which is a few versions away, usually.
29
- So while developing you might want to include the lib/ folder, like this:
25
+ ### Manual Local Execution
26
+ If you don't have `just` installed, you can use `bundle exec` and the `-Ilib` flag:
27
+ * **Run CLI**: `bundle exec ruby -Ilib bin/storazzo scan /path`
28
+ * **Run Tests**: `bundle exec rake test`
29
+ * **Single Test**: `bundle exec ruby -Ilib:test test/media/test_local_folder.rb`
30
30
 
31
- * Use local gem (super latest) for checking latest code: `ruby -Ilib bin/hello-storazzo`
32
- * This will use the gem installed a few days ago, likely so wont do you any good to test latest code: `bin/hello-storazzo`
31
+ ### Why `bundle exec` and `-Ilib`?
32
+ Using `bundle exec` ensures all dependencies from the `Gemfile` are available. The `-Ilib` flag adds the local `lib/` directory to the Ruby load path, ensuring your local changes are used instead of any installed gem version.
33
33
 
34
- Now to toggle verbosity I believe I need to go into Rakefile (bummer)
35
34
  # Thanks
36
35
 
37
36
  Inspiration from:
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.6.1
1
+ 0.7.3
data/bin/hello-storazzo CHANGED
@@ -1,6 +1,10 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
+ require 'bundler/setup'
5
+ $LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
4
6
  require 'storazzo'
5
7
 
6
- Storazzo::Main.say_hi(ARGV[0])
8
+ msg = ARGV.empty? ? 'HelloStorazzo' : ARGV.join(' ')
9
+
10
+ Storazzo::Main.say_hi(msg)
data/bin/ricdisk-magic CHANGED
@@ -1,21 +1,15 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- ############# ############# ############# ############# ############# ############# ############# #############
5
- # placeholder until i make it work..
6
- # https://guides.rubygems.org/make-your-own-gem/#adding-an-executable
7
- # require 'storazzo'
8
- # require_relative '../lib/storazzo'
4
+ require 'bundler/setup'
5
+ $LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
6
+ require 'storazzo'
9
7
  require 'fileutils'
10
8
  require 'yaml'
11
9
  require 'socket'
12
- require 'optparse' # http://ruby.about.com/od/advancedruby/a/optionparser.htm
10
+ require 'optparse'
13
11
 
14
- # Including local gem.
15
- # puts File.expand_path(FileUtils.pwd, "/../")
16
- # local_gem_path = File.expand_path(FileUtils.pwd, "/../")
17
- # gem 'storazzo', path: local_gem_path
18
- require 'storazzo'
12
+ # require 'storazzo'
19
13
  # include Storazzo
20
14
  # include Storazzo::Colors
21
15
  extend Storazzo::Colors
@@ -32,8 +26,8 @@ include Storazzo::Common # instead
32
26
  # include 'lib/ric_disk'
33
27
  # extend Storazzo::Colors
34
28
 
35
- if RUBY_VERSION.split('.')[0] == 1
36
- puts 'Refusing to launch a script form Ruby 1. Sorry Ric, its 2020 damn it!'
29
+ if RUBY_VERSION.split('.')[0].to_i < 3
30
+ puts 'Refusing to launch a script form Ruby 1 or 2. Sorry Ric, its 2020 damn it!'
37
31
  exit 2020
38
32
  end
39
33
 
data/bin/stats-with-md5 CHANGED
@@ -7,7 +7,7 @@ require 'optparse' # http://ruby.about.com/od/advancedruby/a/optionparser.htm
7
7
  require 'date' # for DateTime
8
8
  require 'tempfile'
9
9
 
10
- if RUBY_VERSION.split('.')[0] == 1
10
+ if RUBY_VERSION.split('.')[0].to_i == 1
11
11
  puts 'Refusing to launch a script form Ruby 1. Sorry Ric, its 2020 damn it!'
12
12
  exit 2020
13
13
  end
data/bin/storazzo CHANGED
@@ -1,158 +1,112 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
+ require 'bundler/setup'
5
+ $LOAD_PATH.unshift(File.expand_path('../lib', __dir__))
4
6
  require 'storazzo'
5
- # gem 'storazzo', :path => File.expand_path("../lib", __FILE__)
7
+ require 'thor'
6
8
 
7
- require 'optparse'
8
-
9
- extend Storazzo::Colors
10
- include Storazzo::Common # instead
11
-
12
- if RUBY_VERSION.split('.')[0] == 1
13
- puts 'Refusing to launch a script form Ruby 1. Sorry Ric, its 2020 damn it!'
9
+ if RUBY_VERSION.split('.')[0].to_i < 3
10
+ puts 'Refusing to launch a script form Ruby < 3.'
14
11
  exit 2020
15
12
  end
16
13
 
17
- $PROG_VER = '0.1'
18
- $DEBUG = ENV['DEBUG'] == 'true' # (true/false)
19
-
20
- $actions = %w[
21
- show auto help
22
- ].sort
23
-
24
- # you can't but love Ruby monkey-patching ability..
25
- class Array
26
- # puts "array drop"
27
- def tail
28
- drop(1) # https://stackoverflow.com/questions/3615700/ruby-what-is-the-easiest-way-to-remove-the-first-element-from-an-array
29
- end
30
- end
14
+ module Storazzo
15
+ class CLI < Thor
16
+ include ::Storazzo::Colors
17
+ include ::Storazzo::Common
18
+
19
+ class_option :verbose, type: :boolean, default: false, desc: 'Output more information'
20
+ class_option :debug, type: :boolean, default: false, desc: 'Enable debug mode'
21
+
22
+ desc "scan PATH", "Scan a removable disk or local folder and upload its metadata to GCS"
23
+ def scan(path)
24
+ setup_env
25
+ puts "Scanning path: #{path}"
26
+
27
+ dir = File.expand_path(path)
28
+ unless File.directory?(dir)
29
+ puts "Error: #{dir} is not a valid directory."
30
+ exit 1
31
+ end
32
+
33
+ config = Storazzo::RicDiskConfig.instance
34
+ config.load
35
+
36
+ rd = Storazzo::RicDisk.new(Storazzo::Media::AbstractRicDisk.DirFactory(dir))
37
+ rd.write_config_yaml_to_disk(dir)
38
+ rd.compute_stats_files(upload_to_gcs: true)
39
+
40
+ puts "Scan completed for #{dir}."
41
+ end
31
42
 
32
- HISTORY = <<-BIG_LONG_MULTILINE
33
- 2022-0806 v0.1 First stesure
34
- BIG_LONG_MULTILINE
35
-
36
- $description = <<DESCRIPTION_HEREFILE.gsub(/\s+/, ' ').strip
37
- This util shall expose all Storazzo aPIs via CLI: show-local-dirs, ...
38
- show GCS buckets, ...
39
-
40
- It's also my dream to add some nice icons which are joy to the eye, like
41
- some [ ] [x] before the list to show if its agood or bad directory and type also#{' '}
42
- DESCRIPTION_HEREFILE
43
- # >> "SELECT * FROM users ORDER BY users.id DESC"
44
-
45
- $myconf = {
46
- app_name: "Storazzo CLI: #{$PROGRAM_NAME}",
47
- description: $description
48
- # TODO: move to some class default
49
- # :media_dirs => %w{/media/riccardo/ /Volumes/ /mnt/ ~/git/storazzo/var/test/
50
- # /sobenme/giusto/per/imparare/ad/ammutolire/gli/errori/},
51
- # :mount_types => %w{vfat ntfs},
52
- }
53
-
54
- def usage(comment = nil)
55
- puts white($optparse.banner)
56
- puts($optparse.summarize)
57
- # puts("Description: " + gray($myconf[:description]))
58
- puts red("ERROR: #{comment}") if comment
59
- # puts "Description: #{ $myconf[:description] }"
60
- exit 13
61
- end
43
+ desc "search QUERY", "Search for a keyword across all indexed disks via SQLite DB"
44
+ def search(query)
45
+ setup_env
46
+ require 'storazzo/search_engine'
47
+
48
+ puts "Searching for: #{query}"
49
+ engine = Storazzo::SearchEngine.new
50
+ engine.sync_from_gcs
51
+ results = engine.query(query)
52
+
53
+ if results.empty?
54
+ puts "No results found for '#{query}'."
55
+ else
56
+ puts "Found #{results.size} matches:"
57
+ results.each do |r|
58
+ puts "- [#{r[:disk]}] #{r[:path]} (size: #{r[:size]})"
59
+ end
60
+ end
61
+ end
62
62
 
63
- # include it in main if you want a custome one
64
- # see lib_autoinit in lib/util.rb
65
- def init
66
- $opts = {}
67
- # setting defaults
68
- $opts[:verbose] = false
69
- $opts[:dryrun] = false
70
- $opts[:debug] = false
71
- $opts[:force] = false
72
-
73
- $optparse = OptionParser.new do |opts|
74
- opts.banner = "#{$PROGRAM_NAME} v.#{$PROG_VER}\n Usage: #{File.basename $PROGRAM_NAME} [options] ACTION [file1] [file2] ..."
75
- opts.separator "Actions: #{$actions.join ', '}"
76
- opts.separator ' $0 show # show options and local folders '
77
- opts.separator ' $0 auto # takes automated actions based on config and local disk. For lazy users'
78
- opts.separator 'Options: '
79
- opts.on('-d', '--debug', 'enables debug (DFLT=false)') do
80
- $opts[:debug] = true
81
- $DEBUG = true
63
+ desc "backup SRC DEST", "Backup a local folder to GCS and update index"
64
+ def backup(src, dest)
65
+ setup_env
66
+ puts "Backing up #{src} to #{dest}"
67
+
68
+ src_dir = File.expand_path(src)
69
+ unless File.directory?(src_dir)
70
+ puts "Error: #{src_dir} is not a valid directory."
71
+ exit 1
72
+ end
73
+
74
+ # 1. Run gsutil rsync
75
+ cmd = "gsutil -m rsync -r '#{src_dir}' '#{dest}'"
76
+ puts "Running: #{cmd}"
77
+ system(cmd)
78
+ unless $?.success?
79
+ puts "Failed to backup files to GCS."
80
+ exit 1
81
+ end
82
+
83
+ # 2. Compute stats on the destination bucket
84
+ require 'storazzo/search_engine'
85
+ # We could run `stats-with-md5` for GCS here to generate the index
86
+ # and upload to metadata bucket
87
+ puts "Indexing GCS bucket: #{dest}"
88
+ cmd_stats = "stats-with-md5 --autowrite '#{dest}'"
89
+ system(cmd_stats)
90
+
91
+ puts "Backup and indexing completed."
82
92
  end
83
- opts.on('-f', '--force', 'force stuff (DFLT=false)') { $opts[:force] = true }
84
- opts.on('-h', '--help', 'Display this screen') { usage }
85
- # opts.on( '-j', '--jabba', 'Activates my Jabber powerful CLI' ) { $opts[:jabba] = true }
86
- opts.on('-n', '--dryrun', "Don't really execute code") { $opts[:dryrun] = true }
87
- opts.on('-l', '--logfile FILE', 'Write log to FILE') { |file| $opts[:logfile] = file }
88
- opts.on('-v', '--verbose', 'Output more information') { $opts[:verbose] = true }
89
- opts.separator("Description: #{gray($myconf[:description])}")
90
- # opts.separator " -- "
91
- end
92
- $optparse.parse!
93
- end
94
93
 
95
- def show_action(argv)
96
- deb "ARGV remaning is: #{argv}"
97
- deb('TODO show_action')
98
- # puts(white("1. Config"))
99
- # Pry::ColorPrinter.pp $config.to_verbose_s
100
- puts(white('2. Mounts/Dirs'))
101
- Pry::ColorPrinter.pp Storazzo::Media::GcsBucket.list_all_with_type
102
- pp Storazzo::Media::AbstractRicDisk.super_duper_list_all_with_type
103
- end
94
+ desc "show", "Show options and local folders"
95
+ def show
96
+ setup_env
97
+ puts("1. Mounts/Dirs")
98
+ require 'pp'
99
+ pp Storazzo::Media::GcsBucket.list_all_with_type
100
+ pp Storazzo::Media::AbstractRicDisk.super_duper_list_all_with_type
101
+ end
104
102
 
105
- def real_program
106
- deb("Hello world from a templated '#{yellow $PROGRAM_NAME}'")
107
- deb "+ Options are: #{gray $opts}"
108
- deb "+ Depured args: #{azure ARGV}"
109
- deb "+ Script-specifig super-cool conf: #{green $prog_conf_d}"
110
- deb "+ Your configuration: #{purple $myconf.inspect}"
111
-
112
- # Your code goes here...
113
- puts white("Hello world from #{$myconf[:app_name]}!")
114
- puts "Description: '''#{white $myconf[:description]}'''"
115
- Storazzo::Main.say_hi("Note: if the version of this storazzo is behind local version youre probably using a old library.
116
- I still need to learn how to call the binary with local/current lib/: bundle exec stiKazzi?")
117
-
118
- $config = Storazzo::RicDiskConfig.instance
119
- $config.load
120
- deb "StorazzoConfig: #{$config}"
121
- # config.load # auto_sbrodola(ARGV)
122
- puts yellow("ARGV: #{ARGV}")
123
- # config.iterate_through_file_list_for_disks(ARGV)
124
-
125
- if_deb? { Storazzo::Main.say_hi("ARGV: #{ARGV}") }
126
-
127
- usage('I need at least one argument (storazzo ACTION)') if ARGV == []
128
- argv_action = ARGV[0]
129
- case argv_action # first argment - action
130
- when 'show', 'list'
131
- show_action(ARGV.tail)
132
- when 'auto'
133
- auto_action(ARGV.tail)
134
- when 'help'
135
- usage("There you go, here's your HELP :)")
136
- when String
137
- usage("Unknown action1: #{argv_action}. Available actions: #{$actions}")
138
- else
139
- usage("Unknown action2, really strange!: '#{argv_action}'. Actions: #{$actions}")
140
- end
141
- end
103
+ private
142
104
 
143
- def main(filename)
144
- deb "I'm called by #{white filename}"
145
- deb "HISTORY: #{gray HISTORY}"
146
- init # Enable this to have command line parsing capabilities!
147
- puts white("$DEBUG is #{$DEBUG}. Tu turn on, call me with -d") unless $DEBUG
148
- # warn "[warn] template v#{$TEMPLATE_VER }: proviamo il warn che magari depreca il DEB"
149
- real_program
150
-
151
- if_deb? do
152
- puts 'First I need to figure out how to bring in all the libraries in here..'
153
- Storazzo::Main.say_hi("ARGV is: #{ARGV.join ', '}")
154
- puts Storazzo.version
105
+ def setup_env
106
+ $DEBUG = options[:debug]
107
+ $opts = { verbose: options[:verbose], debug: options[:debug] }
108
+ end
155
109
  end
156
110
  end
157
111
 
158
- main(__FILE__)
112
+ Storazzo::CLI.start(ARGV)
@@ -1 +1 @@
1
- bin/storazzo
1
+ storazzo
data/bin/storazzo-util CHANGED
@@ -1 +1 @@
1
- bin/storazzo
1
+ storazzo
@@ -28,7 +28,12 @@
28
28
  # ๐Ÿ‘ถ ๐Ÿง’ ๐Ÿ‘ฆ ๐Ÿ‘ง ๐Ÿ‘ฉ ๐Ÿ‘จ ๐Ÿง‘ ๐Ÿง” ๐Ÿง“ ๐Ÿ‘ด ๐Ÿ‘ต ๐Ÿ‘ค ๐Ÿ‘ฅ ๐Ÿ‘ช ๐Ÿ‘ซ ๐Ÿ‘ฌ ๐Ÿ‘ญ ๐Ÿ‘ฑ ๐Ÿ‘ณ ๐Ÿ‘ฒ ๐Ÿง• ๐Ÿ‘ธ ๐Ÿคด ๐ŸŽ… ๐Ÿคถ disabled
29
29
  # ๐Ÿง ๐Ÿฆป ๐Ÿฆฎ ๐Ÿฆฏ ๐Ÿฆบ ๐Ÿฆผ ๐Ÿฆฝ ๐Ÿฆพ ๐Ÿฆฟ ๐Ÿคต ๐Ÿ‘ฎ ๐Ÿ‘ท ๐Ÿ’ ๐Ÿ’‚ ๐Ÿ•ด ๐Ÿ•ต ๐Ÿฆธ ๐Ÿฆน ๐Ÿง™ ๐Ÿงš ๐Ÿงœ ๐Ÿง ๐Ÿงž ๐Ÿง› ๐ŸงŸ ๐Ÿ‘ผ ๐Ÿ‘ฟ ๐Ÿ‘ป ๐Ÿ‘น ๐Ÿ‘บ ๐Ÿ‘ฝ ๐Ÿ‘พ ๐Ÿ›ธ ๐Ÿ’€ โ˜  ๐Ÿ•ฑ ๐Ÿง  ๐Ÿฆด ๐Ÿ‘ ๐Ÿ‘€ ๐Ÿ‘‚ ๐Ÿ‘ƒ ๐Ÿ‘„ ๐Ÿ—ข ๐Ÿ‘… ๐Ÿฆท ๐Ÿฆต ๐Ÿฆถ ๐Ÿ’ญ ๐Ÿ—ฌ ๐Ÿ—ญ ๐Ÿ’ฌ ๐Ÿ—จ ๐Ÿ—ฉ ๐Ÿ—ช ๐Ÿ—ซ ๐Ÿ—ฐ ๐Ÿ—ฑ ๐Ÿ—ฎ ๐Ÿ—ฏ ๐Ÿ—ฃ ๐Ÿ—ค ๐Ÿ—ฅ ๐Ÿ—ฆ ๐Ÿ—ง ๐Ÿ’ฆ ๐Ÿ’ง ๐Ÿ’ข ๐Ÿ’ซ ๐Ÿ’ค ๐Ÿ’จ ๐Ÿ’ฅ ๐Ÿ’ช ๐Ÿ—ฒ ๐Ÿ”ฅ ๐Ÿ’ก ๐Ÿ’ฉ ๐Ÿ’ฏ ๐Ÿ”Ÿ ๐Ÿ”ฐ ๐Ÿ•ฒ
30
30
  require_relative 'colors'
31
- require 'pry'
31
+ # require 'pry'
32
+ begin
33
+ require 'pry'
34
+ rescue LoadError
35
+ # Pry not available, no worries
36
+ end
32
37
 
33
38
  module Storazzo
34
39
  module Common
@@ -52,8 +57,8 @@ module Storazzo
52
57
  puts "[Wโš ๏ธRN] #{azure(s)}"
53
58
  end
54
59
 
55
- def err(_str)
56
- puts "[ERR๐Ÿ‘Ž] #{red(s)}" # โ›”
60
+ def err(str)
61
+ puts "[ERR๐Ÿ‘Ž] #{red(str)}" # โ›”
57
62
  end
58
63
 
59
64
  def bug(s)
@@ -68,8 +73,12 @@ module Storazzo
68
73
  end
69
74
 
70
75
  def ppp(complex_object_to_colorize)
71
- # TODO: i need to learn to return without printing..
72
- Pry::ColorPrinter.pp(complex_object_to_colorize)
76
+ if defined?(Pry::ColorPrinter)
77
+ Pry::ColorPrinter.pp(complex_object_to_colorize)
78
+ else
79
+ require 'pp'
80
+ pp complex_object_to_colorize
81
+ end
73
82
  end
74
83
 
75
84
  def fatal(s)
@@ -84,6 +93,10 @@ module Storazzo
84
93
  `uname`.chomp == 'Linux'
85
94
  end
86
95
 
96
+ def slugify(string)
97
+ string.to_s.downcase.strip.gsub(/\s+/, '_').gsub(/[^\w-]/, '')
98
+ end
99
+
87
100
  private
88
101
 
89
102
  def _debug_true
@@ -0,0 +1,85 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'google/cloud/storage'
4
+ require 'storazzo/common'
5
+
6
+ module Storazzo
7
+ module GCS
8
+ class Client
9
+ include Storazzo::Common
10
+
11
+ attr_reader :storage, :project_id, :bucket_name
12
+
13
+ def initialize(project_id = nil, bucket_name = nil)
14
+ @project_id = project_id || autodetect_project_id
15
+ @bucket_name = bucket_name || ENV['GCS_BUCKET'] || "#{@project_id}-storazzo"
16
+ deb "GCS Client initialized for project: #{@project_id}, bucket: #{@bucket_name}"
17
+ end
18
+
19
+ def storage
20
+ @storage ||= Google::Cloud::Storage.new(project_id: @project_id)
21
+ end
22
+
23
+ def ensure_bucket_exists
24
+ return true if bucket_exists?(@bucket_name)
25
+
26
+ deb "Bucket #{@bucket_name} not found. Creating it in project #{@project_id}..."
27
+ storage.create_bucket(@bucket_name)
28
+ true
29
+ rescue StandardError => e
30
+ err "Failed to ensure/create bucket #{@bucket_name}: #{e.message}"
31
+ false
32
+ end
33
+
34
+ def autodetect_project_id
35
+ # Priority 1: Environment Variable
36
+ return ENV['GOOGLE_CLOUD_PROJECT'] if ENV['GOOGLE_CLOUD_PROJECT']
37
+
38
+ # Priority 2: Config file
39
+ config = Storazzo::RicDiskConfig.instance
40
+ config.load
41
+ return config.project_id if config.project_id && config.project_id != 'YOUR-PROJECT-ID'
42
+
43
+ # Priority 3: GCloud CLI default
44
+ begin
45
+ `gcloud config get-value project 2>/dev/null`.strip
46
+ rescue StandardError
47
+ nil
48
+ end
49
+ end
50
+
51
+ def bucket_exists?(bucket_name)
52
+ bucket_name = bucket_name.gsub('gs://', '').split('/').first
53
+ !storage.bucket(bucket_name).nil?
54
+ rescue StandardError => e
55
+ warn "Error checking bucket #{bucket_name}: #{e.message}"
56
+ false
57
+ end
58
+
59
+ def list_buckets
60
+ storage.buckets.map(&:name)
61
+ end
62
+
63
+ def upload_file(local_path, bucket_name, remote_path)
64
+ bucket_name = bucket_name.gsub('gs://', '').split('/').first
65
+ bucket = storage.bucket(bucket_name)
66
+ raise "Bucket #{bucket_name} not found!" unless bucket
67
+
68
+ deb "Uploading #{local_path} to gs://#{bucket_name}/#{remote_path}..."
69
+ bucket.create_file(local_path, remote_path)
70
+ end
71
+
72
+ def download_file(bucket_name, remote_path, local_path)
73
+ bucket_name = bucket_name.gsub('gs://', '').split('/').first
74
+ bucket = storage.bucket(bucket_name)
75
+ raise "Bucket #{bucket_name} not found!" unless bucket
76
+
77
+ file = bucket.file(remote_path)
78
+ raise "Remote file #{remote_path} not found in bucket #{bucket_name}!" unless file
79
+
80
+ deb "Downloading gs://#{bucket_name}/#{remote_path} to #{local_path}..."
81
+ file.download(local_path)
82
+ end
83
+ end
84
+ end
85
+ end
data/lib/storazzo/main.rb CHANGED
@@ -15,11 +15,9 @@ module Storazzo
15
15
  # Arguments:
16
16
  # message: (String) - optional
17
17
 
18
- # Can be same name as Module: https://stackoverflow.com/questions/13261474/ruby-modules-and-classes-same-name-in-structure
19
- module Storazzo
20
- class Main
18
+ class Main
21
19
  require 'storazzo/colors'
22
- extend Storazzo::Colors
20
+ extend ::Storazzo::Colors
23
21
 
24
22
  # version 1.2
25
23
  def self.say_hi(message = nil)
@@ -78,6 +76,5 @@ module Storazzo
78
76
  pwhite 'All tests END'
79
77
  # puts "All tests END"
80
78
  end
81
- end
82
79
  end
83
80
  end