pry-remote-em 0.4.3 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -301,6 +301,17 @@ The standard Pry pager is supported through the included client.
301
301
  :
302
302
  ```
303
303
 
304
+ ## Messaging
305
+ It is possible for each pry-remote-em service to host multiple
306
+ simultaneous connections. You can send messages to other connections
307
+ with the '!' and '!!' prefix.
308
+
309
+ The '!' prefix will send the message to connections on the same object.
310
+ the '!!' prefix will send the message to all connections in the current
311
+ process.
312
+
313
+ Message will not be displayed by the clients until the presses enter.
314
+
304
315
  # Missing Features
305
316
 
306
317
  - AutoDiscovery/Broker [ticket](https://github.com/simulacre/pry-remote-em/issues/11)
@@ -58,16 +58,17 @@ module PryRemoteEm
58
58
 
59
59
  def receive_json(j)
60
60
  if j['p'] # prompt
61
- if @negotiated && !@unbound
62
- Fiber.new {
63
- true while (l = Readline.readline(j['p'], true)).empty?
64
- send_data(l)
65
- }.resume
66
- end
61
+ readline(j['p'])
67
62
 
68
63
  elsif j['d'] # printable data
69
64
  stagger_output j['d'], $stdout # Pry::Helpers::BaseHelpers
70
65
 
66
+ elsif j['m']
67
+ Kernel.puts "\033[1m! msg: " + j['m'] + "\033[0m"
68
+
69
+ elsif j['mb']
70
+ Kernel.puts "\033[1m!! msg: " + j['mb'] + "\033[0m"
71
+
71
72
  elsif j['g'] # server banner
72
73
  Kernel.puts "[pry-remote-em] remote is #{j['g']}"
73
74
  name, version, scheme = j['g'].split(" ", 3)
@@ -123,6 +124,22 @@ module PryRemoteEm
123
124
  return succeed if Gem.loaded_specs["eventmachine"].version < Gem::Version.new("1.0.0.beta4")
124
125
  error? ? fail : succeed
125
126
  end
127
+
128
+ def readline(prompt)
129
+ if @negotiated && !@unbound
130
+ Fiber.new {
131
+ l = Readline.readline(prompt, !prompt.nil?)
132
+ if '!!' == l[0..1]
133
+ send_data({:b => l[2..-1]})
134
+ elsif '!' == l[0]
135
+ send_data({:m => l[1..-1]})
136
+ else
137
+ send_data(l)
138
+ end # "!!" == l[0..1]
139
+ }.resume
140
+ end
141
+ end # readline(prompt = @last_prompt)
142
+
126
143
  end # module::Client
127
144
  end # module::PryRemoteEm
128
145
 
@@ -13,7 +13,8 @@ module PryRemoteEm
13
13
  j = JSON.load(@buffer)
14
14
  @buffer.clear
15
15
  receive_json(j)
16
- receive_data(d[(six + DELIM.length)..-1])
16
+ (rem = d[(six + DELIM.length)..-1]).empty? ||
17
+ receive_data(rem)
17
18
  else
18
19
  @buffer << d
19
20
  end
@@ -39,7 +39,7 @@ module PryRemoteEm
39
39
  # TODO raise a useful exception not RuntimeError
40
40
  raise "root permission required for port below 1024 (#{port})" if port < 1024 && Process.euid != 0
41
41
  begin
42
- EM.start_server(host, port, PryRemoteEm::Server, opts) do |pre|
42
+ EM.start_server(host, port, PryRemoteEm::Server, obj, opts) do |pre|
43
43
  Fiber.new {
44
44
  begin
45
45
  Pry.start(obj, :input => pre, :output => pre)
@@ -60,9 +60,28 @@ module PryRemoteEm
60
60
  scheme = opts[:tls] ? 'pryems' : 'pryem'
61
61
  Kernel.puts "[pry-remote-em] listening for connections on #{scheme}://#{host}:#{port}/"
62
62
  end # run(obj, host = DEFHOST, port = DEFPORT)
63
+
64
+ # The list of pry-remote-em connections for a given object, or the list of all pry-remote-em
65
+ # connections for this process.
66
+ # The peer list is used when broadcasting messages between connections.
67
+ def peers(obj = nil)
68
+ @peers ||= {}
69
+ obj.nil? ? @peers.values.flatten : (@peers[obj] ||= [])
70
+ end
71
+
72
+ # Record the association between a given object and a given pry-remote-em connection.
73
+ def register(obj, peer)
74
+ peers(obj).tap { |plist| plist.include?(peer) || plist.push(peer) }
75
+ end
76
+
77
+ # Remove the association between a given object and a given pry-remote-em connection.
78
+ def unregister(obj, peer)
79
+ peers(obj).tap {|plist| true while plist.delete(peer) }
80
+ end
63
81
  end # class << self
64
82
 
65
- def initialize(opts = {:tls => false})
83
+ def initialize(obj, opts = {:tls => false})
84
+ @obj = obj
66
85
  @after_auth = []
67
86
  @opts = opts
68
87
  return unless (a = opts[:auth])
@@ -88,6 +107,7 @@ module PryRemoteEm
88
107
  Kernel.puts "[pry-remote-em] received client connection from #{ip}:#{port}"
89
108
  send_data({:g => "PryRemoteEm #{VERSION} #{@opts[:tls] ? 'pryems' : 'pryem'}"})
90
109
  @opts[:tls] ? start_tls : (@auth_required && send_data({:a => false}))
110
+ PryRemoteEm::Server.register(@obj, self)
91
111
  end
92
112
 
93
113
  def start_tls
@@ -118,6 +138,7 @@ module PryRemoteEm
118
138
  return send_data({:a => false}) if @auth_required && !j['a']
119
139
 
120
140
  if j['d'] # just normal data
141
+ return send_last_prompt if j['d'].empty?
121
142
  @lines.push(*j['d'].split("\n"))
122
143
  if @waiting
123
144
  f, @waiting = @waiting, nil
@@ -142,6 +163,14 @@ module PryRemoteEm
142
163
  end
143
164
  return send_data({:a => !@auth_required})
144
165
 
166
+ elsif j['m'] # message all peer connections
167
+ peers.each { |peer| peer.send_message(j['m']) }
168
+ send_last_prompt
169
+
170
+ elsif j['b'] # broadcast message
171
+ peers(:all).each { |peer| peer.send_bmessage(j['b']) }
172
+ send_last_prompt
173
+
145
174
  else
146
175
  warn "received unexpected data: #{j.inspect}"
147
176
  end # j['d']
@@ -157,12 +186,34 @@ module PryRemoteEm
157
186
  def unbind
158
187
  Pry.config.pager = @old_pager
159
188
  Pry.config.system = @old_system
189
+ PryRemoteEm::Server.unregister(@obj, self)
160
190
  Kernel.puts "[pry-remote-em] remote session terminated (#{peer_ip}:#{peer_port})"
161
191
  end
162
192
 
193
+ def peers(all = false)
194
+ plist = (all ? PryRemoteEm::Server.peers : PryRemoteEm::Server.peers(@obj)).clone
195
+ plist.delete(self)
196
+ plist
197
+ end
198
+
199
+ def send_last_prompt
200
+ @auth_required ? @after_auth.push({:p => @last_prompt}) : send_data({:p => @last_prompt})
201
+ end
202
+
203
+ # Sends a chat message to the client.
204
+ def send_message(msg)
205
+ @auth_required ? @after_auth.push({:m => msg}) : send_data({:m => msg})
206
+ end
207
+ #
208
+ # Sends a chat message to the client.
209
+ def send_bmessage(msg)
210
+ @auth_required ? @after_auth.push({:mb => msg}) : send_data({:mb => msg})
211
+ end
212
+
163
213
  # Methods that make Server compatible with Pry
164
214
 
165
215
  def readline(prompt)
216
+ @last_prompt = prompt
166
217
  @auth_required ? @after_auth.push({:p => prompt}) : send_data({:p => prompt})
167
218
  return @lines.shift unless @lines.empty?
168
219
  @waiting = Fiber.current
@@ -1,3 +1,3 @@
1
1
  module PryRemoteEm
2
- VERSION = '0.4.3'
2
+ VERSION = '0.5.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pry-remote-em
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.5.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-04 00:00:00.000000000Z
12
+ date: 2012-02-06 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: eventmachine
16
- requirement: &70346942721200 !ruby/object:Gem::Requirement
16
+ requirement: &70256102479660 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70346942721200
24
+ version_requirements: *70256102479660
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: pry
27
- requirement: &70346942720300 !ruby/object:Gem::Requirement
27
+ requirement: &70256102473680 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ~>
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 0.9.6
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *70346942720300
35
+ version_requirements: *70256102473680
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rb-readline
38
- requirement: &70346942719100 !ruby/object:Gem::Requirement
38
+ requirement: &70256102473100 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *70346942719100
46
+ version_requirements: *70256102473100
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: highline
49
- requirement: &70346942716820 !ruby/object:Gem::Requirement
49
+ requirement: &70256102471840 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,9 +54,9 @@ dependencies:
54
54
  version: '0'
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70346942716820
57
+ version_requirements: *70256102471840
58
58
  description: Connect to Pry remotely using EventMachine with tab-completion, paging,
59
- user authentication and SSL support.
59
+ user auth and SSL
60
60
  email: pry-remote-em@simulacre.org
61
61
  executables:
62
62
  - pry-remote-em