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,60 +0,0 @@
1
- module MeshChat
2
- module Display
3
- class Base
4
-
5
- # instantiate the UI, startup the CLI
6
- def start
7
- fail 'overload this method'
8
- end
9
-
10
- # output a generic line of text
11
- def add_line(_line)
12
- fail 'overload this method'
13
- end
14
-
15
- # formatter for a whisper message
16
- def whisper(_line)
17
- fail 'overload this method'
18
- end
19
-
20
-
21
- # an emote
22
- def emote(_line)
23
- fail 'overload this method'
24
- end
25
-
26
-
27
- # server info or other ignorable information
28
- def info(_line)
29
- fail 'overload this method'
30
- end
31
-
32
- # warning message that the user may or may not care about
33
- def warning(_line)
34
- fail 'overload this method'
35
- end
36
-
37
- # really try to get the user's attention
38
- def alert(_line)
39
- fail 'overload this method'
40
- end
41
-
42
- # a happy message to affirm the user something succeded
43
- def success(_line)
44
- fail 'overload this method'
45
- end
46
-
47
- # general chat message
48
- def chat(_line)
49
- fail 'overload this method'
50
- end
51
-
52
-
53
-
54
- # log a message
55
- def log(_msg)
56
- fail 'overload this method'
57
- end
58
- end
59
- end
60
- end
@@ -1,55 +0,0 @@
1
- require 'meshchat/display/base'
2
-
3
- module MeshChat
4
- module Display
5
- class Manager
6
-
7
- attr_accessor :_ui
8
-
9
- delegate :start, to: :_ui
10
- delegate :add_line, to: :_ui
11
- delegate :info, to: :_ui
12
- delegate :emote, to: :_ui
13
- delegate :warning, to: :_ui
14
- delegate :alert, to: :_ui
15
- delegate :success, to: :_ui
16
- delegate :chat, to: :_ui
17
- delegate :whisper, to: :_ui
18
-
19
- attr_accessor :_logger
20
- delegate :fatal, to: :_logger
21
- delegate :debug, to: :_logger
22
- delegate :error, to: :_logger
23
-
24
- def initialize(ui_klass)
25
- self._logger = Logger.new('debug.log')
26
- self._ui = ui_klass.new
27
- end
28
-
29
- def present_message(message)
30
- result = message.handle
31
- return unless result
32
-
33
- case message.class.name
34
- when Message::Chat.name
35
- chat result
36
- Notify.show(summary: message.sender_name, body: message.message)
37
- when Message::Whisper.name
38
- whisper result
39
- Notify.show(summary: message.sender_name, body: message.message)
40
- when Message::Emote.name
41
- emote result
42
- Notify.show(summary: message.sender_name, body: message.message)
43
- when Message::PingReply.name, Message::Ping.name
44
- info result
45
- when Message::NodeList.name,
46
- Message::NodeListDiff.name,
47
- Message::NodeListHash.name
48
- # display nothing
49
- else
50
- add_line result
51
- end
52
- end
53
- end
54
- end
55
- end
@@ -1,40 +0,0 @@
1
- module MeshChat
2
- class Instance
3
- attr_accessor :client_name, :client_version, :display
4
-
5
- class << self
6
- delegate :client_name, :client_version, :display,
7
- to: :instance
8
-
9
- def start(options)
10
- # calling instance to get things going
11
- @instance = new(options)
12
- @instance.start_input_device(options[:input])
13
- @instance.start_ui(options[:display], options[:on_display_start])
14
- end
15
-
16
- def instance
17
- @instance
18
- end
19
- end
20
-
21
- def initialize(options = {})
22
- self.client_name = options[:client_name] || MeshChat::NAME
23
- self.client_version = options[:client_version] || MeshChat::VERSION
24
- end
25
-
26
- # @param [Class] klass should be something that implements Display::Base
27
- # @param [Proc] proc what to do when starting the UI
28
- def start_ui(klass, on_display_start)
29
- self.display = Display::Manager.new(klass)
30
- display.start do
31
- on_display_start.call if on_display_start
32
- end
33
- end
34
-
35
- def start_input_device(klass)
36
- # The CLI is a singleton that takes a method of input
37
- MeshChat::CLI.create(klass)
38
- end
39
- end
40
- end
@@ -1,41 +0,0 @@
1
- require 'meshchat/message/base'
2
- require 'meshchat/message/chat'
3
- require 'meshchat/message/emote'
4
- require 'meshchat/message/ping'
5
- require 'meshchat/message/ping_reply'
6
- require 'meshchat/message/disconnect'
7
- require 'meshchat/message/whisper'
8
- require 'meshchat/message/relay'
9
- require 'meshchat/message/node_list'
10
- require 'meshchat/message/node_list_diff'
11
- require 'meshchat/message/node_list_hash'
12
-
13
- module MeshChat
14
- module Message
15
- CHAT = 'chat'
16
- EMOTE = 'emote'
17
- PING = 'ping'
18
- PING_REPLY = 'pingreply'
19
- WHISPER = 'whisper'
20
- RELAY = 'relay'
21
- DISCONNECT = 'disconnect'
22
-
23
- NODE_LIST = 'nodelist'
24
- NODE_LIST_HASH = 'nodelisthash'
25
- NODE_LIST_DIFF = 'nodelistdiff'
26
-
27
- TYPES = {
28
- CHAT => Chat,
29
- EMOTE => Emote,
30
- WHISPER => Whisper,
31
- DISCONNECT => Disconnect,
32
- PING => Ping,
33
- PING_REPLY => PingReply,
34
- NODE_LIST => NodeList,
35
- NODE_LIST_DIFF => NodeListDiff,
36
- NODE_LIST_HASH => NodeListHash
37
- }
38
-
39
-
40
- end
41
- end
@@ -1,97 +0,0 @@
1
- module MeshChat
2
- module Message
3
- #
4
- # NOTE:
5
- # #display: shows the message
6
- # should be used locally, before *sending* a message
7
- # #handle: processing logic for the message
8
- # should be used when receiving a message, and there
9
- # needs to be a response right away
10
- # #respond: where the actual logic for the response goes
11
- class Base
12
- attr_accessor :payload, :time_recieved,
13
- :message, :sender_name, :sender_location, :sender_uid
14
-
15
- # @param [String] message
16
- # @param [String] name_of_sender
17
- # @param [String] location the location of the sender
18
- # @param [Hash] payload optionally overrides the default payload
19
- def initialize(
20
- message: '',
21
- sender_name: '',
22
- sender_location: '',
23
- sender_uid: '',
24
- time_recieved: nil,
25
- payload: nil)
26
-
27
- @payload = payload.presence
28
-
29
- # TODO: find a more elegant way to represent this
30
- self.message = message.presence || @payload.try(:[], 'message')
31
- self.sender_name = sender_name.presence || @payload.try(:[], 'sender').try(:[], 'alias') || Settings['alias']
32
- self.sender_location = sender_location.presence || @payload.try(:[], 'sender').try(:[], 'location') || Settings.location
33
- self.sender_uid = sender_uid.presence || @payload.try(:[], 'sender').try(:[], 'uid') || Settings['uid']
34
- self.time_recieved = time_recieved.presence || Time.now
35
-
36
- end
37
-
38
- def payload
39
- @payload ||= {
40
- 'type' => type,
41
- 'message' => message,
42
- 'client' => client,
43
- 'client_version' => client_version,
44
- 'time_sent' => time_recieved || Time.now.to_s,
45
- 'sender' => {
46
- 'alias' => sender_name,
47
- 'location' => sender_location,
48
- 'uid' => sender_uid
49
- }
50
- }
51
- end
52
-
53
- def type
54
- @type ||= TYPES.invert[self.class]
55
- end
56
-
57
- def client
58
- MeshChat.name
59
- end
60
-
61
- def client_version
62
- MeshChat.version
63
- end
64
-
65
- def sender
66
- payload['sender']
67
- end
68
-
69
- # shows the message
70
- # should be used locally, before *sending* a message
71
- def display
72
- message
73
- end
74
-
75
- # processing logic for the message
76
- # should be used when receiving a message, and there
77
- # needs to be a response right away.
78
- # this may call display, if the response is always to be displayed
79
- def handle
80
- display
81
- end
82
-
83
- # Most message types aren't going to need to have an
84
- # immediate response.
85
- #
86
- def respond
87
- return
88
- end
89
-
90
- # this message should be called immediately
91
- # before sending to the whomever
92
- def render
93
- payload.to_json
94
- end
95
- end
96
- end
97
- end
@@ -1,19 +0,0 @@
1
- module MeshChat
2
- module Message
3
- class Chat < Base
4
-
5
- def display
6
- time_recieved = self.time_recieved.strftime('%e/%m/%y %H:%I:%M')
7
- name = payload['sender']['alias']
8
- message = payload['message']
9
-
10
- format_display(time_recieved, name, message)
11
- end
12
-
13
-
14
- def format_display(time, name, message)
15
- "#{time} #{name} > #{message}"
16
- end
17
- end
18
- end
19
- end
@@ -1,13 +0,0 @@
1
- module MeshChat
2
- module Message
3
- class Disconnect < Base
4
- def display
5
- location = payload['sender']['location']
6
- name = payload['sender']['alias']
7
- node = Node.find_by_location(location)
8
- node.update(online: false) if node
9
- "#{name}@#{location} has disconnected"
10
- end
11
- end
12
- end
13
- end
@@ -1,9 +0,0 @@
1
- module MeshChat
2
- module Message
3
- class Emote < Chat
4
- def format_display(time, name, message)
5
- "#{time} #{name} #{message}"
6
- end
7
- end
8
- end
9
- end
@@ -1,63 +0,0 @@
1
- module MeshChat
2
- module Message
3
- class NodeList < Base
4
- def message
5
- @message ||= Node.as_json
6
- end
7
-
8
- def handle
9
- respond
10
- return
11
- end
12
-
13
- # only need to respond if this server has node entries that the
14
- # sender of this message doesn't have
15
- def respond
16
- received_list = message
17
- we_only_have, they_only_have = Node.diff(received_list)
18
-
19
- Display.debug('node_list#respond: me: ' + we_only_have.to_s)
20
- Display.debug('node_list#respond: they: ' + they_only_have.to_s)
21
-
22
- if they_only_have.present?
23
- they_only_have.each do |n|
24
- Node.from_json(n).save!
25
- end
26
- end
27
-
28
-
29
- location = payload['sender']['location']
30
-
31
- node = Node.find_by_location(location)
32
- if we_only_have.present?
33
- Display.debug 'we have nodes that they do not'
34
-
35
- # give the sender our list
36
- MeshChat::Net::Client.send(
37
- node: node,
38
- message: NodeListDiff.new(message: we_only_have)
39
- )
40
-
41
- # give people we know about
42
- # (but the sender of the Node List may not know about)
43
- # our node list diff
44
- Node.online.each do |entry|
45
- MeshChat::Net::Client.send(
46
- node: entry,
47
- message: NodeListDiff.new(message: they_only_have)
48
- )
49
- end
50
- else
51
- Display.debug 'node lists are in sync'
52
-
53
- # lists are in sync, confirm with hash
54
- MeshChat::Net::Client.send(
55
- node: node,
56
- message: NodeListHash.new
57
- )
58
- end
59
-
60
- end
61
- end
62
- end
63
- end
@@ -1,15 +0,0 @@
1
- module MeshChat
2
- module Message
3
- class NodeListDiff < Base
4
- def handle
5
- entries_we_do_not_have = message
6
-
7
- entries_we_do_not_have.each do |entry_as_json|
8
- # this will silently fail if there is a duplicate
9
- # or if this is an invalid entry
10
- Node.from_json(entry_as_json).save
11
- end
12
- end
13
- end
14
- end
15
- end
@@ -1,33 +0,0 @@
1
- module MeshChat
2
- module Message
3
- class NodeListHash < Base
4
- def message
5
- @message ||= Node.as_sha512
6
- end
7
-
8
- # node list hash is received
9
- # @return [NilClass] no output for this message type
10
- def handle
11
- respond
12
- return
13
- end
14
-
15
- def respond
16
- if message != Node.as_sha512
17
- Display.debug 'node list hashes do not match'
18
- location = payload['sender']['location']
19
-
20
- Display.debug 'sending a node list to ' + location
21
- node = Node.find_by_location(location)
22
-
23
- MeshChat::Net::Client.send(
24
- node: node,
25
- message: NodeList.new(message: Node.as_json)
26
- )
27
- else
28
- Display.debug 'node list hash matches'
29
- end
30
- end
31
- end
32
- end
33
- end