meshchat 0.11.2 → 0.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/meshchat/configuration/database.rb +2 -0
- data/lib/meshchat/locale/en.yml +1 -0
- data/lib/meshchat/network/message/whisper.rb +4 -0
- data/lib/meshchat/ui/cli/input_factory.rb +18 -0
- data/lib/meshchat/ui/cli/readline_input.rb +26 -2
- data/lib/meshchat/ui/command.rb +11 -3
- data/lib/meshchat/ui/command/all_chat_lock.rb +18 -0
- data/lib/meshchat/ui/command/base.rb +3 -1
- data/lib/meshchat/ui/command/node_finder.rb +58 -0
- data/lib/meshchat/ui/command/whisper.rb +25 -12
- data/lib/meshchat/ui/command/whisper_lock.rb +24 -0
- data/lib/meshchat/ui/display/readline_display.rb +10 -7
- data/lib/meshchat/version.rb +1 -1
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 677204be2321055039fb7d40db56bf98240b65c5
|
4
|
+
data.tar.gz: 7183a0315be9faa2f4730c3a6f3c5d718ae184b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cdf0dfc6e780ce78e04f0986ea82c895e3ced5a76ef0e69184e655aa5d2e3d411a5a53505fdc5f127d3e1820c75f053f15c72fd928eb8f6c23badc5fb1da3853
|
7
|
+
data.tar.gz: 78e642349854b82423d953819e49f326046b5096f3c876611acdc12e1e5584cd98ae1c62d886f044867bf8176f4d247d88621dc009ed2467a54683ad9cdcdd1a
|
data/lib/meshchat/locale/en.yml
CHANGED
@@ -7,6 +7,7 @@ module Meshchat
|
|
7
7
|
COMMAND = '/'
|
8
8
|
|
9
9
|
attr_accessor :_message_dispatcher, :_message_factory, :_cli
|
10
|
+
attr_accessor :_whisper_lock_target
|
10
11
|
|
11
12
|
def initialize(message_dispatcher, message_factory, cli)
|
12
13
|
self._message_dispatcher = message_dispatcher
|
@@ -32,6 +33,14 @@ module Meshchat
|
|
32
33
|
klass.new(input, _message_dispatcher, _message_factory, self)
|
33
34
|
end
|
34
35
|
|
36
|
+
def clear_whisper_lock
|
37
|
+
self._whisper_lock_target = nil
|
38
|
+
end
|
39
|
+
|
40
|
+
def whisper_lock_to(node)
|
41
|
+
self._whisper_lock_target = node
|
42
|
+
end
|
43
|
+
|
35
44
|
def create_for_input(input)
|
36
45
|
klass =
|
37
46
|
if is_command?(input)
|
@@ -39,11 +48,20 @@ module Meshchat
|
|
39
48
|
elsif is_whisper?(input)
|
40
49
|
Command::Whisper
|
41
50
|
else
|
51
|
+
return whisper_for_locked_target(input) if _whisper_lock_target
|
42
52
|
Command::Chat
|
43
53
|
end
|
44
54
|
|
45
55
|
create_with_class(input, klass)
|
46
56
|
end
|
57
|
+
|
58
|
+
def whisper_for_locked_target(input)
|
59
|
+
command = Command::Whisper.new(
|
60
|
+
input, _message_dispatcher, _message_factory, self)
|
61
|
+
|
62
|
+
command._target_node = _whisper_lock_target
|
63
|
+
command
|
64
|
+
end
|
47
65
|
end
|
48
66
|
end
|
49
67
|
end
|
@@ -16,7 +16,18 @@ module Meshchat
|
|
16
16
|
|
17
17
|
def initialize
|
18
18
|
Readline.callback_handler_install('> ') do |line|
|
19
|
-
EventMachine.next_tick {
|
19
|
+
EventMachine.next_tick { handle_input(line) }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def handle_input(line)
|
24
|
+
if @callback
|
25
|
+
# call and clear, so we can resume normal
|
26
|
+
# input handling
|
27
|
+
@callback.call(line)
|
28
|
+
@callback = nil
|
29
|
+
else
|
30
|
+
@input_receiver.create_input(line)
|
20
31
|
end
|
21
32
|
end
|
22
33
|
|
@@ -32,6 +43,10 @@ module Meshchat
|
|
32
43
|
@input_receiver = receiver
|
33
44
|
end
|
34
45
|
|
46
|
+
def callback_on_next_tick=(callback)
|
47
|
+
@callback = callback
|
48
|
+
end
|
49
|
+
|
35
50
|
end
|
36
51
|
|
37
52
|
class << self
|
@@ -40,6 +55,14 @@ module Meshchat
|
|
40
55
|
aliases = Meshchat::Node.all.map { |n| "#{n.alias_name}" }
|
41
56
|
commands + aliases
|
42
57
|
end
|
58
|
+
|
59
|
+
def input_handler
|
60
|
+
@input_handler
|
61
|
+
end
|
62
|
+
|
63
|
+
def input_handler=(handler)
|
64
|
+
@input_handler = handler
|
65
|
+
end
|
43
66
|
end
|
44
67
|
|
45
68
|
def start
|
@@ -48,12 +71,13 @@ module Meshchat
|
|
48
71
|
conn = EventMachine.watch $stdin, Handler
|
49
72
|
conn.notify_readable = true
|
50
73
|
conn.input_receiver = _input_receiver
|
51
|
-
|
74
|
+
self.class.input_handler = conn
|
52
75
|
# update auto completion
|
53
76
|
completion = proc { |s| self.class.autocompletes.grep(/^#{Regexp.escape(s)}/) }
|
54
77
|
Readline.completion_proc = completion
|
55
78
|
end
|
56
79
|
|
80
|
+
|
57
81
|
# def initialize(*args)
|
58
82
|
# super(args)
|
59
83
|
#
|
data/lib/meshchat/ui/command.rb
CHANGED
@@ -7,13 +7,17 @@ module Meshchat
|
|
7
7
|
eager_autoload do
|
8
8
|
autoload :Base
|
9
9
|
autoload :Chat
|
10
|
+
autoload :Emote
|
11
|
+
autoload :Whisper
|
12
|
+
autoload :WhisperLock
|
13
|
+
autoload :AllChatLock
|
14
|
+
|
10
15
|
autoload :Identity
|
11
16
|
autoload :Irb
|
12
17
|
autoload :Config
|
13
18
|
autoload :Ping
|
14
19
|
autoload :PingAll
|
15
20
|
autoload :Server
|
16
|
-
autoload :Whisper
|
17
21
|
autoload :Exit
|
18
22
|
autoload :SendDisconnect
|
19
23
|
autoload :Help
|
@@ -22,8 +26,10 @@ module Meshchat
|
|
22
26
|
autoload :Offline
|
23
27
|
autoload :Share
|
24
28
|
autoload :Import
|
25
|
-
autoload :Emote
|
26
29
|
autoload :Roll
|
30
|
+
|
31
|
+
# Utility
|
32
|
+
autoload :NodeFinder
|
27
33
|
end
|
28
34
|
|
29
35
|
COMMAND_MAP = {
|
@@ -46,7 +52,9 @@ module Meshchat
|
|
46
52
|
Base::SEND_DISCONNECT => SendDisconnect,
|
47
53
|
Base::EMOTE => Emote,
|
48
54
|
Base::ROLL => Roll,
|
49
|
-
Base::CHAT => Chat
|
55
|
+
Base::CHAT => Chat,
|
56
|
+
Base::WHISPER_LOCK => WhisperLock,
|
57
|
+
Base::ALL_CHAT_LOCK => AllChatLock
|
50
58
|
}.freeze
|
51
59
|
end
|
52
60
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Meshchat
|
3
|
+
module Ui
|
4
|
+
module Command
|
5
|
+
class AllChatLock < Command::Base
|
6
|
+
def self.description
|
7
|
+
'sets the current chat to the "All Chat"'
|
8
|
+
end
|
9
|
+
|
10
|
+
def handle
|
11
|
+
return unless _input_factory._whisper_lock_target
|
12
|
+
Display.info 'whisper lock disabled'
|
13
|
+
_input_factory.clear_whisper_lock
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -30,6 +30,8 @@ module Meshchat
|
|
30
30
|
SEND_DISCONNECT = 'senddisconnect'
|
31
31
|
EMOTE = 'me'
|
32
32
|
ROLL = 'roll'
|
33
|
+
WHISPER_LOCK = 'wl'
|
34
|
+
ALL_CHAT_LOCK = 'all'
|
33
35
|
|
34
36
|
attr_reader :_input, :_message_dispatcher
|
35
37
|
attr_reader :_message_factory, :_input_factory
|
@@ -47,7 +49,7 @@ module Meshchat
|
|
47
49
|
if klass
|
48
50
|
_input_factory.create(for_input: _input, with_class: klass).handle
|
49
51
|
else
|
50
|
-
Display.alert
|
52
|
+
Display.alert "#{command} not implemented..."
|
51
53
|
end
|
52
54
|
end
|
53
55
|
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Meshchat
|
2
|
+
module Ui
|
3
|
+
module Command
|
4
|
+
module NodeFinder
|
5
|
+
module_function
|
6
|
+
|
7
|
+
def find_by_target(string, &block)
|
8
|
+
search_key = string.start_with?('#') ? :uid : :alias_name
|
9
|
+
nodes = Node.where(search_key => string)
|
10
|
+
if nodes.length == 0
|
11
|
+
return Display.warning('No node by: ' + string)
|
12
|
+
end
|
13
|
+
|
14
|
+
return block.call(nodes.first) if nodes.length == 1
|
15
|
+
|
16
|
+
Display.warning I18n.t('node.multiple_with_alias', name: string)
|
17
|
+
ask_for_specification(nodes, block)
|
18
|
+
end
|
19
|
+
|
20
|
+
def ask_for_specification(nodes, block)
|
21
|
+
# there are now more than 1 nodes
|
22
|
+
display_nodes(nodes)
|
23
|
+
|
24
|
+
|
25
|
+
# insert a callback into the input handler to run the next
|
26
|
+
# time a line is received
|
27
|
+
#
|
28
|
+
# TODO: this feels gross, is there a better way?
|
29
|
+
# TODO: move this callback from ReadlineInput to the Input Base
|
30
|
+
CLI::ReadlineInput.input_handler.callback_on_next_tick = lambda do |line|
|
31
|
+
answer = line.to_i
|
32
|
+
node = nodes[answer]
|
33
|
+
# finally, send the mesasge
|
34
|
+
# (or do whatever this is)
|
35
|
+
# but usually, it sending the message
|
36
|
+
block.call(node)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def display_nodes(nodes)
|
41
|
+
# write header
|
42
|
+
Display.info "\t\t UID Last Seen"
|
43
|
+
Display.info '-' * 60
|
44
|
+
|
45
|
+
# write nodes
|
46
|
+
nodes.each_with_index do |node, index|
|
47
|
+
i = index.to_s
|
48
|
+
alias_name = node.alias_name
|
49
|
+
uid = node.uid[0..5]
|
50
|
+
last_seen = node.updated_at&.strftime('%B %e, %Y %H:%M:%S') || 'never'
|
51
|
+
line = "%-2s | %-15s %-8s %s" % [i, alias_name, uid, last_seen]
|
52
|
+
Display.info line
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -3,35 +3,48 @@ module Meshchat
|
|
3
3
|
module Ui
|
4
4
|
module Command
|
5
5
|
class Whisper < Command::Base
|
6
|
+
attr_accessor :_target_node
|
7
|
+
|
6
8
|
def self.description
|
7
9
|
'sends a private message to a spepcific person'
|
8
10
|
end
|
9
11
|
|
10
12
|
def target
|
11
13
|
# get first arg
|
14
|
+
return _target_node.alias_name if _target_node
|
12
15
|
command
|
13
16
|
end
|
14
17
|
|
15
18
|
def message
|
19
|
+
return _input if _target_node
|
16
20
|
command_args[1..command_args.length].try(:join, ' ')
|
17
21
|
end
|
18
22
|
|
19
23
|
def handle
|
20
|
-
|
24
|
+
return send_message_to_node(_target_node) if _target_node
|
25
|
+
find_node_and_whisper(target)
|
26
|
+
end
|
21
27
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
28
|
+
def send_message_to_node(node)
|
29
|
+
m = _message_factory.create(
|
30
|
+
Network::Message::WHISPER,
|
31
|
+
data: {
|
32
|
+
message: message,
|
33
|
+
to: target
|
34
|
+
})
|
29
35
|
|
30
|
-
|
36
|
+
Display.whisper m.display
|
37
|
+
|
38
|
+
_message_dispatcher.send_message(node: node, message: m)
|
39
|
+
end
|
31
40
|
|
32
|
-
|
33
|
-
|
34
|
-
|
41
|
+
def find_node_and_whisper(target)
|
42
|
+
NodeFinder.find_by_target(target) do |node|
|
43
|
+
if node
|
44
|
+
send_message_to_node(node)
|
45
|
+
else
|
46
|
+
Display.alert "node for #{target} not found or is not online"
|
47
|
+
end
|
35
48
|
end
|
36
49
|
end
|
37
50
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Meshchat
|
3
|
+
module Ui
|
4
|
+
module Command
|
5
|
+
class WhisperLock < Command::Base
|
6
|
+
def self.description
|
7
|
+
'sets the current chat to to a chosen person'
|
8
|
+
end
|
9
|
+
|
10
|
+
def target
|
11
|
+
# get first arg
|
12
|
+
command_args[1]
|
13
|
+
end
|
14
|
+
|
15
|
+
def handle
|
16
|
+
NodeFinder.find_by_target(target) do |node|
|
17
|
+
Display.info "whisper-locked to #{node.alias_name}##{node.uid}"
|
18
|
+
_input_factory.whisper_lock_to(node)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -35,7 +35,7 @@ module Meshchat
|
|
35
35
|
|
36
36
|
def info(msg)
|
37
37
|
if msg.is_a?(Hash)
|
38
|
-
message_parts_for(msg) do |time, name, message|
|
38
|
+
message_parts_for(msg) do |time, name, message, _|
|
39
39
|
colored_time = (time.to_s + ' ').colorize(:magenta)
|
40
40
|
colored_name = (name + ' ').colorize(:light_black)
|
41
41
|
colored_message = message.colorize(:light_black)
|
@@ -60,7 +60,7 @@ module Meshchat
|
|
60
60
|
end
|
61
61
|
|
62
62
|
def emote(msg)
|
63
|
-
message_parts_for(msg) do |time, name, message|
|
63
|
+
message_parts_for(msg) do |time, name, message, _|
|
64
64
|
colored_time = (time.to_s + ' ').colorize(:magenta)
|
65
65
|
colored_name = (name + ' ').colorize(:light_black)
|
66
66
|
colored_message = message.colorize(:light_black)
|
@@ -70,7 +70,7 @@ module Meshchat
|
|
70
70
|
end
|
71
71
|
|
72
72
|
def chat(msg)
|
73
|
-
message_parts_for(msg) do |time, name, message|
|
73
|
+
message_parts_for(msg) do |time, name, message, _|
|
74
74
|
colored_time = (time.to_s + ' ').colorize(:light_magenta)
|
75
75
|
colored_name = (name + ' ').colorize(:cyan)
|
76
76
|
|
@@ -79,12 +79,14 @@ module Meshchat
|
|
79
79
|
end
|
80
80
|
|
81
81
|
def whisper(msg)
|
82
|
-
message_parts_for(msg) do |time, name, message|
|
82
|
+
message_parts_for(msg) do |time, name, message, to|
|
83
83
|
colored_time = (time.to_s + ' ').colorize(:magenta).bold
|
84
|
-
colored_name =
|
84
|
+
colored_name = name.colorize(:light_black).bold
|
85
85
|
colored_message = message.colorize(:blue).bold
|
86
|
+
colored_to = to.colorize(:blue).bold
|
86
87
|
|
87
|
-
|
88
|
+
names = "#{colored_name}->#{to} "
|
89
|
+
print_non_destructively(colored_time + names + colored_message)
|
88
90
|
end
|
89
91
|
end
|
90
92
|
|
@@ -94,8 +96,9 @@ module Meshchat
|
|
94
96
|
time = msg[:time].strftime('%H:%M:%S')
|
95
97
|
name = msg[:from].to_s
|
96
98
|
message = msg[:message]
|
99
|
+
to = msg[:to]
|
97
100
|
|
98
|
-
yield(time, name, message)
|
101
|
+
yield(time, name, message, to)
|
99
102
|
end
|
100
103
|
end
|
101
104
|
end
|
data/lib/meshchat/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: meshchat
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- L. Preston Sego III
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-05-
|
11
|
+
date: 2016-05-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sqlite3
|
@@ -316,6 +316,7 @@ files:
|
|
316
316
|
- lib/meshchat/ui/cli/keyboard_line_input.rb
|
317
317
|
- lib/meshchat/ui/cli/readline_input.rb
|
318
318
|
- lib/meshchat/ui/command.rb
|
319
|
+
- lib/meshchat/ui/command/all_chat_lock.rb
|
319
320
|
- lib/meshchat/ui/command/base.rb
|
320
321
|
- lib/meshchat/ui/command/bind.rb
|
321
322
|
- lib/meshchat/ui/command/chat.rb
|
@@ -326,6 +327,7 @@ files:
|
|
326
327
|
- lib/meshchat/ui/command/identity.rb
|
327
328
|
- lib/meshchat/ui/command/import.rb
|
328
329
|
- lib/meshchat/ui/command/irb.rb
|
330
|
+
- lib/meshchat/ui/command/node_finder.rb
|
329
331
|
- lib/meshchat/ui/command/offline.rb
|
330
332
|
- lib/meshchat/ui/command/online.rb
|
331
333
|
- lib/meshchat/ui/command/ping.rb
|
@@ -335,6 +337,7 @@ files:
|
|
335
337
|
- lib/meshchat/ui/command/server.rb
|
336
338
|
- lib/meshchat/ui/command/share.rb
|
337
339
|
- lib/meshchat/ui/command/whisper.rb
|
340
|
+
- lib/meshchat/ui/command/whisper_lock.rb
|
338
341
|
- lib/meshchat/ui/display.rb
|
339
342
|
- lib/meshchat/ui/display/base.rb
|
340
343
|
- lib/meshchat/ui/display/manager.rb
|
@@ -366,6 +369,6 @@ rubyforge_project:
|
|
366
369
|
rubygems_version: 2.5.1
|
367
370
|
signing_key:
|
368
371
|
specification_version: 4
|
369
|
-
summary: Meshchat-0.
|
372
|
+
summary: Meshchat-0.12.0
|
370
373
|
test_files: []
|
371
374
|
has_rdoc:
|