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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +71 -18
  3. data/lib/raygatherer/api_client.rb +101 -27
  4. data/lib/raygatherer/cli.rb +39 -17
  5. data/lib/raygatherer/commands/alerts.rb +7 -12
  6. data/lib/raygatherer/commands/analysis/report.rb +77 -0
  7. data/lib/raygatherer/commands/analysis/run.rb +10 -7
  8. data/lib/raygatherer/commands/analysis/status.rb +1 -9
  9. data/lib/raygatherer/commands/base.rb +20 -1
  10. data/lib/raygatherer/commands/config/set.rb +1 -4
  11. data/lib/raygatherer/commands/config/show.rb +1 -9
  12. data/lib/raygatherer/commands/config/test_notification.rb +1 -4
  13. data/lib/raygatherer/commands/debug/display_state.rb +95 -0
  14. data/lib/raygatherer/commands/gps/set.rb +69 -0
  15. data/lib/raygatherer/commands/gps/show.rb +54 -0
  16. data/lib/raygatherer/commands/log.rb +38 -0
  17. data/lib/raygatherer/commands/recording/delete.rb +55 -11
  18. data/lib/raygatherer/commands/recording/download.rb +6 -9
  19. data/lib/raygatherer/commands/recording/list.rb +1 -9
  20. data/lib/raygatherer/commands/recording/start.rb +2 -5
  21. data/lib/raygatherer/commands/recording/stop.rb +2 -5
  22. data/lib/raygatherer/commands/stats.rb +4 -9
  23. data/lib/raygatherer/commands/time/show.rb +52 -0
  24. data/lib/raygatherer/commands/time/sync.rb +53 -0
  25. data/lib/raygatherer/commands/update/status.rb +62 -0
  26. data/lib/raygatherer/commands/wifi/scan.rb +54 -0
  27. data/lib/raygatherer/commands/wifi/show.rb +55 -0
  28. data/lib/raygatherer/formatters/{human.rb → alerts_human.rb} +1 -1
  29. data/lib/raygatherer/formatters/{json.rb → alerts_json.rb} +2 -2
  30. data/lib/raygatherer/formatters/analysis_report_human.rb +88 -0
  31. data/lib/raygatherer/formatters/analysis_report_json.rb +13 -0
  32. data/lib/raygatherer/formatters/config_human.rb +39 -2
  33. data/lib/raygatherer/formatters/gps_human.rb +13 -0
  34. data/lib/raygatherer/formatters/gps_json.rb +13 -0
  35. data/lib/raygatherer/formatters/recording_list_human.rb +6 -1
  36. data/lib/raygatherer/formatters/time_human.rb +15 -0
  37. data/lib/raygatherer/formatters/time_json.rb +13 -0
  38. data/lib/raygatherer/formatters/update_status_human.rb +25 -0
  39. data/lib/raygatherer/formatters/update_status_json.rb +13 -0
  40. data/lib/raygatherer/formatters/wifi_scan_human.rb +17 -0
  41. data/lib/raygatherer/formatters/wifi_scan_json.rb +13 -0
  42. data/lib/raygatherer/formatters/wifi_status_human.rb +19 -0
  43. data/lib/raygatherer/formatters/wifi_status_json.rb +13 -0
  44. data/lib/raygatherer/version.rb +6 -1
  45. data/lib/raygatherer.rb +24 -2
  46. metadata +41 -6
  47. data/CLAUDE.md +0 -102
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "optparse"
4
+ require "time"
5
+ require_relative "../base"
6
+
7
+ module Raygatherer
8
+ module Commands
9
+ module Time
10
+ class Sync < Base
11
+ def run
12
+ with_error_handling do
13
+ parse_options
14
+
15
+ time_data = @api_client.fetch_time
16
+ device_system_time = ::Time.parse(time_data["system_time"])
17
+ offset = (::Time.now - device_system_time).round
18
+ @api_client.set_time_offset(offset)
19
+ @stdout.puts "Clock synced. Offset: #{offset}s"
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 sync"
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 sync"
39
+ output.puts ""
40
+ output.puts "Syncs the device clock to this machine's time."
41
+ output.puts ""
42
+ output.puts "Options:"
43
+ output.puts " -h, --help Show this help message"
44
+ output.puts ""
45
+ print_global_options(output)
46
+ output.puts ""
47
+ output.puts "Examples:"
48
+ output.puts " raygatherer --host http://192.168.1.100:8080 time sync"
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "optparse"
4
+ require_relative "../base"
5
+ require_relative "../../formatters/update_status_json"
6
+ require_relative "../../formatters/update_status_human"
7
+
8
+ module Raygatherer
9
+ module Commands
10
+ module Update
11
+ class Status < Base
12
+ EXIT_CODE_UPDATE_AVAILABLE = 20
13
+
14
+ def run
15
+ with_error_handling do
16
+ parse_options
17
+
18
+ status = @api_client.fetch_update_status
19
+
20
+ warn_if_rayhunter_outdated(status["current_version"]) if status["current_version"]
21
+
22
+ formatter = @json ? Formatters::UpdateStatusJSON.new : Formatters::UpdateStatusHuman.new
23
+ @stdout.puts formatter.format(status)
24
+
25
+ status["update_available"] ? EXIT_CODE_UPDATE_AVAILABLE : EXIT_CODE_SUCCESS
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def parse_options
32
+ OptionParser.new do |opts|
33
+ opts.banner = "Usage: raygatherer update status [options]"
34
+ opts.separator ""
35
+ opts.separator "Options:"
36
+
37
+ add_help_option(opts)
38
+ end.parse!(@argv)
39
+ end
40
+
41
+ def show_help(output = @stdout)
42
+ output.puts "Usage: raygatherer [global options] update status [options]"
43
+ output.puts ""
44
+ output.puts "Options:"
45
+ output.puts " -h, --help Show this help message"
46
+ output.puts ""
47
+ print_global_options(output, json: true)
48
+ output.puts ""
49
+ output.puts "Exit Codes:"
50
+ output.puts " #{EXIT_CODE_SUCCESS} Up to date (or auto_check_updates is disabled on the device)"
51
+ output.puts " #{EXIT_CODE_ERROR} Error (connection, parse, missing --host, etc.)"
52
+ output.puts " #{EXIT_CODE_UPDATE_AVAILABLE} Update available"
53
+ output.puts ""
54
+ output.puts "Examples:"
55
+ output.puts " raygatherer --host http://192.168.1.100:8080 update status"
56
+ output.puts " raygatherer --host http://192.168.1.100:8080 --json update status"
57
+ output.puts " raygatherer --host http://rayhunter update status; [ $? -eq #{EXIT_CODE_UPDATE_AVAILABLE} ] && telegram-send 'Rayhunter update available!'"
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "optparse"
4
+ require_relative "../base"
5
+ require_relative "../../formatters/wifi_scan_json"
6
+ require_relative "../../formatters/wifi_scan_human"
7
+
8
+ module Raygatherer
9
+ module Commands
10
+ module Wifi
11
+ class Scan < Base
12
+ def run
13
+ with_error_handling do
14
+ parse_options
15
+
16
+ networks = @api_client.scan_wifi
17
+
18
+ formatter = @json ? Formatters::WifiScanJSON.new : Formatters::WifiScanHuman.new
19
+ @stdout.puts formatter.format(networks)
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 wifi scan [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] wifi scan [options]"
39
+ output.puts ""
40
+ output.puts "Scan for nearby wifi networks the device could connect to as a client."
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 wifi scan"
49
+ output.puts " raygatherer --host http://192.168.1.100:8080 --json wifi scan"
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "optparse"
4
+ require_relative "../base"
5
+ require_relative "../../formatters/wifi_status_json"
6
+ require_relative "../../formatters/wifi_status_human"
7
+
8
+ module Raygatherer
9
+ module Commands
10
+ module Wifi
11
+ class Show < Base
12
+ def run
13
+ with_error_handling do
14
+ parse_options
15
+
16
+ status = @api_client.fetch_wifi_status
17
+
18
+ formatter = @json ? Formatters::WifiStatusJSON.new : Formatters::WifiStatusHuman.new
19
+ @stdout.puts formatter.format(status)
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 wifi 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] wifi show [options]"
39
+ output.puts ""
40
+ output.puts "Show the device's wifi client connection status (the daemon's own outbound"
41
+ output.puts "connection to an upstream network, separate from the AP it hosts)."
42
+ output.puts ""
43
+ output.puts "Options:"
44
+ output.puts " -h, --help Show this help message"
45
+ output.puts ""
46
+ print_global_options(output, json: true)
47
+ output.puts ""
48
+ output.puts "Examples:"
49
+ output.puts " raygatherer --host http://192.168.1.100:8080 wifi show"
50
+ output.puts " raygatherer --host http://192.168.1.100:8080 --json wifi show"
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Raygatherer
4
4
  module Formatters
