nserver 1.0.1 → 1.1.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 (7) hide show
  1. data/History.txt +7 -0
  2. data/README.txt +8 -0
  3. data/Rakefile +1 -1
  4. data/bin/nclient +7 -2
  5. data/bin/nserver +28 -1
  6. data/lib/nserver.rb +101 -28
  7. metadata +2 -2
data/History.txt CHANGED
@@ -1,3 +1,10 @@
1
+ == 1.1.0 / 2007-11.07
2
+
3
+ * Major feature - accept connections from any host
4
+ * Bind to any address on machine
5
+ * Allow access based on IPs or Ranges
6
+ * Reject access if not explicitly permitted.
7
+
1
8
  == 1.0.1 / 2007-11-06
2
9
 
3
10
  * Minor enhancement
data/README.txt CHANGED
@@ -22,6 +22,10 @@ If you have the Daemons ruby gem installed, simply run:
22
22
 
23
23
  This starts a persistent NServer::Server instance on port 10001.
24
24
 
25
+ If you want to customize the bind ip or port:
26
+
27
+ % nserver start --bind-ip x.x.x.x --allow y.y.y.y,z.z.z.z/24
28
+
25
29
  === Client Example:
26
30
 
27
31
  Assuming you have a NServer::Server instance running, you can use the client like this:
@@ -39,6 +43,10 @@ or
39
43
 
40
44
  % nclient "Urgent message" -p critical
41
45
 
46
+ If you're NServer is listening on another mahcine, you can:
47
+
48
+ % nclient --host y.y.y.y "My message"
49
+
42
50
  == REQUIREMENTS:
43
51
 
44
52
  * daemons
data/Rakefile CHANGED
@@ -6,7 +6,7 @@ require 'rake'
6
6
  require 'spec/rake/spectask'
7
7
  require './lib/nserver.rb'
8
8
 
9
- Hoe.new('nserver', NServer::Server::VERSION) do |p|
9
+ Hoe.new('nserver', NServer::VERSION) do |p|
10
10
  p.rubyforge_name = 'burningbush'
11
11
  p.author = 'Jon Moses'
12
12
  p.email = 'jon@burningbush.us'
data/bin/nclient CHANGED
@@ -5,10 +5,12 @@ require 'nserver'
5
5
  require 'getoptlong'
6
6
 
7
7
  opts = GetoptLong.new(
8
- [ '--priority', '-p', GetoptLong::REQUIRED_ARGUMENT ]
8
+ [ '--priority', '-p', GetoptLong::REQUIRED_ARGUMENT ],
9
+ [ '--host', GetoptLong::REQUIRED_ARGUMENT ]
9
10
  )
10
11
 
11
12
  priority = :normal
13
+ host_ip = '127.0.0.1'
12
14
  msg = nil
13
15
 
14
16
  opts.each do |opt,arg|
@@ -20,6 +22,8 @@ opts.each do |opt,arg|
20
22
  exit 1
21
23
  end
22
24
  priority = p
25
+ when '--host'
26
+ host_ip = arg
23
27
  end
24
28
  end
25
29
 
@@ -31,7 +35,8 @@ end
31
35
  msg = ARGV[0]
32
36
 
33
37
  begin
34
- NServer::Client.notify( msg, priority )
38
+ client = NServer::Client.new(:host => host_ip)
39
+ client.notify(msg, priority )
35
40
  rescue NServer::NoServerAvailable
36
41
  STDERR.puts("No server available.")
37
42
  exit 1
data/bin/nserver CHANGED
@@ -3,10 +3,37 @@
3
3
  require 'rubygems'
4
4
  require 'daemons'
5
5
  require 'nserver'
6
+ require 'getoptlong'
7
+
8
+ bind_ip = nil
9
+ allowed_client_ips = nil
10
+ port = nil
11
+
12
+ opts = GetoptLong.new(
13
+ ['--bind-ip', GetoptLong::REQUIRED_ARGUMENT ],
14
+ ['--allowed-client-ips', GetoptLong::REQUIRED_ARGUMENT ],
15
+ ['--port', GetoptLong::REQUIRED_ARGUMENT ]
16
+ )
17
+
18
+ opts.each do |opt,arg|
19
+ case opt
20
+ when '--bind-ip'
21
+ bind_ip = arg
22
+ when '--allowed-client-ips'
23
+ allowed_client_ips = arg
24
+ when '--port'
25
+ port = arg
26
+ end
27
+ end
28
+
6
29
 
