meshchat 0.8.0 → 0.10.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 +39 -11
- data/lib/meshchat.rb +48 -42
- data/lib/meshchat/configuration.rb +14 -0
- data/lib/meshchat/configuration/app_config.rb +63 -0
- data/lib/meshchat/configuration/database.rb +41 -0
- data/lib/meshchat/{config → configuration}/hash_file.rb +7 -6
- data/lib/meshchat/configuration/identity.rb +79 -0
- data/lib/meshchat/{config → configuration}/settings.rb +22 -26
- data/lib/meshchat/debug.rb +69 -0
- data/lib/meshchat/encryption.rb +7 -2
- data/lib/meshchat/encryption/aes_rsa.rb +2 -1
- data/lib/meshchat/encryption/passthrough.rb +5 -3
- data/lib/meshchat/locale/en.yml +14 -0
- data/lib/meshchat/models/node.rb +140 -0
- data/lib/meshchat/network.rb +19 -0
- data/lib/meshchat/network/dispatcher.rb +83 -0
- data/lib/meshchat/network/errors.rb +11 -0
- data/lib/meshchat/network/incoming.rb +13 -0
- data/lib/meshchat/network/incoming/message_decryptor.rb +51 -0
- data/lib/meshchat/network/incoming/message_processor.rb +75 -0
- data/lib/meshchat/network/incoming/request_processor.rb +30 -0
- data/lib/meshchat/network/local.rb +12 -0
- data/lib/meshchat/network/local/connection.rb +58 -0
- data/lib/meshchat/network/local/server.rb +69 -0
- data/lib/meshchat/network/message.rb +34 -0
- data/lib/meshchat/network/message/base.rb +139 -0
- data/lib/meshchat/network/message/chat.rb +9 -0
- data/lib/meshchat/network/message/disconnect.rb +21 -0
- data/lib/meshchat/network/message/emote.rb +9 -0
- data/lib/meshchat/network/message/factory.rb +80 -0
- data/lib/meshchat/network/message/node_list.rb +75 -0
- data/lib/meshchat/network/message/node_list_diff.rb +18 -0
- data/lib/meshchat/network/message/node_list_hash.rb +32 -0
- data/lib/meshchat/network/message/ping.rb +31 -0
- data/lib/meshchat/network/message/ping_reply.rb +12 -0
- data/lib/meshchat/network/message/whisper.rb +28 -0
- data/lib/meshchat/network/remote.rb +13 -0
- data/lib/meshchat/network/remote/connection.rb +28 -0
- data/lib/meshchat/network/remote/relay.rb +109 -0
- data/lib/meshchat/network/remote/relay_pool.rb +52 -0
- data/lib/meshchat/ui.rb +13 -0
- data/lib/meshchat/ui/cli.rb +48 -0
- data/lib/meshchat/ui/cli/base.rb +39 -0
- data/lib/meshchat/ui/cli/input_factory.rb +50 -0
- data/lib/meshchat/ui/cli/keyboard_line_input.rb +14 -0
- data/lib/meshchat/ui/command.rb +51 -0
- data/lib/meshchat/ui/command/base.rb +77 -0
- data/lib/meshchat/ui/command/bind.rb +47 -0
- data/lib/meshchat/ui/command/chat.rb +31 -0
- data/lib/meshchat/ui/command/config.rb +37 -0
- data/lib/meshchat/ui/command/emote.rb +23 -0
- data/lib/meshchat/ui/command/exit.rb +16 -0
- data/lib/meshchat/ui/command/help.rb +20 -0
- data/lib/meshchat/ui/command/identity.rb +16 -0
- data/lib/meshchat/ui/command/import.rb +42 -0
- data/lib/meshchat/ui/command/irb.rb +22 -0
- data/lib/meshchat/ui/command/offline.rb +23 -0
- data/lib/meshchat/ui/command/online.rb +18 -0
- data/lib/meshchat/ui/command/ping.rb +65 -0
- data/lib/meshchat/ui/command/ping_all.rb +19 -0
- data/lib/meshchat/ui/command/send_disconnect.rb +20 -0
- data/lib/meshchat/ui/command/server.rb +22 -0
- data/lib/meshchat/ui/command/share.rb +16 -0
- data/lib/meshchat/ui/command/whisper.rb +40 -0
- data/lib/meshchat/ui/display.rb +78 -0
- data/lib/meshchat/ui/display/base.rb +58 -0
- data/lib/meshchat/ui/display/manager.rb +59 -0
- data/lib/meshchat/ui/notifier.rb +9 -0
- data/lib/meshchat/ui/notifier/base.rb +33 -0
- data/lib/meshchat/version.rb +3 -2
- metadata +150 -80
- data/lib/meshchat/cli.rb +0 -188
- data/lib/meshchat/cli/base.rb +0 -13
- data/lib/meshchat/cli/input.rb +0 -37
- data/lib/meshchat/command/base.rb +0 -80
- data/lib/meshchat/command/bind.rb +0 -44
- data/lib/meshchat/command/chat.rb +0 -30
- data/lib/meshchat/command/config.rb +0 -34
- data/lib/meshchat/command/emote.rb +0 -20
- data/lib/meshchat/command/exit.rb +0 -13
- data/lib/meshchat/command/help.rb +0 -17
- data/lib/meshchat/command/identity.rb +0 -13
- data/lib/meshchat/command/import.rb +0 -41
- data/lib/meshchat/command/init.rb +0 -34
- data/lib/meshchat/command/irb.rb +0 -23
- data/lib/meshchat/command/listen.rb +0 -13
- data/lib/meshchat/command/offline.rb +0 -20
- data/lib/meshchat/command/online.rb +0 -15
- data/lib/meshchat/command/ping.rb +0 -65
- data/lib/meshchat/command/ping_all.rb +0 -15
- data/lib/meshchat/command/send_disconnect.rb +0 -15
- data/lib/meshchat/command/server.rb +0 -20
- data/lib/meshchat/command/share.rb +0 -13
- data/lib/meshchat/command/stop_listening.rb +0 -13
- data/lib/meshchat/command/whisper.rb +0 -38
- data/lib/meshchat/database.rb +0 -30
- data/lib/meshchat/display.rb +0 -33
- data/lib/meshchat/display/base.rb +0 -60
- data/lib/meshchat/display/manager.rb +0 -55
- data/lib/meshchat/instance.rb +0 -40
- data/lib/meshchat/message.rb +0 -41
- data/lib/meshchat/message/base.rb +0 -97
- data/lib/meshchat/message/chat.rb +0 -19
- data/lib/meshchat/message/disconnect.rb +0 -13
- data/lib/meshchat/message/emote.rb +0 -9
- data/lib/meshchat/message/node_list.rb +0 -63
- data/lib/meshchat/message/node_list_diff.rb +0 -15
- data/lib/meshchat/message/node_list_hash.rb +0 -33
- data/lib/meshchat/message/ping.rb +0 -32
- data/lib/meshchat/message/ping_reply.rb +0 -9
- data/lib/meshchat/message/relay.rb +0 -43
- data/lib/meshchat/message/whisper.rb +0 -36
- data/lib/meshchat/models/entry.rb +0 -104
- data/lib/meshchat/net/client.rb +0 -83
- data/lib/meshchat/net/listener/errors.rb +0 -11
- data/lib/meshchat/net/listener/request.rb +0 -48
- data/lib/meshchat/net/listener/request_processor.rb +0 -50
- data/lib/meshchat/net/listener/server.rb +0 -114
- data/lib/meshchat/net/request.rb +0 -29
- data/lib/meshchat/notifier/base.rb +0 -31
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Meshchat
|
3
|
+
module Network
|
4
|
+
module Remote
|
5
|
+
class RelayPool
|
6
|
+
# This channel is determine by the server, see
|
7
|
+
# https://github.com/NullVoxPopuli/mesh-relay/blob/master/app/channels/mesh_relay_channel.rb
|
8
|
+
CHANNEL = 'MeshRelayChannel'
|
9
|
+
|
10
|
+
attr_accessor :_message_dispatcher
|
11
|
+
attr_accessor :_active_relay
|
12
|
+
attr_accessor :_known_relays, :_available_relays
|
13
|
+
|
14
|
+
def initialize(message_dispatcher)
|
15
|
+
@_message_dispatcher = message_dispatcher
|
16
|
+
@_known_relays = APP_CONFIG.user['relays'] || []
|
17
|
+
@_available_relays = APP_CONFIG.user['relays'] || []
|
18
|
+
|
19
|
+
find_initial_relay if @_known_relays.present?
|
20
|
+
end
|
21
|
+
|
22
|
+
# TODO: add logic for just selecting the first available relay.
|
23
|
+
# we only need one connection.
|
24
|
+
# @return [Array] an array of action cable clients
|
25
|
+
def find_initial_relay(connected: nil)
|
26
|
+
url = _known_relays.first
|
27
|
+
@_active_relay = Relay.new(
|
28
|
+
url, _message_dispatcher,
|
29
|
+
connected: connected)
|
30
|
+
end
|
31
|
+
|
32
|
+
# @param [Hash] payload - the message payload
|
33
|
+
def send_payload(payload)
|
34
|
+
return if _active_relay.blank?
|
35
|
+
|
36
|
+
ensure_active_connection! do
|
37
|
+
_active_relay.perform('chat', payload)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def ensure_active_connection!(&block)
|
42
|
+
# TODO: make action_cable_client return a boolean
|
43
|
+
if !_active_relay.connected?
|
44
|
+
find_initial_relay(connected: block)
|
45
|
+
else
|
46
|
+
yield
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/lib/meshchat/ui.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Meshchat
|
3
|
+
module Ui
|
4
|
+
# A user interface is responsible for for creating a client
|
5
|
+
# and sending messages to that client
|
6
|
+
class CLI
|
7
|
+
extend ActiveSupport::Autoload
|
8
|
+
|
9
|
+
eager_autoload do
|
10
|
+
autoload :InputFactory
|
11
|
+
autoload :Base
|
12
|
+
autoload :KeyboardLineInput
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :_message_dispatcher, :_message_factory, :_command_factory
|
16
|
+
|
17
|
+
def initialize(dispatcher, message_factory, _display)
|
18
|
+
@_message_dispatcher = dispatcher
|
19
|
+
@_message_factory = message_factory
|
20
|
+
@_command_factory = InputFactory.new(dispatcher, message_factory, self)
|
21
|
+
end
|
22
|
+
|
23
|
+
def create_input(msg)
|
24
|
+
handler = _command_factory.create(for_input: msg)
|
25
|
+
handler.handle
|
26
|
+
rescue => e
|
27
|
+
Debug.creating_input_failed(e)
|
28
|
+
end
|
29
|
+
|
30
|
+
# save config and exit
|
31
|
+
def shutdown
|
32
|
+
# close_server
|
33
|
+
Display.info 'saving config...'
|
34
|
+
APP_CONFIG.user.save
|
35
|
+
Display.info 'notifying of disconnection...'
|
36
|
+
send_disconnect
|
37
|
+
Display.alert "\n\nGoodbye. \n\nThank you for using #{Meshchat.name}"
|
38
|
+
exit
|
39
|
+
end
|
40
|
+
|
41
|
+
def send_disconnect
|
42
|
+
klass = Command::SendDisconnect
|
43
|
+
command = _command_factory.create(with_class: klass)
|
44
|
+
command.handle
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Meshchat
|
3
|
+
module Ui
|
4
|
+
class CLI
|
5
|
+
# this class, and all subclasses are Keyboard Handlers
|
6
|
+
# that are used for EventMachine's open_keyboard
|
7
|
+
# @see https://github.com/eventmachine/eventmachine/wiki/Code-Snippets#keyboard-input-example
|
8
|
+
class Base < EventMachine::Connection
|
9
|
+
# The class used for interpeting the line input
|
10
|
+
attr_reader :_input_receiver
|
11
|
+
# An array of typed keystrokes
|
12
|
+
attr_reader :_input_buffer
|
13
|
+
|
14
|
+
def initialize(input_receiver)
|
15
|
+
@_input_receiver = input_receiver
|
16
|
+
@_input_buffer = []
|
17
|
+
end
|
18
|
+
|
19
|
+
# override this method to alter how input is
|
20
|
+
# interpreted by the receiver.
|
21
|
+
#
|
22
|
+
# hopefully, just by calling a different method
|
23
|
+
# on the receiver, as input processing shouldn't
|
24
|
+
# occurr in this class or any subclass unless it is
|
25
|
+
# raw keystroke input
|
26
|
+
#
|
27
|
+
# @note that this method receives raw keystrokes by default
|
28
|
+
# and does not send data to the input receiver
|
29
|
+
def receive_data(data)
|
30
|
+
_input_buffer.push(data)
|
31
|
+
end
|
32
|
+
|
33
|
+
def receive_line(line)
|
34
|
+
# only used when including EM::Protocols::LineText2
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Meshchat
|
3
|
+
module Ui
|
4
|
+
class CLI
|
5
|
+
class InputFactory
|
6
|
+
WHISPER = '@'
|
7
|
+
COMMAND = '/'
|
8
|
+
|
9
|
+
attr_accessor :_message_dispatcher, :_message_factory, :_cli
|
10
|
+
|
11
|
+
def initialize(message_dispatcher, message_factory, cli)
|
12
|
+
self._message_dispatcher = message_dispatcher
|
13
|
+
self._message_factory = message_factory
|
14
|
+
self._cli = cli
|
15
|
+
end
|
16
|
+
|
17
|
+
def is_command?(input)
|
18
|
+
input[0, 1] == COMMAND
|
19
|
+
end
|
20
|
+
|
21
|
+
def is_whisper?(input)
|
22
|
+
input[0, 1] == WHISPER
|
23
|
+
end
|
24
|
+
|
25
|
+
def create(for_input: nil, with_class: nil)
|
26
|
+
return create_with_class(for_input, with_class) if with_class
|
27
|
+
|
28
|
+
create_for_input(for_input)
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_with_class(input, klass)
|
32
|
+
klass.new(input, _message_dispatcher, _message_factory, self)
|
33
|
+
end
|
34
|
+
|
35
|
+
def create_for_input(input)
|
36
|
+
klass =
|
37
|
+
if is_command?(input)
|
38
|
+
Command::Base
|
39
|
+
elsif is_whisper?(input)
|
40
|
+
Command::Whisper
|
41
|
+
else
|
42
|
+
Command::Chat
|
43
|
+
end
|
44
|
+
|
45
|
+
create_with_class(input, klass)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Meshchat
|
3
|
+
module Ui
|
4
|
+
module Command
|
5
|
+
extend ActiveSupport::Autoload
|
6
|
+
|
7
|
+
eager_autoload do
|
8
|
+
autoload :Base
|
9
|
+
autoload :Chat
|
10
|
+
autoload :Identity
|
11
|
+
autoload :Irb
|
12
|
+
autoload :Config
|
13
|
+
autoload :Ping
|
14
|
+
autoload :PingAll
|
15
|
+
autoload :Server
|
16
|
+
autoload :Whisper
|
17
|
+
autoload :Exit
|
18
|
+
autoload :SendDisconnect
|
19
|
+
autoload :Help
|
20
|
+
autoload :Bind
|
21
|
+
autoload :Online
|
22
|
+
autoload :Offline
|
23
|
+
autoload :Share
|
24
|
+
autoload :Import
|
25
|
+
autoload :Emote
|
26
|
+
end
|
27
|
+
|
28
|
+
COMMAND_MAP = {
|
29
|
+
Base::CONFIG => Config,
|
30
|
+
Base::PING => Ping,
|
31
|
+
Base::PING_ALL => PingAll,
|
32
|
+
Base::SERVERS => Server,
|
33
|
+
Base::SERVER => Server,
|
34
|
+
Base::EXIT => Exit,
|
35
|
+
Base::QUIT => Exit,
|
36
|
+
Base::IDENTITY => Identity,
|
37
|
+
Base::IRB => Irb,
|
38
|
+
Base::SHARE => Share,
|
39
|
+
Base::IMPORT => Import,
|
40
|
+
Base::EXPORT => Share,
|
41
|
+
Base::ONLINE => Online,
|
42
|
+
Base::OFFLINE => Offline,
|
43
|
+
Base::HELP => Help,
|
44
|
+
Base::BIND => Bind,
|
45
|
+
Base::SEND_DISCONNECT => SendDisconnect,
|
46
|
+
Base::EMOTE => Emote,
|
47
|
+
Base::CHAT => Chat
|
48
|
+
}.freeze
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Meshchat
|
3
|
+
module Ui
|
4
|
+
module Command
|
5
|
+
class Base
|
6
|
+
# Commands
|
7
|
+
SET = 'set'
|
8
|
+
CONFIG = 'config'
|
9
|
+
DISPLAY = 'display'
|
10
|
+
EXIT = 'exit'
|
11
|
+
QUIT = 'quit'
|
12
|
+
CHAT = 'chat'
|
13
|
+
ADD = 'add'
|
14
|
+
REMOVE = 'remove'
|
15
|
+
RM = 'rm'
|
16
|
+
SERVERS = 'servers'
|
17
|
+
SERVER = 'server'
|
18
|
+
WHO = 'who'
|
19
|
+
PING = 'ping'
|
20
|
+
PING_ALL = 'pingall'
|
21
|
+
IDENTITY = 'identity'
|
22
|
+
IRB = 'c'
|
23
|
+
SHARE = 'share'
|
24
|
+
IMPORT = 'import'
|
25
|
+
EXPORT = 'export'
|
26
|
+
ONLINE = 'online'
|
27
|
+
OFFLINE = 'offline'
|
28
|
+
HELP = 'help'
|
29
|
+
BIND = 'bind'
|
30
|
+
SEND_DISCONNECT = 'senddisconnect'
|
31
|
+
EMOTE = 'me'
|
32
|
+
|
33
|
+
attr_reader :_input, :_message_dispatcher
|
34
|
+
attr_reader :_message_factory, :_input_factory
|
35
|
+
|
36
|
+
def initialize(input, message_dispatcher, message_factory, input_factory)
|
37
|
+
@_input = input&.chomp
|
38
|
+
@_message_dispatcher = message_dispatcher
|
39
|
+
@_message_factory = message_factory
|
40
|
+
@_input_factory = input_factory
|
41
|
+
end
|
42
|
+
|
43
|
+
def handle
|
44
|
+
klass = COMMAND_MAP[command]
|
45
|
+
Display.debug("INPUT: #{klass&.name} from #{command} derived from #{_input}")
|
46
|
+
if klass
|
47
|
+
_input_factory.create(for_input: _input, with_class: klass).handle
|
48
|
+
else
|
49
|
+
Display.alert 'not implemented...'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
protected
|
54
|
+
|
55
|
+
def command_string
|
56
|
+
@command_string ||= _input[1, _input.length]
|
57
|
+
end
|
58
|
+
|
59
|
+
def command_args
|
60
|
+
@command_args ||= command_string.split(' ')
|
61
|
+
end
|
62
|
+
|
63
|
+
def command
|
64
|
+
@command ||= command_args.first
|
65
|
+
end
|
66
|
+
|
67
|
+
def sub_command_args
|
68
|
+
@sub_command_args ||= command_args[2..3]
|
69
|
+
end
|
70
|
+
|
71
|
+
def sub_command
|
72
|
+
@sub_command ||= command_args[1]
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'socket'
|
3
|
+
require 'open-uri'
|
4
|
+
|
5
|
+
module Meshchat
|
6
|
+
module Ui
|
7
|
+
module Command
|
8
|
+
class Bind < Command::Base
|
9
|
+
def self.description
|
10
|
+
'helper for choosing what ip address to use for yourself'
|
11
|
+
end
|
12
|
+
|
13
|
+
def handle
|
14
|
+
options = ip_addresses
|
15
|
+
option_numbers = []
|
16
|
+
Display.success 'Choose an ip:'
|
17
|
+
options.each_with_index do |ip, index|
|
18
|
+
Display.info "#{index}: #{ip}"
|
19
|
+
option_numbers << index
|
20
|
+
end
|
21
|
+
|
22
|
+
selected = gets
|
23
|
+
|
24
|
+
if option_numbers.include?(selected.to_i)
|
25
|
+
Display.success Settings.set('ip', with: options[selected.to_i])
|
26
|
+
else
|
27
|
+
Display.alert 'Invalid selection'
|
28
|
+
handle # repeat
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def ip_addresses
|
33
|
+
local = Socket.getifaddrs.map { |i| i.addr.ip_address if i.addr.ipv4? }.compact
|
34
|
+
# get public
|
35
|
+
begin
|
36
|
+
remote_ip = open('http://whatismyip.akamai.com').read
|
37
|
+
local << remote_ip
|
38
|
+
rescue => e
|
39
|
+
Display.fatal e.message
|
40
|
+
Display.alert 'public ip lookup failed'
|
41
|
+
end
|
42
|
+
local
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Meshchat
|
3
|
+
module Ui
|
4
|
+
module Command
|
5
|
+
class Chat < Command::Base
|
6
|
+
def handle
|
7
|
+
servers = Node.online
|
8
|
+
if !servers.empty?
|
9
|
+
type = self.class.name.demodulize.downcase
|
10
|
+
m = _message_factory.create(type, data: { message: _input })
|
11
|
+
show_myself(m)
|
12
|
+
|
13
|
+
# if sending to all, iterate thorugh list of
|
14
|
+
# servers, and send to each one
|
15
|
+
# TODO: do this async so that one server doesn't block
|
16
|
+
# the rest of the servers from receiving the messages
|
17
|
+
servers.each do |entry|
|
18
|
+
_message_dispatcher.send_message(node: entry, message: m)
|
19
|
+
end
|
20
|
+
else
|
21
|
+
Display.warning 'you have no servers'
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def show_myself(message)
|
26
|
+
Display.chat message.display
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Meshchat
|
3
|
+
module Ui
|
4
|
+
module Command
|
5
|
+
class Config < Command::Base
|
6
|
+
def self.description
|
7
|
+
'interface for setting and displaying various config options'
|
8
|
+
end
|
9
|
+
|
10
|
+
def handle
|
11
|
+
case sub_command
|
12
|
+
when SET
|
13
|
+
if is_valid_set_command?
|
14
|
+
key, value = config_set_args
|
15
|
+
|
16
|
+
Display.info APP_CONFIG.user.set(key, with: value)
|
17
|
+
else
|
18
|
+
Display.alert 'set requires a key and a value'
|
19
|
+
end
|
20
|
+
when DISPLAY
|
21
|
+
Display.info APP_CONFIG.user.display
|
22
|
+
else
|
23
|
+
Display.alert 'config command not implemented...'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def config_set_args
|
28
|
+
command_args[2..3]
|
29
|
+
end
|
30
|
+
|
31
|
+
def is_valid_set_command?
|
32
|
+
sub_command == SET && command_args.length == 4
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|