5
- class Human
5
+ class AlertsHuman
6
6
  def format(alerts)
7
7
  if alerts.empty?
8
8
  colorize("✓ No alerts detected", :green)
@@ -4,7 +4,7 @@ require "json"
4
4
 
5
5
  module Raygatherer
6
6
  module Formatters
7
- class JSON
7
+ class AlertsJSON
8
8
  def format(alerts)
9
9
  output = alerts.map do |alert|
10
10
  {
@@ -15,7 +15,7 @@ module Raygatherer
15
15
  }
16
16
  end
17
17
 
18
- ::JSON.generate(output)
18
+ JSON.generate(output)
19
19
  end
20
20
  end
21
21
  end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "time"
4
+
5
+ module Raygatherer
6
+ module Formatters
7
+ class AnalysisReportHuman
8
+ def format(data)
9
+ metadata = data[:metadata] || {}
10
+ rows = data[:rows] || []
11
+
12
+ lines = []
13
+ lines << format_header(metadata)
14
+ lines << format_analyzers(metadata)
15
+ lines << ""
16
+
17
+ rows.each do |row|
18
+ lines.concat(format_row(row, metadata))
19
+ end
20
+
21
+ lines.join("\n")
22
+ end
23
+
24
+ private
25
+
26
+ def format_header(metadata)
27
+ rayhunter = metadata["rayhunter"] || {}
28
+ version = rayhunter["rayhunter_version"]
29
+ os = rayhunter["system_os"]
30
+ arch = rayhunter["arch"]
31
+ report_version = metadata["report_version"]
32
+
33
+ parts = []
34
+ parts << "Rayhunter v#{version}" if version
35
+ os_arch = [os, arch].compact.join(" ")
36
+ parts << os_arch unless os_arch.empty?
37
+ parts << "Report version #{report_version}" if report_version
38
+
39
+ parts.join(" | ")
40
+ end
41
+
42
+ def format_analyzers(metadata)
43
+ analyzers = metadata["analyzers"] || []
44
+ return "Analyzers: (none)" if analyzers.empty?
45
+
46
+ names = analyzers.filter_map do |a|
47
+ next unless a
48
+ v = a["version"] ? " (v#{a["version"]})" : ""
49
+ "#{a["name"]}#{v}"
50
+ end
51
+
52
+ "Analyzers: #{names.join(", ")}"
53
+ end
54
+
55
+ def format_row(row, metadata)
56
+ analyzers = metadata["analyzers"] || []
57
+ timestamp = format_timestamp(row["packet_timestamp"])
58
+
59
+ if (reason = row["skipped_message_reason"])
60
+ return ["#{timestamp} Skipped: #{reason}"]
61
+ end
62
+
63
+ events = row["events"] || []
64
+ present_events = events.each_with_index.reject { |e, _| e.nil? }
65
+
66
+ if present_events.empty?
67
+ return ["#{timestamp} No events"]
68
+ end
69
+
70
+ present_events.map do |event, index|
71
+ event_type = event["event_type"] || "Unknown"
72
+ message = event["message"]
73
+ analyzer = analyzers.dig(index, "name")
74
+ analyzer_part = analyzer ? "(#{analyzer}) " : ""
75
+ "#{timestamp} #{event_type.ljust(13)} #{analyzer_part}#{message}"
76
+ end
77
+ end
78
+
79
+ def format_timestamp(ts)
80
+ return "[no timestamp]" unless ts
81
+ time = Time.parse(ts).utc
82
+ "[#{time.strftime("%Y-%m-%d %H:%M:%S UTC")}]"
83
+ rescue ArgumentError
84
+ "[#{ts}]"
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ module Raygatherer
6
+ module Formatters
7
+ class AnalysisReportJSON
8
+ def format(data)
9
+ ::JSON.generate({"metadata" => data[:metadata], "rows" => data[:rows]})
10
+ end
11
+ end
12
+ end
13
+ end
@@ -7,12 +7,49 @@ module Raygatherer
7
7
  lines = []
