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.
Files changed (121) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +39 -11
  3. data/lib/meshchat.rb +48 -42
  4. data/lib/meshchat/configuration.rb +14 -0
  5. data/lib/meshchat/configuration/app_config.rb +63 -0
  6. data/lib/meshchat/configuration/database.rb +41 -0
  7. data/lib/meshchat/{config → configuration}/hash_file.rb +7 -6
  8. data/lib/meshchat/configuration/identity.rb +79 -0
  9. data/lib/meshchat/{config → configuration}/settings.rb +22 -26
  10. data/lib/meshchat/debug.rb +69 -0
  11. data/lib/meshchat/encryption.rb +7 -2
  12. data/lib/meshchat/encryption/aes_rsa.rb +2 -1
  13. data/lib/meshchat/encryption/passthrough.rb +5 -3
  14. data/lib/meshchat/locale/en.yml +14 -0
  15. data/lib/meshchat/models/node.rb +140 -0
  16. data/lib/meshchat/network.rb +19 -0
  17. data/lib/meshchat/network/dispatcher.rb +83 -0
  18. data/lib/meshchat/network/errors.rb +11 -0
  19. data/lib/meshchat/network/incoming.rb +13 -0
  20. data/lib/meshchat/network/incoming/message_decryptor.rb +51 -0
  21. data/lib/meshchat/network/incoming/message_processor.rb +75 -0
  22. data/lib/meshchat/network/incoming/request_processor.rb +30 -0
  23. data/lib/meshchat/network/local.rb +12 -0
  24. data/lib/meshchat/network/local/connection.rb +58 -0
  25. data/lib/meshchat/network/local/server.rb +69 -0
  26. data/lib/meshchat/network/message.rb +34 -0
  27. data/lib/meshchat/network/message/base.rb +139 -0
  28. data/lib/meshchat/network/message/chat.rb +9 -0
  29. data/lib/meshchat/network/message/disconnect.rb +21 -0
  30. data/lib/meshchat/network/message/emote.rb +9 -0
  31. data/lib/meshchat/network/message/factory.rb +80 -0
  32. data/lib/meshchat/network/message/node_list.rb +75 -0
  33. data/lib/meshchat/network/message/node_list_diff.rb +18 -0
  34. data/lib/meshchat/network/message/node_list_hash.rb +32 -0
  35. data/lib/meshchat/network/message/ping.rb +31 -0
  36. data/lib/meshchat/network/message/ping_reply.rb +12 -0
  37. data/lib/meshchat/network/message/whisper.rb +28 -0
  38. data/lib/meshchat/network/remote.rb +13 -0
  39. data/lib/meshchat/network/remote/connection.rb +28 -0
  40. data/lib/meshchat/network/remote/relay.rb +109 -0
  41. data/lib/meshchat/network/remote/relay_pool.rb +52 -0
  42. data/lib/meshchat/ui.rb +13 -0
  43. data/lib/meshchat/ui/cli.rb +48 -0
  44. data/lib/meshchat/ui/cli/base.rb +39 -0
  45. data/lib/meshchat/ui/cli/input_factory.rb +50 -0
  46. data/lib/meshchat/ui/cli/keyboard_line_input.rb +14 -0
  47. data/lib/meshchat/ui/command.rb +51 -0
  48. data/lib/meshchat/ui/command/base.rb +77 -0
  49. data/lib/meshchat/ui/command/bind.rb +47 -0
  50. data/lib/meshchat/ui/command/chat.rb +31 -0
  51. data/lib/meshchat/ui/command/config.rb +37 -0
  52. data/lib/meshchat/ui/command/emote.rb +23 -0
  53. data/lib/meshchat/ui/command/exit.rb +16 -0
  54. data/lib/meshchat/ui/command/help.rb +20 -0
  55. data/lib/meshchat/ui/command/identity.rb +16 -0
  56. data/lib/meshchat/ui/command/import.rb +42 -0
  57. data/lib/meshchat/ui/command/irb.rb +22 -0
  58. data/lib/meshchat/ui/command/offline.rb +23 -0
  59. data/lib/meshchat/ui/command/online.rb +18 -0
  60. data/lib/meshchat/ui/command/ping.rb +65 -0
  61. data/lib/meshchat/ui/command/ping_all.rb +19 -0
  62. data/lib/meshchat/ui/command/send_disconnect.rb +20 -0
  63. data/lib/meshchat/ui/command/server.rb +22 -0
  64. data/lib/meshchat/ui/command/share.rb +16 -0
  65. data/lib/meshchat/ui/command/whisper.rb +40 -0
  66. data/lib/meshchat/ui/display.rb +78 -0
  67. data/lib/meshchat/ui/display/base.rb +58 -0
  68. data/lib/meshchat/ui/display/manager.rb +59 -0
  69. data/lib/meshchat/ui/notifier.rb +9 -0
  70. data/lib/meshchat/ui/notifier/base.rb +33 -0
  71. data/lib/meshchat/version.rb +3 -2
  72. metadata +150 -80
  73. data/lib/meshchat/cli.rb +0 -188
  74. data/lib/meshchat/cli/base.rb +0 -13
  75. data/lib/meshchat/cli/input.rb +0 -37
  76. data/lib/meshchat/command/base.rb +0 -80
  77. data/lib/meshchat/command/bind.rb +0 -44
  78. data/lib/meshchat/command/chat.rb +0 -30
  79. data/lib/meshchat/command/config.rb +0 -34
  80. data/lib/meshchat/command/emote.rb +0 -20
  81. data/lib/meshchat/command/exit.rb +0 -13
  82. data/lib/meshchat/command/help.rb +0 -17
  83. data/lib/meshchat/command/identity.rb +0 -13
  84. data/lib/meshchat/command/import.rb +0 -41
  85. data/lib/meshchat/command/init.rb +0 -34
  86. data/lib/meshchat/command/irb.rb +0 -23
  87. data/lib/meshchat/command/listen.rb +0 -13
  88. data/lib/meshchat/command/offline.rb +0 -20
  89. data/lib/meshchat/command/online.rb +0 -15
  90. data/lib/meshchat/command/ping.rb +0 -65
  91. data/lib/meshchat/command/ping_all.rb +0 -15
  92. data/lib/meshchat/command/send_disconnect.rb +0 -15
  93. data/lib/meshchat/command/server.rb +0 -20
  94. data/lib/meshchat/command/share.rb +0 -13
  95. data/lib/meshchat/command/stop_listening.rb +0 -13
  96. data/lib/meshchat/command/whisper.rb +0 -38
  97. data/lib/meshchat/database.rb +0 -30
  98. data/lib/meshchat/display.rb +0 -33
  99. data/lib/meshchat/display/base.rb +0 -60
  100. data/lib/meshchat/display/manager.rb +0 -55
  101. data/lib/meshchat/instance.rb +0 -40
  102. data/lib/meshchat/message.rb +0 -41
  103. data/lib/meshchat/message/base.rb +0 -97
  104. data/lib/meshchat/message/chat.rb +0 -19
  105. data/lib/meshchat/message/disconnect.rb +0 -13
  106. data/lib/meshchat/message/emote.rb +0 -9
  107. data/lib/meshchat/message/node_list.rb +0 -63
  108. data/lib/meshchat/message/node_list_diff.rb +0 -15
  109. data/lib/meshchat/message/node_list_hash.rb +0 -33
  110. data/lib/meshchat/message/ping.rb +0 -32
  111. data/lib/meshchat/message/ping_reply.rb +0 -9
  112. data/lib/meshchat/message/relay.rb +0 -43
  113. data/lib/meshchat/message/whisper.rb +0 -36
  114. data/lib/meshchat/models/entry.rb +0 -104
  115. data/lib/meshchat/net/client.rb +0 -83
  116. data/lib/meshchat/net/listener/errors.rb +0 -11
  117. data/lib/meshchat/net/listener/request.rb +0 -48
  118. data/lib/meshchat/net/listener/request_processor.rb +0 -50
  119. data/lib/meshchat/net/listener/server.rb +0 -114
  120. data/lib/meshchat/net/request.rb +0 -29
  121. data/lib/meshchat/notifier/base.rb +0 -31