7
30
  Daemons.run_proc("nserver", :dir => "/tmp", :dir_mode => :normal) do
8
31
 
9
- server = NServer::Server.new
32
+ server = NServer::Server.new(
33
+ :host => bind_ip,
34
+ :port => port,
35
+ :allow => allowed_client_ips
36
+ )
10
37
  server.start
11
38
  server.join
12
39
 
data/lib/nserver.rb CHANGED
@@ -1,44 +1,56 @@
1
1
  require 'RNotify'
2
2
  require 'gserver'
3
3
  require 'socket'
4
+ require 'ipaddr'
4
5
 
5
6
  module NServer
6
- class NoServerAvailable < StandardError
7
- def initialize
8
- super("No server available.")
9
- end
10
- end
11
-
12
- class Message
13
- PRIORITIES = [:low, :normal, :critical]
14
-
15
- attr :text, :writable => true
16
- attr :priority, :writable => true
17
-
18
- def initialize( text = "", priority = :normal )
19
- @text = text
20
- @priority = ( PRIORITIES.index( priority ) or 1 )
21
- end
22
- end
23
-
7
+ VERSION = '1.1.0'
24
8
  class Server < GServer
25
- VERSION = '1.0.1'
26
9
 
27
- def initialize( port = 10001, *args )
28
- super(port, *args)
10
+ # Create a NServer::Server instance
11
+ #
12
+ # Options:
13
+ #
14
+ # port::
15
+ # Port for the server to listen on. Default is 10001
16
+ # host::
17
+ # Host (IP) for the server to listen on. Default is 127.0.0.1
18
+ # Note that if you specify a non-localhost IP here you *must* specifiy
19
+ # an allow list. Also accepts 0.0.0.0 to listen on all available
20
+ # interfaces.
21
+ # allow::
22
+ # Comma seperated list of IPs to accept connections from. Default is
23
+ # only 127.0.0.1 IP ranges are allowed, in a x.x.x.x/y format.
24
+ # check_interval::
25
+ # Interval to check for messages. Default is 10s.
26
+ # tray_icon::
27
+ # GTK Icon name to use for the systray icon. Default is 'gnome-gmush'.
28
+ # msg_timeout::
29
+ # Message display timeout. Default is 5000ms (5s).
30
+ def initialize( opts = {} )
31
+ opts[:port] ||= 10001
32
+ opts[:host] ||= "127.0.0.1"
29
33
 
30
- @check_interval = 10
34
+ super(opts[:port], opts[:host])
35
+
36
+ opts[:check_interval] ||= 10
37
+ opts[:tray_icon] ||= "gnome-gmush"
38
+ opts[:msg_timeout] ||= 5000
39
+ opts[:allow] = ( opts[:allow] or "127.0.0.1" ).split(',').collect {|i| IPAddr.new( i ) }
40
+
41
+ @check_interval = opts[:check_interval]
31
42
 
32
43
  @msg_list = [ Message.new("NServer Ready.") ]
44
+ @allowed_clients = opts[:allow]
33
45
 
34
46
  Notify.init("Notification Server")
35
47
  tray_icon = Gtk::StatusIcon.new
36
- tray_icon.icon_name = "gnome-gmush"
48
+ tray_icon.icon_name = opts[:tray_icon]
37
49
  #tray_icon.file = File.join( File.dirname(__FILE__), 'icons', 'default.png')
38
50
  tray_icon.tooltip = "NServer"
39
51
 
40
52
  @notification = Notify::Notification::new("X", nil, nil, tray_icon)
41
- @notification.timeout = 5000
53
+ @notification.timeout = opts[:msg_timeout]
42
54
 
43
55
  Thread.new { Gtk.main }
44
56
  sleep 5
@@ -53,24 +65,29 @@ module NServer
53
65
  end
54
66
  end
55
67
 
68
+ # Display the message
56
69
  def notify(msg)
57
70
  @notification.update("Message Received", msg.text, nil)
58
71
  @notification.urgency = msg.priority
59
72
  @notification.show
60
73
  end
61
74
 