8
8
 
9
9
  lines << "Port: #{config["port"]}"
10
- lines << "Readonly port: #{config["readonly_port"]}"
11
10
  lines << "QMDL store path: #{config["qmdl_store_path"]}"
11
+ lines << "Device: #{config["device"]}" if config.key?("device")
12
+ lines << "Debug mode: #{config["debug_mode"]}" if config.key?("debug_mode")
13
+ lines << "UI level: #{config["ui_level"]}" if config.key?("ui_level")
14
+ lines << "Colorblind mode: #{config["colorblind_mode"]}" if config.key?("colorblind_mode")
15
+ lines << "Key input mode: #{config["key_input_mode"]}" if config.key?("key_input_mode")
12
16
 
13
- notification_url = config["notification_url"]
17
+ notification_url = config["ntfy_url"] || config["notification_url"]
14
18
  lines << "Notification URL: #{notification_url || "(not set)"}"
15
19
 
20
+ if config.key?("enabled_notifications")
21
+ lines << "Notifications enabled: #{config["enabled_notifications"].join(", ")}"
22
+ end
23
+
24
+ if config.key?("min_space_to_start_recording_mb")
25
+ lines << "Min space to start recording: #{config["min_space_to_start_recording_mb"]} MB"
26
+ end
27
+ if config.key?("min_space_to_continue_recording_mb")
28
+ lines << "Min space to continue recording: #{config["min_space_to_continue_recording_mb"]} MB"
29
+ end
30
+
31
+ lines << "Auto check updates: #{config["auto_check_updates"]}" if config.key?("auto_check_updates")
32
+ lines << "Clock sync mode: #{config["clock_sync_mode"]}" if config.key?("clock_sync_mode")
33
+ lines << "GPS mode: #{config["gps_mode"]}" if config.key?("gps_mode")
34
+ lines << "GPS fixed latitude: #{config["gps_fixed_latitude"]}" if config["gps_fixed_latitude"]
35
+ lines << "GPS fixed longitude: #{config["gps_fixed_longitude"]}" if config["gps_fixed_longitude"]
36
+ lines << "WiFi enabled: #{config["wifi_enabled"]}" if config.key?("wifi_enabled")
37
+ lines << "WiFi SSID: #{config["wifi_ssid"]}" if config["wifi_ssid"]
38
+ lines << "WiFi security: #{config["wifi_security"]}" if config["wifi_security"]
39
+ lines << "DNS servers: #{config["dns_servers"].join(", ")}" if config["dns_servers"]&.any?
40
+
41
+ webdav = config["webdav"]
42
+ if webdav && !webdav["url"].to_s.empty?
43
+ lines << ""
44
+ lines << "WebDAV:"
45
+ lines << " URL: #{webdav["url"]}"
46
+ lines << " Username: #{webdav["username"]}" if webdav["username"]
47
+ lines << " Upload timeout: #{webdav["upload_timeout_secs"]}s" if webdav.key?("upload_timeout_secs")
48
+ lines << " Poll interval: #{webdav["poll_interval_secs"]}s" if webdav.key?("poll_interval_secs")
49
+ lines << " Min age: #{webdav["min_age_secs"]}s" if webdav.key?("min_age_secs")
50
+ lines << " Delete on upload: #{webdav["delete_on_upload"]}" if webdav.key?("delete_on_upload")
51
+ end
52
+
16
53
  analyzers = config["analyzers"]
