meshchat 0.8.0 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
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