75
+ # Add a message to the message queue
62
76
  def add_message(msg, priority = :normal)
63
77
  @msg_list << Message.new(msg, priority)
64
78
  end
65
79
 
80
+ # Display the next message, if any.
66
81
  def process
67
82
  if @msg_list.size > 0
68
83
  notify(@msg_list.shift)
69
84
  end
70
85
  end
71
86
 
87
+ # Get and add a message to the list. GServer method.
72
88
  def serve(io)
73
- unless io.addr.last == "127.0.0.1"
89
+ unless @allowed_clients.include?( IPAddr.new(io.peeraddr.last) )
90
+ io.puts "#{io.addr.last} is not allowed."
74
91
  return
75
92
  end
76
93
  io.puts("Enter message, terminate with line break.")
@@ -92,6 +109,7 @@ module NServer
92
109
  end
93
110
  end
94
111
 
112
+ # On server shutdown, also do GUI shutdown stuff.
95
113
  def shutdown
96
114
  Notify.uninit
97
115
  Gtk.main_quit
@@ -100,9 +118,25 @@ module NServer
100
118
  end
101
119
 
102
120
  class Client
103
- def Client.notify( msg, priority = :normal )
121
+ attr :host_ip, :writable => true
122
+ attr :host_port, :writable => true
123
+
124
+ # Create a new client
125
+ #
126
+ # Options:
127
+ #
128
+ # host::
129
+ # The host to connect to. Default is 127.0.0.1
130
+ # post::
131
+ # The port to connect to. Default is 10001.
132
+ def initialize( opts = {} )
133
+ @host_ip = ( opts[:host] or '127.0.0.1' )
134
+ @host_port = ( opts[:port] or '10001' ).to_i
135
+ end
136
+
137
+ def notify( msg, priority = :normal )
104
138
  begin
105
- sock = TCPSocket.new('127.0.0.1', 10001)
139
+ sock = TCPSocket.new(@host_ip, @host_port)
106
140
  sleep(0.1) ## Needs delay, or wait until prompt.
107
141
  sock.write("#{priority.to_s.upcase}:#{msg}\n")
108
142
  sock.close
@@ -111,7 +145,8 @@ module NServer
111
145
  end
112
146
  end
113
147
 
114
- def Client.try_notify( msg, priority = :normal )
148
+
149
+ def try_notify(msg, priority = :normal )
115
150
  begin
116
151
  notify(msg, priority)
117
152
  rescue NoServerAvailable
@@ -120,9 +155,47 @@ module NServer
120
155
  return true
121
156
  end
122
157
 
158
+ def with_notification( msg )
159
+ yield
160
+ notify(msg)
161
+ end
162
+
163
+ # Connect to the currently running NServer instance and add the
164
+ # message to the queue. If no server, raise a NoServerAvailable
165
+ # error.
166
+ def Client.notify( msg, priority = :normal )
167
+ Client.new.notify(msg, priority)
168
+ end
169
+
170
+ # Connect to the currently running NServer, if any, and add the
171
+ # message. If no server is available, just return false.
172
+ def Client.try_notify( msg, priority = :normal )
173
+ Client.new.try_notify(msg, priority)
174
+ end
175
+
176
+ # Run the block, then notify (with errors).
123
177
  def Client.with_notification( msg )
124
178
  yield
125
179
  notify( msg )
126
180
  end
127
181
  end
182
+
183
+ class NoServerAvailable < StandardError
184
+ def initialize
185
+ super("No server available.")
186
+ end
187
+ end
188
+
189
+ class Message
190
+ PRIORITIES = [:low, :normal, :critical]
191
+
192
+ attr :text, :writable => true
193
+ attr :priority, :writable => true
194
+
195
+ def initialize( text = "", priority = :normal )
196
+ @text = text
197
+ @priority = ( PRIORITIES.index( priority ) or 1 )
198
+ end
199
+ end
200
+
128
201
  end
metadata CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.4.5
3
3
  specification_version: 2
4
4
  name: nserver
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.0.1
7
- date: 2007-11-06 00:00:00 -05:00
6
+ version: 1.1.0
7
+ date: 2007-11-07 00:00:00 -05:00
8
8
  summary: Notification server for ruby using libnotify
9
9
  require_paths:
10
10
  - lib