17
54
  if analyzers
18
55
  lines << ""
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Raygatherer
4
+ module Formatters
5
+ class GpsHuman
6
+ def format(gps)
7
+ return "No GPS position recorded yet (nothing has been submitted to /api/gps this session)." if gps.nil?
8
+
9
+ "Latitude: #{gps["latitude"]}\nLongitude: #{gps["longitude"]}"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ module Raygatherer
6
+ module Formatters
7
+ class GpsJSON
8
+ def format(gps)
9
+ ::JSON.generate(gps)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -59,13 +59,18 @@ module Raygatherer
59
59
 
60
60
  lines << " Size: #{format_size(entry["qmdl_size_bytes"])}"
61
61
 
62
+ if !active && entry["stop_reason"]
63
+ lines << " Stop reason: #{entry["stop_reason"]}"
64
+ end
65
+
62
66
  lines.join("\n")
63
67
  end
64
68
 
65
69
  def format_time(time_string)
66
70
  return "" unless time_string
67
-
68
71
  Time.parse(time_string).strftime("%Y-%m-%d %H:%M:%S")
72
+ rescue ArgumentError
73
+ time_string
69
74
  end
70
75
  end
71
76
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Raygatherer
4
+ module Formatters
5
+ class TimeHuman
6
+ def format(time)
7
+ lines = []
8
+ lines << "System time: #{time["system_time"]}"
9
+ lines << "Adjusted time: #{time["adjusted_time"]}"
10
+ lines << "Offset: #{time["offset_seconds"]}s"
11
+ lines.join("\n")
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ module Raygatherer
6
+ module Formatters
7
+ class TimeJSON
8
+ def format(time)
9
+ ::JSON.generate(time)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Raygatherer
4
+ module Formatters
5
+ class UpdateStatusHuman
6
+ def format(status)
7
+ lines = []
8
+
9
+ lines << "Current version: #{status["current_version"]}"
10
+ lines << "Update available: #{status["update_available"] ? "yes" : "no"}"
11
+ lines << "Latest version: #{status["latest_version"]}" if status["latest_version"]
12
+ lines << "Release notes: #{status["latest_release_url"]}" if status["latest_release_url"]
13
+ lines << "Last checked: #{status["last_checked"]}" if status["last_checked"]
14
+ lines << "Last error: #{status["last_error"]}" if status["last_error"]
15
+
16
+ if status["latest_version"].nil? && status["last_checked"].nil?
17
+ lines << ""
18
+ lines << "No update check has run yet — check that auto_check_updates is enabled in rayhunter's config."
19
+ end
20
+
21
+ lines.join("\n")
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ module Raygatherer
6
+ module Formatters
7
+ class UpdateStatusJSON
8
+ def format(status)
9
+ ::JSON.generate(status)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Raygatherer
4
+ module Formatters
5
+ class WifiScanHuman
6
+ def format(networks)
7
+ return "No networks found" if networks.empty?
8
+
9
+ lines = ["Networks: #{networks.length}", ""]
10
+ networks.each do |network|
11
+ lines << "#{network["ssid"]} (#{network["signal_dbm"]} dBm, #{network["security"]})"
12
+ end
13
+ lines.join("\n")
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ module Raygatherer
6
+ module Formatters
7
+ class WifiScanJSON
8
+ def format(networks)
9
+ ::JSON.generate(networks)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Raygatherer
4
+ module Formatters
5
+ class WifiStatusHuman
6
+ def format(status)
7
+ lines = []
8
+
9
+ lines << "State: #{status["state"]}"
10
+ lines << "SSID: #{status["ssid"]}" if status["ssid"]
11
+ lines << "IP: #{status["ip"]}" if status["ip"]
12
+ lines << "TX packets: #{status["txPackets"]}" if status["txPackets"]
13
+ lines << "Error: #{status["error"]}" if status["error"]
14
+
15
+ lines.join("\n")
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "json"
4
+
5
+ module Raygatherer
6
+ module Formatters
7
+ class WifiStatusJSON
8
+ def format(status)
9
+ ::JSON.generate(status)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -1,5 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Raygatherer
4
- VERSION = "0.1.0"
4
+ VERSION = "0.3.0"
5
+
6
+ # The rayhunter daemon version this release was last verified against. Used only to warn
7
+ # when talking to an older daemon that may lack fields/endpoints raygatherer expects;
8
+ # never enforced.
9
+ TESTED_RAYHUNTER_VERSION = "0.12.0"
5
10
  end
