pry-remote-em 0.4.3 → 0.5.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.
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