@@ -1,188 +0,0 @@
1
- require 'meshchat/cli/input'
2
- require 'meshchat/cli/base'
3
- require 'meshchat/command/base'
4
- require 'meshchat/command/chat'
5
- require 'meshchat/command/identity'
6
- require 'meshchat/command/irb'
7
- require 'meshchat/command/config'
8
- require 'meshchat/command/ping'
9
- require 'meshchat/command/ping_all'
10
- require 'meshchat/command/server'
11
- require 'meshchat/command/whisper'
12
- require 'meshchat/command/exit'
13
- require 'meshchat/command/listen'
14
- require 'meshchat/command/stop_listening'
15
- require 'meshchat/command/send_disconnect'
16
- require 'meshchat/command/help'
17
- require 'meshchat/command/bind'
18
- require 'meshchat/command/online'
19
- require 'meshchat/command/offline'
20
- require 'meshchat/command/init'
21
- require 'meshchat/command/share'
22
- require 'meshchat/command/import'
23
- require 'meshchat/command/emote'
24
-
25
-
26
- module MeshChat
27
- # A user interface is responsible for for creating a client
28
- # and sending messages to that client
29
- class CLI
30
- COMMAND_MAP = {
31
- MeshChat::Command::Base::CONFIG => MeshChat::Command::Config,
32
- MeshChat::Command::Base::PING => MeshChat::Command::Ping,
33
- MeshChat::Command::Base::PING_ALL => MeshChat::Command::PingAll,
34
- MeshChat::Command::Base::STOP_LISTENING => MeshChat::Command::StopListening,
35
- MeshChat::Command::Base::SERVERS => MeshChat::Command::Server,
36
- MeshChat::Command::Base::SERVER => MeshChat::Command::Server,
37
- MeshChat::Command::Base::EXIT => MeshChat::Command::Exit,
38
- MeshChat::Command::Base::QUIT => MeshChat::Command::Exit,
39
- MeshChat::Command::Base::LISTEN => MeshChat::Command::Listen,
40
- MeshChat::Command::Base::IDENTITY => MeshChat::Command::Identity,
41
- MeshChat::Command::Base::IRB => MeshChat::Command::IRB,
42
- MeshChat::Command::Base::INIT => MeshChat::Command::Init,
43
- MeshChat::Command::Base::SHARE => MeshChat::Command::Share,
44
- MeshChat::Command::Base::IMPORT => MeshChat::Command::Import,
45
- MeshChat::Command::Base::EXPORT => MeshChat::Command::Share,
46
- MeshChat::Command::Base::ONLINE => MeshChat::Command::Online,
47
- MeshChat::Command::Base::OFFLINE => MeshChat::Command::Offline,
48
- MeshChat::Command::Base::HELP => MeshChat::Command::Help,
49
- MeshChat::Command::Base::BIND => MeshChat::Command::Bind,
50
- MeshChat::Command::Base::SEND_DISCONNECT => MeshChat::Command::SendDisconnect,
51
- MeshChat::Command::Base::EMOTE => MeshChat::Command::Emote,
52
- MeshChat::Command::Base::CHAT => MeshChat::Command::Chat
53
-
54
- }
55
-
56
-
57
- attr_accessor :_input_device
58
-
59
- class << self
60
-
61
- delegate :server_location, :listen_for_commands,
62
- :shutdown, :start_server, :client, :server,
63
- :check_startup_settings, :create_input, :close_server,
64
- to: :instance
65
-
66
- def create(input_klass)
67
- @input_klass = input_klass
68
- @instance = new(input_klass)
69
- end
70
-
71
- def get_input
72
- instance.get_input
73
- end
74
-
75
- def instance
76
- # default input collector
77
- @instance ||= new
78
- end
79
- end
80
-
81
-
82
- def initialize(input_klass = nil)
83
- input_klass ||= MeshChat::CLI::Base
84
- # instantiate the interface with which we are communicated with
85
- self._input_device = input_klass.new
86
- # this will allow our listener / server to print exceptions,
87
- # rather than silently fail
88
- Thread.abort_on_exception = true
89
- end
90
-
91
- def listen_for_commands
92
- process_input while true
93
- end
94
-
95
- def process_input
96
- msg = get_input
97
- create_input(msg)
98
- rescue SystemExit, Interrupt
99
- close_program
100
- rescue Exception => e
101
- Display.error e.class.name
102
- Display.error e.message.colorize(:red)
103
- Display.error e.backtrace.join("\n").colorize(:red)
104
- end
105
-
106
- def get_input
107
- _input_device.get_input
108
- end
109
-
110
- def create_input(msg)
111
- Display.debug("input: #{msg}")
112
- handler = Input.create(msg)
113
- handler.handle
114
- rescue => e
115
- Display.error e.message
116
- Display.error e.class.name
117
- Display.error e.backtrace.join("\n").colorize(:red)
118
- end
119
-
120
- def start_server
121
-
122
- unless Settings.valid?
123
- Display.alert("settings not fully valid\n")
124
- errors = Settings.errors
125
- errors.each do |error|
126
- Display.alert(" - #{error}")
127
- end
128
-
129
- if errors.present?
130
- Display.info('set these with /config set <field> <value>')
131
- end
132
-
133
- return
134
- end
135
-
136
- Thread.abort_on_exception = false
137
- Thin::Logging.silent = true
138
-
139
- Thread.new do
140
- # boot sinatra
141
- MeshChat::Net::Listener::Server.run!(
142
- port: MeshChat::Settings['port'],
143
- # logger: MeshChat::Display,
144
- show_exceptions: true,
145
- server: :thin,
146
- dump_errors: true,
147
- threaded: true
148
- )
149
- end
150
- end
151
-
152
- def close_server
153
- puts 'shutting down server'
154
- if @server.present?
155
- server = @server.pop
156
- server.try(:server).try(:close)
157
- end
158
- puts 'no longer listening...'
159
- end
160
-
161
- def server_location
162
- Settings.location
163
- end
164
-
165
- def check_startup_settings
166
- start_server if Settings['autolisten']
167
- end
168
-
169
- def close_program
170
- exit
171
- end
172
-
173
- # save config and exit
174
- def shutdown
175
- # close_server
176
- Display.info 'saving config...'
177
- Settings.save
178
- Display.info 'notifying of disconnection...'
179
- send_disconnect
180
- Display.alert "\n\nGoodbye. \n\nThank you for using #{MeshChat.name}"
181
- exit
182
- end
183
-
184
- def send_disconnect
185
- MeshChat::Command::SendDisconnect.new('/senddisconnect')
186
- end
187
- end
188
- end
@@ -1,13 +0,0 @@
1
- module MeshChat
2
- class CLI
3
- class Base
4
- # override this to alter how input is gathered
5
- #
6
- # the returned value of this method should be a whole line / command
7
- # that will be passed to MeshChat::CLI.create_input
8
- def get_input
9
- gets
10
- end
11
- end
12
- end
13
- end
@@ -1,37 +0,0 @@
1
- module MeshChat
2
- class CLI
3
- class Input
4
- WHISPER = '@'
5
- COMMAND = '/'
6
- attr_accessor :_input
7
-
8
- class << self
9
- def is_command?(input)
10
- input[0, 1] == COMMAND
11
- end
12
-
13
- def is_whisper?(input)
14
- input[0, 1] == WHISPER
15
- end
16
-
17
- def create(input)
18
- klass =
19
- if is_command?(input)
20
- Command::Base
21
- elsif is_whisper?(input)
22
- Command::Whisper
23
- else
24
- Command::Chat
25
- end
26
-
27
- Display.debug("INPUT: Detected '#{klass.name}' from '#{input}'")
28
- klass.new(input)
29
- end
30
- end
31
-
32
- def initialize(input)
33
- self._input = input.chomp
34
- end
35
- end
36
- end
37
- end
@@ -1,80 +0,0 @@
1
- module MeshChat
2
- class Command
3
- class Base < CLI::Input
4
- attr_accessor :_input
5
-
6
- # Commands
7
- SET = 'set'
8
- CONFIG = 'config'
9
- DISPLAY = 'display'
10
- EXIT = 'exit'
11
- QUIT = 'quit'
12
- LISTEN = 'listen'
13
- STOP_LISTENING = 'stoplistening'
14
- CONNECT = 'connect'
15
- CHAT = 'chat'
16
- ADD = 'add'
17
- REMOVE = 'remove'
18
- RM = 'rm'
19
- SERVERS = 'servers'
20
- SERVER = 'server'
21
- WHO = 'who'
22
- PING = 'ping'
23
- PING_ALL = 'pingall'
24
- IDENTITY = 'identity'
25
- IRB = 'c'
26
- INIT = 'init'
27
- SHARE = 'share'
28
- IMPORT = 'import'
29
- EXPORT = 'export'
30
- ONLINE = 'online'
31
- OFFLINE = 'offline'
32
- HELP = 'help'
33
- BIND = 'bind'
34
- SEND_DISCONNECT = 'senddisconnect'
35
- EMOTE = 'me'
36
-
37
- def handle
38
- klass = CLI::COMMAND_MAP[command]
39
- Display.debug("INPUT: #{klass.name} from #{command} derived from #{_input}")
40
- if klass
41
- klass.new(_input).handle
42
- else
43
- Display.alert 'not implemented...'
44
- end
45
- end
46
-
47
- protected
48
-
49
- def corresponding_message_class
50
- my_kind = self.class.name.demodulize
51
- message_root_name = MeshChat::Message.name
52
- message_class_name = "#{message_root_name}::#{my_kind}"
53
-
54
- Display.debug("Corresponding: #{message_class_name}")
55
-
56
- message_class_name.constantize
57
- end
58
-
59
- def command_string
60
- @command_string ||= _input[1, _input.length]
61
- end
62
-
63
- def command_args
64
- @command_args ||= command_string.split(' ')
65
- end
66
-
67
- def command
68
- @command ||= command_args.first
69
- end
70
-
71
- def sub_command_args
72
- @sub_command_args ||= command_args[2..3]
73
- end
74
-
75
- def sub_command
76
- @sub_command ||= command_args[1]
77
- end
78
- end
79
- end
80
- end
@@ -1,44 +0,0 @@
1
- require 'socket'
2
- require 'open-uri'
3
-
4
- module MeshChat
5
- class Command
6
- class Bind < Command::Base
7
- def self.description
8
- 'helper for choosing what ip address to use for yourself'
9
- end
10
-
11
- def handle
12
- options = ip_addresses
13
- option_numbers = []
14
- Display.success 'Choose an ip:'
15
- options.each_with_index do |ip, index|
16
- Display.info "#{index}: #{ip}"
17
- option_numbers << index
18
- end
19
-
20
- selected = MeshChat::CLI.get_input
21
-
22
- if option_numbers.include?(selected.to_i)
23
- Display.success Settings.set('ip', with: options[selected.to_i])
24
- else
25
- Display.alert 'Invalid selection'
26
- handle # repeat
27
- end
28
- end
29
-
30
- def ip_addresses
31
- local = Socket.getifaddrs.map { |i| i.addr.ip_address if i.addr.ipv4? }.compact
32
- # get public
33
- begin
34
- remote_ip = open('http://whatismyip.akamai.com').read
35
- local << remote_ip
36
- rescue => e
37
- Display.fatal e.message
38
- Display.alert 'public ip lookup failed'
39
- end
40
- local
41
- end
42
- end
43
- end
44
- end
@@ -1,30 +0,0 @@
1
- module MeshChat
2
- class Command
3
- class Chat < Command::Base
4
- def handle
5
- servers = Node.online
6
- if !servers.empty?
7
- m = corresponding_message_class.new(
8
- message: _input
9
- )
10
-
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
- Net::Client.send(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
@@ -1,34 +0,0 @@
1
- module MeshChat
2
- class Command
3
- class Config < Command::Base
4
- def self.description
5
- 'interface for setting and displaying various config options'
6
- end
7
-
8
- def handle
9
- case sub_command
10
- when SET
11
- if is_valid_set_command?
12
- key, value = config_set_args
13
-
14
- Display.info Settings.set(key, with: value)
15
- else
16
- Display.alert 'set requires a key and a value'
17
- end
18
- when DISPLAY
19
- Display.info Settings.display
20
- else
21
- Display.alert 'config command not implemented...'
22
- end
23
- end
24
-
25
- def config_set_args
26
- command_args[2..3]
27
- end
28
-
29
- def is_valid_set_command?
30
- sub_command == SET && command_args.length == 4
31
- end
32
- end
33
- end
34
- end
@@ -1,20 +0,0 @@
1
- module MeshChat
2
- class Command
3
- class Emote < Command::Chat
4
- def self.description
5
- 'send an emote to the current chat'
6
- end
7
-
8
- def initialize(input)
9
- input = input.chomp
10
- emote_message = input.gsub(/\A\/me /, '').chomp
11
- self._input = emote_message
12
- end
13
-
14
- def show_myself(message)
15
- Display.info message.display
16
- end
17
-
18
- end
19
- end
20
- end