data/lib/raygatherer.rb CHANGED
@@ -4,16 +4,28 @@ require_relative "raygatherer/version"
4
4
  require_relative "raygatherer/config"
5
5
  require_relative "raygatherer/cli"
6
6
  require_relative "raygatherer/api_client"
7
- require_relative "raygatherer/formatters/human"
8
- require_relative "raygatherer/formatters/json"
7
+ require_relative "raygatherer/formatters/alerts_human"
8
+ require_relative "raygatherer/formatters/alerts_json"
9
9
  require_relative "raygatherer/formatters/recording_list_json"
10
10
  require_relative "raygatherer/formatters/recording_list_human"
11
11
  require_relative "raygatherer/formatters/stats_json"
12
12
  require_relative "raygatherer/formatters/stats_human"
13
13
  require_relative "raygatherer/formatters/analysis_status_json"
14
14
  require_relative "raygatherer/formatters/analysis_status_human"
15
+ require_relative "raygatherer/formatters/analysis_report_json"
16
+ require_relative "raygatherer/formatters/analysis_report_human"
15
17
  require_relative "raygatherer/formatters/config_json"
16
18
  require_relative "raygatherer/formatters/config_human"
19
+ require_relative "raygatherer/formatters/time_json"
20
+ require_relative "raygatherer/formatters/time_human"
21
+ require_relative "raygatherer/formatters/update_status_json"
22
+ require_relative "raygatherer/formatters/update_status_human"
23
+ require_relative "raygatherer/formatters/gps_json"
24
+ require_relative "raygatherer/formatters/gps_human"
25
+ require_relative "raygatherer/formatters/wifi_status_json"
26
+ require_relative "raygatherer/formatters/wifi_status_human"
27
+ require_relative "raygatherer/formatters/wifi_scan_json"
28
+ require_relative "raygatherer/formatters/wifi_scan_human"
17
29
  require_relative "raygatherer/spinner"
