raygatherer 0.1.0 → 0.3.0
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 +4 -4
- data/README.md +71 -18
- data/lib/raygatherer/api_client.rb +101 -27
- data/lib/raygatherer/cli.rb +39 -17
- data/lib/raygatherer/commands/alerts.rb +7 -12
- data/lib/raygatherer/commands/analysis/report.rb +77 -0
- data/lib/raygatherer/commands/analysis/run.rb +10 -7
- data/lib/raygatherer/commands/analysis/status.rb +1 -9
- data/lib/raygatherer/commands/base.rb +20 -1
- data/lib/raygatherer/commands/config/set.rb +1 -4
- data/lib/raygatherer/commands/config/show.rb +1 -9
- data/lib/raygatherer/commands/config/test_notification.rb +1 -4
- data/lib/raygatherer/commands/debug/display_state.rb +95 -0
- data/lib/raygatherer/commands/gps/set.rb +69 -0
- data/lib/raygatherer/commands/gps/show.rb +54 -0
- data/lib/raygatherer/commands/log.rb +38 -0
- data/lib/raygatherer/commands/recording/delete.rb +55 -11
- data/lib/raygatherer/commands/recording/download.rb +6 -9
- data/lib/raygatherer/commands/recording/list.rb +1 -9
- data/lib/raygatherer/commands/recording/start.rb +2 -5
- data/lib/raygatherer/commands/recording/stop.rb +2 -5
- data/lib/raygatherer/commands/stats.rb +4 -9
- data/lib/raygatherer/commands/time/show.rb +52 -0
- data/lib/raygatherer/commands/time/sync.rb +53 -0
- data/lib/raygatherer/commands/update/status.rb +62 -0
- data/lib/raygatherer/commands/wifi/scan.rb +54 -0
- data/lib/raygatherer/commands/wifi/show.rb +55 -0
- data/lib/raygatherer/formatters/{human.rb → alerts_human.rb} +1 -1
- data/lib/raygatherer/formatters/{json.rb → alerts_json.rb} +2 -2
- data/lib/raygatherer/formatters/analysis_report_human.rb +88 -0
- data/lib/raygatherer/formatters/analysis_report_json.rb +13 -0
- data/lib/raygatherer/formatters/config_human.rb +39 -2
- data/lib/raygatherer/formatters/gps_human.rb +13 -0
- data/lib/raygatherer/formatters/gps_json.rb +13 -0
- data/lib/raygatherer/formatters/recording_list_human.rb +6 -1
- data/lib/raygatherer/formatters/time_human.rb +15 -0
- data/lib/raygatherer/formatters/time_json.rb +13 -0
- data/lib/raygatherer/formatters/update_status_human.rb +25 -0
- data/lib/raygatherer/formatters/update_status_json.rb +13 -0
- data/lib/raygatherer/formatters/wifi_scan_human.rb +17 -0
- data/lib/raygatherer/formatters/wifi_scan_json.rb +13 -0
- data/lib/raygatherer/formatters/wifi_status_human.rb +19 -0
- data/lib/raygatherer/formatters/wifi_status_json.rb +13 -0
- data/lib/raygatherer/version.rb +6 -1
- data/lib/raygatherer.rb +24 -2
- metadata +41 -6
- data/CLAUDE.md +0 -102
|
@@ -9,11 +9,6 @@ module Raygatherer
|
|
|
9
9
|
module Commands
|
|
10
10
|
module Analysis
|
|
11
11
|
class Status < Base
|
|
12
|
-
def initialize(argv, stdout: $stdout, stderr: $stderr, api_client: nil, json: false)
|
|
13
|
-
super(argv, stdout: stdout, stderr: stderr, api_client: api_client)
|
|
14
|
-
@json = json
|
|
15
|
-
end
|
|
16
|
-
|
|
17
12
|
def run
|
|
18
13
|
with_error_handling do
|
|
19
14
|
parse_options
|
|
@@ -35,10 +30,7 @@ module Raygatherer
|
|
|
35
30
|
opts.separator ""
|
|
36
31
|
opts.separator "Options:"
|
|
37
32
|
|
|
38
|
-
opts
|
|
39
|
-
show_help
|
|
40
|
-
raise CLI::EarlyExit, EXIT_CODE_SUCCESS
|
|
41
|
-
end
|
|
33
|
+
add_help_option(opts)
|
|
42
34
|
end.parse!(@argv)
|
|
43
35
|
end
|
|
44
36
|
|
|
@@ -10,15 +10,23 @@ module Raygatherer
|
|
|
10
10
|
new(argv, **kwargs).run
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
def initialize(argv, stdout: $stdout, stderr: $stderr, api_client: nil, **_kwargs)
|
|
13
|
+
def initialize(argv, stdout: $stdout, stderr: $stderr, api_client: nil, json: false, **_kwargs)
|
|
14
14
|
@argv = argv
|
|
15
15
|
@stdout = stdout
|
|
16
16
|
@stderr = stderr
|
|
17
17
|
@api_client = api_client
|
|
18
|
+
@json = json
|
|
18
19
|
end
|
|
19
20
|
|
|
20
21
|
private
|
|
21
22
|
|
|
23
|
+
def add_help_option(opts)
|
|
24
|
+
opts.on("-h", "--help", "Show this help message") do
|
|
25
|
+
show_help
|
|
26
|
+
raise CLI::EarlyExit, EXIT_CODE_SUCCESS
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
22
30
|
def print_global_options(output, json: false)
|
|
23
31
|
output.puts "Global options (see 'raygatherer --help'):"
|
|
24
32
|
if json
|
|
@@ -36,6 +44,17 @@ module Raygatherer
|
|
|
36
44
|
@stderr.puts "Error: #{e.message}"
|
|
37
45
|
EXIT_CODE_ERROR
|
|
38
46
|
end
|
|
47
|
+
|
|
48
|
+
def warn_if_rayhunter_outdated(rayhunter_version)
|
|
49
|
+
actual = Gem::Version.new(rayhunter_version)
|
|
50
|
+
tested = Gem::Version.new(Raygatherer::TESTED_RAYHUNTER_VERSION)
|
|
51
|
+
return unless actual < tested
|
|
52
|
+
|
|
53
|
+
@stderr.puts "Warning: connected rayhunter is v#{rayhunter_version}; raygatherer was last " \
|
|
54
|
+
"tested against v#{Raygatherer::TESTED_RAYHUNTER_VERSION} — some fields or commands may not be supported."
|
|
55
|
+
rescue ArgumentError
|
|
56
|
+
nil
|
|
57
|
+
end
|
|
39
58
|
end
|
|
40
59
|
end
|
|
41
60
|
end
|
|
@@ -9,11 +9,6 @@ module Raygatherer
|
|
|
9
9
|
module Commands
|
|
10
10
|
module Config
|
|
11
11
|
class Show < Base
|
|
12
|
-
def initialize(argv, stdout: $stdout, stderr: $stderr, api_client: nil, json: false)
|
|
13
|
-
super(argv, stdout: stdout, stderr: stderr, api_client: api_client)
|
|
14
|
-
@json = json
|
|
15
|
-
end
|
|
16
|
-
|
|
17
12
|
def run
|
|
18
13
|
with_error_handling do
|
|
19
14
|
parse_options
|
|
@@ -35,10 +30,7 @@ module Raygatherer
|
|
|
35
30
|
opts.separator ""
|
|
36
31
|
opts.separator "Options:"
|
|
37
32
|
|
|
38
|
-
opts
|
|
39
|
-
show_help
|
|
40
|
-
raise CLI::EarlyExit, EXIT_CODE_SUCCESS
|
|
41
|
-
end
|
|
33
|
+
add_help_option(opts)
|
|
42
34
|
end.parse!(@argv)
|
|
43
35
|
end
|
|
44
36
|
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "json"
|
|
4
|
+
require "optparse"
|
|
5
|
+
require_relative "../base"
|
|
6
|
+
|
|
7
|
+
module Raygatherer
|
|
8
|
+
module Commands
|
|
9
|
+
module Debug
|
|
10
|
+
class DisplayState < Base
|
|
11
|
+
VALID_STATES = %w[recording paused warning].freeze
|
|
12
|
+
VALID_SEVERITIES = %w[low medium high].freeze
|
|
13
|
+
|
|
14
|
+
def initialize(argv, stdout: $stdout, stderr: $stderr, api_client: nil)
|
|
15
|
+
super
|
|
16
|
+
@severity = nil
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def run
|
|
20
|
+
with_error_handling do
|
|
21
|
+
parse_options
|
|
22
|
+
|
|
23
|
+
state = @argv.shift
|
|
24
|
+
|
|
25
|
+
unless VALID_STATES.include?(state)
|
|
26
|
+
@stderr.puts "Error: state must be one of: #{VALID_STATES.join(", ")}"
|
|
27
|
+
return EXIT_CODE_ERROR
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
if state == "warning" && @severity.nil?
|
|
31
|
+
@stderr.puts "Error: --severity is required when state is 'warning'"
|
|
32
|
+
return EXIT_CODE_ERROR
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
if state != "warning" && !@severity.nil?
|
|
36
|
+
@stderr.puts "Error: --severity is only valid when state is 'warning'"
|
|
37
|
+
return EXIT_CODE_ERROR
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
@api_client.set_display_state(build_body(state))
|
|
41
|
+
@stdout.puts "Display state updated."
|
|
42
|
+
|
|
43
|
+
EXIT_CODE_SUCCESS
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def build_body(state)
|
|
50
|
+
case state
|
|
51
|
+
when "recording" then JSON.generate("Recording")
|
|
52
|
+
when "paused" then JSON.generate("Paused")
|
|
53
|
+
when "warning" then JSON.generate({"WarningDetected" => {"event_type" => @severity.capitalize}})
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def parse_options
|
|
58
|
+
OptionParser.new do |opts|
|
|
59
|
+
opts.banner = "Usage: raygatherer debug display-state [options] STATE"
|
|
60
|
+
opts.separator ""
|
|
61
|
+
opts.separator "Options:"
|
|
62
|
+
|
|
63
|
+
opts.on("--severity LEVEL", VALID_SEVERITIES, "Severity: low, medium, high (required for 'warning' state)") do |s|
|
|
64
|
+
@severity = s
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
add_help_option(opts)
|
|
68
|
+
end.parse!(@argv)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def show_help(output = @stdout)
|
|
72
|
+
output.puts "Usage: raygatherer [global options] debug display-state [options] STATE"
|
|
73
|
+
output.puts ""
|
|
74
|
+
output.puts "Change the display state of the device for debugging purposes."
|
|
75
|
+
output.puts ""
|
|
76
|
+
output.puts "States:"
|
|
77
|
+
output.puts " recording Device is recording, no warnings"
|
|
78
|
+
output.puts " paused Device is not recording"
|
|
79
|
+
output.puts " warning Warning detected (requires --severity)"
|
|
80
|
+
output.puts ""
|
|
81
|
+
output.puts "Options:"
|
|
82
|
+
output.puts " --severity LEVEL Warning severity: low, medium, high"
|
|
83
|
+
output.puts " -h, --help Show this help message"
|
|
84
|
+
output.puts ""
|
|
85
|
+
print_global_options(output)
|
|
86
|
+
output.puts ""
|
|
87
|
+
output.puts "Examples:"
|
|
88
|
+
output.puts " raygatherer --host http://192.168.1.100:8080 debug display-state recording"
|
|
89
|
+
output.puts " raygatherer --host http://192.168.1.100:8080 debug display-state paused"
|
|
90
|
+
output.puts " raygatherer --host http://192.168.1.100:8080 debug display-state warning --severity high"
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "../base"
|
|
4
|
+
|
|
5
|
+
module Raygatherer
|
|
6
|
+
module Commands
|
|
7
|
+
module Gps
|
|
8
|
+
class Set < Base
|
|
9
|
+
def run
|
|
10
|
+
with_error_handling do
|
|
11
|
+
parse_options
|
|
12
|
+
|
|
13
|
+
unless @argv.length == 2
|
|
14
|
+
@stderr.puts "Error: latitude and longitude are required (usage: gps set LAT LON)"
|
|
15
|
+
return EXIT_CODE_ERROR
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
lat_str, lon_str = @argv
|
|
19
|
+
|
|
20
|
+
latitude = parse_coordinate(lat_str, "latitude")
|
|
21
|
+
return EXIT_CODE_ERROR unless latitude
|
|
22
|
+
|
|
23
|
+
longitude = parse_coordinate(lon_str, "longitude")
|
|
24
|
+
return EXIT_CODE_ERROR unless longitude
|
|
25
|
+
|
|
26
|
+
@api_client.set_gps(latitude, longitude)
|
|
27
|
+
@stdout.puts "GPS position set: #{latitude}, #{longitude}"
|
|
28
|
+
|
|
29
|
+
EXIT_CODE_SUCCESS
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def parse_coordinate(str, label)
|
|
36
|
+
Float(str)
|
|
37
|
+
rescue ArgumentError
|
|
38
|
+
@stderr.puts "Error: #{label} must be a number (got #{str.inspect})"
|
|
39
|
+
nil
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Deliberately not using OptionParser#parse! here: a negative longitude like "-0.1"
|
|
43
|
+
# looks like an unrecognized flag to it and raises OptionParser::InvalidOption. This
|
|
44
|
+
# command's only "option" is help, so just scan for it directly instead.
|
|
45
|
+
def parse_options
|
|
46
|
+
return unless @argv.include?("-h") || @argv.include?("--help")
|
|
47
|
+
|
|
48
|
+
show_help
|
|
49
|
+
raise CLI::EarlyExit, EXIT_CODE_SUCCESS
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def show_help(output = @stdout)
|
|
53
|
+
output.puts "Usage: raygatherer [global options] gps set [options] LAT LON"
|
|
54
|
+
output.puts ""
|
|
55
|
+
output.puts "Submit a GPS position to the device, to be embedded into the current recording."
|
|
56
|
+
output.puts "Requires the device's gps_mode config to be set to 'Api' (see 'config show'/'config set')."
|
|
57
|
+
output.puts ""
|
|
58
|
+
output.puts "Options:"
|
|
59
|
+
output.puts " -h, --help Show this help message"
|
|
60
|
+
output.puts ""
|
|
61
|
+
print_global_options(output)
|
|
62
|
+
output.puts ""
|
|
63
|
+
output.puts "Examples:"
|
|
64
|
+
output.puts " raygatherer --host http://192.168.1.100:8080 gps set 51.5074 -0.1278"
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "optparse"
|
|
4
|
+
require_relative "../base"
|
|
5
|
+
require_relative "../../formatters/gps_json"
|
|
6
|
+
require_relative "../../formatters/gps_human"
|
|
7
|
+
|
|
8
|
+
module Raygatherer
|
|
9
|
+
module Commands
|
|
10
|
+
module Gps
|
|
11
|
+
class Show < Base
|
|
12
|
+
def run
|
|
13
|
+
with_error_handling do
|
|
14
|
+
parse_options
|
|
15
|
+
|
|
16
|
+
gps = @api_client.fetch_gps
|
|
17
|
+
|
|
18
|
+
formatter = @json ? Formatters::GpsJSON.new : Formatters::GpsHuman.new
|
|
19
|
+
@stdout.puts formatter.format(gps)
|
|
20
|
+
|
|
21
|
+
EXIT_CODE_SUCCESS
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def parse_options
|
|
28
|
+
OptionParser.new do |opts|
|
|
29
|
+
opts.banner = "Usage: raygatherer gps show [options]"
|
|
30
|
+
opts.separator ""
|
|
31
|
+
opts.separator "Options:"
|
|
32
|
+
|
|
33
|
+
add_help_option(opts)
|
|
34
|
+
end.parse!(@argv)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def show_help(output = @stdout)
|
|
38
|
+
output.puts "Usage: raygatherer [global options] gps show [options]"
|
|
39
|
+
output.puts ""
|
|
40
|
+
output.puts "Show the last GPS position submitted to the device (see 'gps set')."
|
|
41
|
+
output.puts ""
|
|
42
|
+
output.puts "Options:"
|
|
43
|
+
output.puts " -h, --help Show this help message"
|
|
44
|
+
output.puts ""
|
|
45
|
+
print_global_options(output, json: true)
|
|
46
|
+
output.puts ""
|
|
47
|
+
output.puts "Examples:"
|
|
48
|
+
output.puts " raygatherer --host http://192.168.1.100:8080 gps show"
|
|
49
|
+
output.puts " raygatherer --host http://192.168.1.100:8080 --json gps show"
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "optparse"
|
|
4
|
+
require_relative "base"
|
|
5
|
+
|
|
6
|
+
module Raygatherer
|
|
7
|
+
module Commands
|
|
8
|
+
class Log < Base
|
|
9
|
+
def run
|
|
10
|
+
with_error_handling do
|
|
11
|
+
parse_options
|
|
12
|
+
@stdout.print @api_client.fetch_log
|
|
13
|
+
EXIT_CODE_SUCCESS
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def parse_options
|
|
20
|
+
OptionParser.new do |opts|
|
|
21
|
+
add_help_option(opts)
|
|
22
|
+
end.parse!(@argv)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def show_help(output = @stdout)
|
|
26
|
+
output.puts "Usage: raygatherer [global options] log [options]"
|
|
27
|
+
output.puts ""
|
|
28
|
+
output.puts "Options:"
|
|
29
|
+
output.puts " -h, --help Show this help message"
|
|
30
|
+
output.puts ""
|
|
31
|
+
print_global_options(output)
|
|
32
|
+
output.puts ""
|
|
33
|
+
output.puts "Examples:"
|
|
34
|
+
output.puts " raygatherer --host http://192.168.1.100:8080 log"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -7,47 +7,91 @@ module Raygatherer
|
|
|
7
7
|
module Commands
|
|
8
8
|
module Recording
|
|
9
9
|
class Delete < Base
|
|
10
|
+
def initialize(argv, stdout: $stdout, stderr: $stderr, api_client: nil, stdin: $stdin, **_kwargs)
|
|
11
|
+
super(argv, stdout: stdout, stderr: stderr, api_client: api_client)
|
|
12
|
+
@stdin = stdin
|
|
13
|
+
@all = false
|
|
14
|
+
@force = false
|
|
15
|
+
end
|
|
16
|
+
|
|
10
17
|
def run
|
|
11
18
|
with_error_handling do
|
|
12
19
|
parse_options
|
|
13
20
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
next EXIT_CODE_ERROR
|
|
21
|
+
if @all && !@argv.empty?
|
|
22
|
+
@stderr.puts "Error: cannot specify both a recording name and --all"
|
|
23
|
+
return EXIT_CODE_ERROR
|
|
18
24
|
end
|
|
19
25
|
|
|
20
|
-
@
|
|
21
|
-
|
|
22
|
-
|
|
26
|
+
if @all
|
|
27
|
+
delete_all
|
|
28
|
+
else
|
|
29
|
+
delete_named
|
|
30
|
+
end
|
|
23
31
|
end
|
|
24
32
|
end
|
|
25
33
|
|
|
26
34
|
private
|
|
27
35
|
|
|
36
|
+
def delete_all
|
|
37
|
+
unless @force
|
|
38
|
+
@stderr.print "Warning: This will permanently delete ALL recordings!\nAre you sure? [y/N]: "
|
|
39
|
+
response = @stdin.gets&.strip&.downcase || ""
|
|
40
|
+
unless response == "y" || response == "yes"
|
|
41
|
+
@stderr.puts "Aborted."
|
|
42
|
+
return EXIT_CODE_ERROR
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
@api_client.delete_all_recordings
|
|
46
|
+
@stdout.puts "Deleted all recordings."
|
|
47
|
+
EXIT_CODE_SUCCESS
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def delete_named
|
|
51
|
+
name = @argv.shift
|
|
52
|
+
unless name
|
|
53
|
+
@stderr.puts "Error: recording name or --all is required"
|
|
54
|
+
return EXIT_CODE_ERROR
|
|
55
|
+
end
|
|
56
|
+
@api_client.delete_recording(name)
|
|
57
|
+
@stdout.puts "Deleted recording: #{name}"
|
|
58
|
+
EXIT_CODE_SUCCESS
|
|
59
|
+
end
|
|
60
|
+
|
|
28
61
|
def parse_options
|
|
29
62
|
OptionParser.new do |opts|
|
|
30
|
-
opts.banner = "Usage: raygatherer recording delete <name>"
|
|
63
|
+
opts.banner = "Usage: raygatherer recording delete <name> | --all [--force]"
|
|
31
64
|
opts.separator ""
|
|
32
65
|
opts.separator "Options:"
|
|
33
66
|
|
|
34
|
-
opts.on("
|
|
35
|
-
|
|
36
|
-
raise CLI::EarlyExit, EXIT_CODE_SUCCESS
|
|
67
|
+
opts.on("--all", "Delete all recordings (prompts for confirmation)") do
|
|
68
|
+
@all = true
|
|
37
69
|
end
|
|
70
|
+
|
|
71
|
+
opts.on("-f", "--force", "Skip confirmation prompt (use with --all)") do
|
|
72
|
+
@force = true
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
add_help_option(opts)
|
|
38
76
|
end.parse!(@argv)
|
|
39
77
|
end
|
|
40
78
|
|
|
41
79
|
def show_help(output = @stdout)
|
|
42
80
|
output.puts "Usage: raygatherer [global options] recording delete <name>"
|
|
81
|
+
output.puts " raygatherer [global options] recording delete --all [--force]"
|
|
43
82
|
output.puts ""
|
|
44
83
|
output.puts "Options:"
|
|
84
|
+
output.puts " --all Delete all recordings (prompts for confirmation)"
|
|
85
|
+
output.puts " -f, --force Skip confirmation prompt (use with --all)"
|
|
45
86
|
output.puts " -h, --help Show this help message"
|
|
46
87
|
output.puts ""
|
|
47
88
|
print_global_options(output)
|
|
48
89
|
output.puts ""
|
|
49
90
|
output.puts "Examples:"
|
|
50
91
|
output.puts " raygatherer --host http://192.168.1.100:8080 recording delete 1738950000"
|
|
92
|
+
output.puts " raygatherer --host http://192.168.1.100:8080 recording delete --all"
|
|
93
|
+
output.puts " raygatherer --host http://192.168.1.100:8080 recording delete --all --force"
|
|
94
|
+
output.puts " echo y | raygatherer --host http://192.168.1.100:8080 recording delete --all"
|
|
51
95
|
end
|
|
52
96
|
end
|
|
53
97
|
end
|
|
@@ -28,21 +28,21 @@ module Raygatherer
|
|
|
28
28
|
def run
|
|
29
29
|
with_error_handling do
|
|
30
30
|
parse_options
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
return EXIT_CODE_ERROR unless validate_format_flags
|
|
32
|
+
return EXIT_CODE_ERROR unless validate_path_flags
|
|
33
33
|
|
|
34
34
|
name = @argv.shift
|
|
35
35
|
unless name
|
|
36
36
|
@stderr.puts "Error: recording name is required"
|
|
37
|
-
|
|
37
|
+
return EXIT_CODE_ERROR
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
dest_path = resolve_destination(name)
|
|
41
|
-
|
|
41
|
+
return EXIT_CODE_ERROR unless dest_path
|
|
42
42
|
|
|
43
43
|
if File.exist?(dest_path)
|
|
44
44
|
@stderr.puts "Error: file already exists: #{dest_path}"
|
|
45
|
-
|
|
45
|
+
return EXIT_CODE_ERROR
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
spinner = Spinner.new(stderr: @stderr)
|
|
@@ -87,10 +87,7 @@ module Raygatherer
|
|
|
87
87
|
@save_as = path
|
|
88
88
|
end
|
|
89
89
|
|
|
90
|
-
opts
|
|
91
|
-
show_help
|
|
92
|
-
raise CLI::EarlyExit, EXIT_CODE_SUCCESS
|
|
93
|
-
end
|
|
90
|
+
add_help_option(opts)
|
|
94
91
|
end.parse!(@argv)
|
|
95
92
|
end
|
|
96
93
|
|
|
@@ -9,11 +9,6 @@ module Raygatherer
|
|
|
9
9
|
module Commands
|
|
10
10
|
module Recording
|
|
11
11
|
class List < Base
|
|
12
|
-
def initialize(argv, stdout: $stdout, stderr: $stderr, api_client: nil, json: false)
|
|
13
|
-
super(argv, stdout: stdout, stderr: stderr, api_client: api_client)
|
|
14
|
-
@json = json
|
|
15
|
-
end
|
|
16
|
-
|
|
17
12
|
def run
|
|
18
13
|
with_error_handling do
|
|
19
14
|
parse_options
|
|
@@ -35,10 +30,7 @@ module Raygatherer
|
|
|
35
30
|
opts.separator ""
|
|
36
31
|
opts.separator "Options:"
|
|
37
32
|
|
|
38
|
-
opts
|
|
39
|
-
show_help
|
|
40
|
-
raise CLI::EarlyExit, EXIT_CODE_SUCCESS
|
|
41
|
-
end
|
|
33
|
+
add_help_option(opts)
|
|
42
34
|
end.parse!(@argv)
|
|
43
35
|
end
|
|
44
36
|
|
|
@@ -13,7 +13,7 @@ module Raygatherer
|
|
|
13
13
|
|
|
14
14
|
if @argv.any?
|
|
15
15
|
@stderr.puts "Error: recording start does not take a name"
|
|
16
|
-
|
|
16
|
+
return EXIT_CODE_ERROR
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
@api_client.start_recording
|
|
@@ -30,10 +30,7 @@ module Raygatherer
|
|
|
30
30
|
opts.separator ""
|
|
31
31
|
opts.separator "Options:"
|
|
32
32
|
|
|
33
|
-
opts
|
|
34
|
-
show_help
|
|
35
|
-
raise CLI::EarlyExit, EXIT_CODE_SUCCESS
|
|
36
|
-
end
|
|
33
|
+
add_help_option(opts)
|
|
37
34
|
end.parse!(@argv)
|
|
38
35
|
end
|
|
39
36
|
|
|
@@ -13,7 +13,7 @@ module Raygatherer
|
|
|
13
13
|
|
|
14
14
|
if @argv.any?
|
|
15
15
|
@stderr.puts "Error: recording stop does not take a name"
|
|
16
|
-
|
|
16
|
+
return EXIT_CODE_ERROR
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
@api_client.stop_recording
|
|
@@ -30,10 +30,7 @@ module Raygatherer
|
|
|
30
30
|
opts.separator ""
|
|
31
31
|
opts.separator "Options:"
|
|
32
32
|
|
|
33
|
-
opts
|
|
34
|
-
show_help
|
|
35
|
-
raise CLI::EarlyExit, EXIT_CODE_SUCCESS
|
|
36
|
-
end
|
|
33
|
+
add_help_option(opts)
|
|
37
34
|
end.parse!(@argv)
|
|
38
35
|
end
|
|
39
36
|
|
|
@@ -8,17 +8,15 @@ require_relative "../formatters/stats_human"
|
|
|
8
8
|
module Raygatherer
|
|
9
9
|
module Commands
|
|
10
10
|
class Stats < Base
|
|
11
|
-
def initialize(argv, stdout: $stdout, stderr: $stderr, api_client: nil, json: false)
|
|
12
|
-
super(argv, stdout: stdout, stderr: stderr, api_client: api_client)
|
|
13
|
-
@json = json
|
|
14
|
-
end
|
|
15
|
-
|
|
16
11
|
def run
|
|
17
12
|
with_error_handling do
|
|
18
13
|
parse_options
|
|
19
14
|
|
|
20
15
|
stats = @api_client.fetch_system_stats
|
|
21
16
|
|
|
17
|
+
rayhunter_version = stats.dig("runtime_metadata", "rayhunter_version")
|
|
18
|
+
warn_if_rayhunter_outdated(rayhunter_version) if rayhunter_version
|
|
19
|
+
|
|
22
20
|
formatter = @json ? Formatters::StatsJSON.new : Formatters::StatsHuman.new
|
|
23
21
|
@stdout.puts formatter.format(stats)
|
|
24
22
|
|
|
@@ -34,10 +32,7 @@ module Raygatherer
|
|
|
34
32
|
opts.separator ""
|
|
35
33
|
opts.separator "Options:"
|
|
36
34
|
|
|
37
|
-
opts
|
|
38
|
-
show_help
|
|
39
|
-
raise CLI::EarlyExit, EXIT_CODE_SUCCESS
|
|
40
|
-
end
|
|
35
|
+
add_help_option(opts)
|
|
41
36
|
end.parse!(@argv)
|
|
42
37
|
end
|
|
43
38
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "optparse"
|
|
4
|
+
require_relative "../base"
|
|
5
|
+
require_relative "../../formatters/time_json"
|
|
6
|
+
require_relative "../../formatters/time_human"
|
|
7
|
+
|
|
8
|
+
module Raygatherer
|
|
9
|
+
module Commands
|
|
10
|
+
module Time
|
|
11
|
+
class Show < Base
|
|
12
|
+
def run
|
|
13
|
+
with_error_handling do
|
|
14
|
+
parse_options
|
|
15
|
+
|
|
16
|
+
time = @api_client.fetch_time
|
|
17
|
+
|
|
18
|
+
formatter = @json ? Formatters::TimeJSON.new : Formatters::TimeHuman.new
|
|
19
|
+
@stdout.puts formatter.format(time)
|
|
20
|
+
|
|
21
|
+
EXIT_CODE_SUCCESS
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def parse_options
|
|
28
|
+
OptionParser.new do |opts|
|
|
29
|
+
opts.banner = "Usage: raygatherer time show [options]"
|
|
30
|
+
opts.separator ""
|
|
31
|
+
opts.separator "Options:"
|
|
32
|
+
|
|
33
|
+
add_help_option(opts)
|
|
34
|
+
end.parse!(@argv)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def show_help(output = @stdout)
|
|
38
|
+
output.puts "Usage: raygatherer [global options] time show [options]"
|
|
39
|
+
output.puts ""
|
|
40
|
+
output.puts "Options:"
|
|
41
|
+
output.puts " -h, --help Show this help message"
|
|
42
|
+
output.puts ""
|
|
43
|
+
print_global_options(output, json: true)
|
|
44
|
+
output.puts ""
|
|
45
|
+
output.puts "Examples:"
|
|
46
|
+
output.puts " raygatherer --host http://192.168.1.100:8080 time show"
|
|
47
|
+
output.puts " raygatherer --host http://192.168.1.100:8080 --json time show"
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|