18
30
  require_relative "raygatherer/commands/base"
19
31
  require_relative "raygatherer/commands/alerts"
@@ -22,12 +34,22 @@ require_relative "raygatherer/commands/recording/download"
22
34
  require_relative "raygatherer/commands/recording/delete"
23
35
  require_relative "raygatherer/commands/recording/stop"
24
36
  require_relative "raygatherer/commands/recording/start"
37
+ require_relative "raygatherer/commands/log"
25
38
  require_relative "raygatherer/commands/stats"
26
39
  require_relative "raygatherer/commands/analysis/status"
27
40
  require_relative "raygatherer/commands/analysis/run"
41
+ require_relative "raygatherer/commands/analysis/report"
28
42
  require_relative "raygatherer/commands/config/show"
29
43
  require_relative "raygatherer/commands/config/set"
30
44
  require_relative "raygatherer/commands/config/test_notification"
45
+ require_relative "raygatherer/commands/debug/display_state"
46
+ require_relative "raygatherer/commands/time/show"
47
+ require_relative "raygatherer/commands/time/sync"
48
+ require_relative "raygatherer/commands/update/status"
49
+ require_relative "raygatherer/commands/gps/show"
50
+ require_relative "raygatherer/commands/gps/set"
51
+ require_relative "raygatherer/commands/wifi/show"
52
+ require_relative "raygatherer/commands/wifi/scan"
31
53
 
32
54
  module Raygatherer
33
55
  class Error < StandardError; end