ruby_gntp 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -38,17 +38,17 @@ class TooFewParametersError < Exception
38
38
  end
39
39
 
40
40
  class GNTP
41
- attr_reader :app_name, :target_host, :target_port, :password
41
+ attr_reader :app_name, :target_host, :target_port
42
42
  attr_reader :message if $DEBUG
43
43
 
44
44
  RUBY_GNTP_NAME = 'ruby_gntp'
45
- RUBY_GNTP_VERSION = '0.2.3'
45
+ RUBY_GNTP_VERSION = '0.3.0'
46
46
 
47
47
  def initialize(app_name = 'Ruby/GNTP', host = 'localhost', password = '', port = 23053)
48
- @app_name = app_name
49
- @target_host = host
50
- @target_port = port
51
- @password = password
48
+ @app_name = app_name
49
+ @target_host = host
50
+ @target_port = port
51
+ @password = password
52
52
  end
53
53
 
54
54
  #
@@ -56,16 +56,17 @@ class GNTP
56
56
  #
57
57
  def register(params)
58
58
  @notifications = params[:notifications]
59
+ @app_icon = params[:app_icon]
60
+
59
61
  raise TooFewParametersError, "Need least one 'notification' for register" unless @notifications
60
62
 
61
- @app_icon = params[:app_icon]
62
63
  @binaries = []
63
64
 
64
- @message = register_header(@app_name, @app_icon)
65
- @message << output_origin_headers
65
+ message = register_header(@app_name, @app_icon)
66
+ message << output_origin_headers
66
67
 
67
- @message << "Notifications-Count: #{@notifications.size}\r\n"
68
- @message << "\r\n"
68
+ message << "Notifications-Count: #{@notifications.size}\r\n"
69
+ message << "\r\n"
69
70
 
70
71
  @notifications.each do |notification|
71
72
  name = notification[:name]
@@ -73,19 +74,19 @@ class GNTP
73
74
  enabled = notification[:enabled] || true
74
75
  icon = notification[:icon]
75
76
 
76
- @message << "Notification-Name: #{name}\r\n"
77
- @message << "Notification-Enabled: #{enabled ? 'True' : 'False'}\r\n"
78
- @message << "Notification-Display-Name: #{disp_name}\r\n"
79
- @message << "#{handle_icon(icon, 'Notification')}\r\n" if icon
77
+ message << "Notification-Name: #{name}\r\n"
78
+ message << "Notification-Enabled: #{enabled ? 'True' : 'False'}\r\n"
79
+ message << "Notification-Display-Name: #{disp_name}\r\n"
80
+ message << "#{handle_icon(icon, 'Notification')}\r\n" if icon
80
81
  end
81
82
 
82
83
  @binaries.each {|binary|
83
- @message << output_binary(binary)
84
+ message << output_binary(binary)
84
85
  }
85
86
 
86
- @message << "\r\n"
87
+ message << "\r\n"
87
88
 
88
- unless (ret = send_and_recieve(@message))
89
+ unless (ret = send_and_recieve(message))
89
90
  raise "Register failed"
90
91
  end
91
92
  end
@@ -93,27 +94,33 @@ class GNTP
93
94
  #
94
95
  # notify
95
96
  #
96
- def notify(params)
97
+ def notify(params, &callback)
97
98
  name = params[:name]
98
- raise TooFewParametersError, "Notification need 'name', 'title' parameters" unless name || title
99
-
100
99
  title = params[:title]
101
100
  text = params[:text]
102
101
  icon = params[:icon] || get_notification_icon(name)
103
102
  sticky = params[:sticky]
103
+ callback_context = params[:callback_context]
104
+ callback_context_type = params[:callback_context_type]
105
+
106
+ raise TooFewParametersError, "Notification need 'name', 'title' parameters" unless name || title
104
107
 
105
108
  @binaries = []
106
109
 
107
- @message = notify_header(app_name, name, title, text, sticky, icon)
108
- @message << output_origin_headers
110
+ message = notify_header(app_name, name, title, text, sticky, icon)
111
+ message << output_origin_headers
112
+ if callback || callback_context
113
+ message << "Notification-Callback-Context: #{callback_context || '(none)'}\r\n"
114
+ message << "Notification-Callback-Context-Type: #{callback_context_type || '(none)'}\r\n"
115
+ end
109
116
 
110
117
  @binaries.each {|binary|
111
- @message << output_binary(binary)
118
+ message << output_binary(binary)
112
119
  }
113
120
 
114
- @message << "\r\n"
121
+ message << "\r\n"
115
122
 
116
- unless (ret = send_and_recieve(@message))
123
+ unless (ret = send_and_recieve(message, callback))
117
124
  raise "Notify failed"
118
125
  end
119
126
  end
@@ -122,7 +129,7 @@ class GNTP
122
129
  #
123
130
  # instant notification
124
131
  #
125
- def self.notify(params)
132
+ def self.notify(params, &callback)
126
133
  host = params[:host]
127
134
  passwd = params[:passwd]
128
135
 
@@ -133,7 +140,7 @@ class GNTP
133
140
  growl.register(:notifications => [
134
141
  :name => notification[:name]
135
142
  ])
136
- growl.notify(notification)
143
+ growl.notify(notification, &callback)
137
144
  end
138
145
 
139
146
  private
@@ -141,7 +148,7 @@ class GNTP
141
148
  #
142
149
  # send and recieve
143
150
  #
144
- def send_and_recieve msg
151
+ def send_and_recieve(msg, callback=nil)
145
152
  print msg if $DEBUG
146
153
 
147
154
  sock = TCPSocket.open(@target_host, @target_port)
@@ -153,8 +160,24 @@ class GNTP
153
160
  print ">#{rcv}" if $DEBUG
154
161
  ret = $1 if /GNTP\/1.0\s+-(\S+)/ =~ rcv
155
162
  end
156
- sock.close
157
163
 
164
+ if callback
165
+ Thread.new do
166
+ response = {}
167
+ while rcv = sock.gets
168
+ break if rcv == "\r\n"
169
+ print ">>#{rcv}" if $DEBUG
170
+ response[:callback_result] = $1 if /Notification-Callback-Result:\s+(\S*)\r\n/ =~ rcv
171
+ response[:callback_context] = $1 if /Notification-Callback-Context:\s+(\S*)\r\n/ =~ rcv
172
+ response[:callback_context_type] = $1 if /Notification-Callback-Context-Type:\s+(\S*)\r\n/ =~ rcv
173
+ end
174
+ callback.call(response)
175
+ sock.close
176
+ end
177
+ return true
178
+ end
179
+
180
+ sock.close
158
181
  return 'OK' == ret
159
182
  end
160
183
 
@@ -198,6 +221,9 @@ class GNTP
198
221
 
199
222
  platformname, platformversion = '', ''
200
223
 
224
+ # see Proper way to detect Windows platform in Ruby - The Empty Way
225
+ # http://blog.emptyway.com/2009/11/03/proper-way-to-detect-windows-platform-in-ruby/
226
+ #
201
227
  if Config::CONFIG['host_os'] =~ /mswin/
202
228
  ver = `ver`
203
229
  if ver.index('[')
@@ -285,7 +311,9 @@ if __FILE__ == $0
285
311
  :text => "Congraturation! You are successful install ruby_gntp.",
286
312
  :icon => "http://www.hatena.ne.jp/users/sn/snaka72/profile.gif",
287
313
  :sticky=> true
288
- )
314
+ ) do |response|
315
+ p response
316
+ end
289
317
 
290
318
  #--- Use instant notification method (just 'notify')
291
319
  GNTP.notify({
@@ -295,7 +323,14 @@ if __FILE__ == $0
295
323
  :title => "Instant notification",
296
324
  :text => "Instant notification available now.",
297
325
  :icon => "http://www.hatena.ne.jp/users/sn/snaka72/profile.gif",
298
- })
326
+ }) do |response|
327
+ p response
328
+ end
329
+
330
+ #--- wait
331
+ puts
332
+ puts "press enter key to finish."
333
+ a = STDIN.gets
299
334
  end
300
335
 
301
336
  # vim: ts=2 sw=2 expandtab fdm=marker
@@ -54,6 +54,7 @@ describe GNTP do
54
54
  ].each {|expected_text|
55
55
  @sended_messages.last.should include(expected_text)
56
56
  }
57
+
57
58
  end
58
59
 
59
60
  it "can notify with minimum params" do
@@ -72,11 +73,67 @@ describe GNTP do
72
73
  end
73
74
 
74
75
  it "should callback when notify clicked" do
76
+ # prepare callback msg
77
+ @opened_socket.add [
78
+ "GNTP/1.0 -CALLBACK NONE\r\n",
79
+ "Notification-Callback-Result: CLICKED\r\n",
80
+ "Notification-Callback-Context: hoge\r\n",
81
+ "Notification-Callback-Context-Type: fuga\r\n",
82
+ "\r\n",
83
+ ].join
84
+
85
+ callback_called = false
86
+ msg = {}
87
+
75
88
  @gntp = GNTP.new
76
89
  @gntp.register :notifications => [{:name => NOTIFICATION_NAME}]
77
- @gntp.notify(:name => NOTIFICATION_NAME) do |context|
78
- context.should_not_nil
90
+ @gntp.notify(:name => NOTIFICATION_NAME) do |response|
91
+ sleep 1
92
+ callback_called = true
93
+ msg = response
79
94
  end
95
+
96
+ [
97
+ "Notification-Callback-Context: (none)\r\n",
98
+ "Notification-Callback-Context-Type: (none)\r\n"
99
+ ].each {|expected_text|
100
+ @sended_messages.last.should include(expected_text)
101
+ }
102
+
103
+ # wait for callback called
104
+ sleep 3
105
+ callback_called.should be_true
106
+ msg[:callback_result].should == 'CLICKED'
107
+ msg[:callback_context].should == 'hoge'
108
+ msg[:callback_context_type].should == 'fuga'
109
+ end
110
+
111
+ it "should not send 'Notification-Callback-*' header when block parameter has not given" do
112
+ @gntp = GNTP.new
113
+ @gntp.register :notifications => [{:name => NOTIFICATION_NAME}]
114
+ @gntp.notify :name => NOTIFICATION_NAME
115
+
116
+ [
117
+ "Notification-Callback-Context: (none)\r\n",
118
+ "Notification-Callback-Context-Type: (none)\r\n"
119
+ ].each {|expected_text|
120
+ @sended_messages.last.should_not include(expected_text)
121
+ }
122
+ end
123
+
124
+ it "should send 'Notification-Callback-*' header when block parameter has not given, but supply :callback_* parameter given" do
125
+ @gntp = GNTP.new
126
+ @gntp.register :notifications => [{:name => NOTIFICATION_NAME}]
127
+ @gntp.notify :name => NOTIFICATION_NAME,
128
+ :callback_context => 'hoge',
129
+ :callback_context_type => 'text'
130
+
131
+ [
132
+ "Notification-Callback-Context: hoge\r\n",
133
+ "Notification-Callback-Context-Type: text\r\n"
134
+ ].each {|expected_text|
135
+ @sended_messages.last.should include(expected_text)
136
+ }
80
137
  end
81
138
 
82
139
  end
@@ -16,6 +16,12 @@ module GNTPExampleHelperMethods
16
16
  ok_response.rewind
17
17
  end
18
18
 
19
+ stub(sock).add do |msg|
20
+ ok_response.seek(0, IO::SEEK_END)
21
+ ok_response.write msg
22
+ ok_response.rewind
23
+ end
24
+
19
25
  stub(sock).gets do
20
26
  ok_response.gets
21
27
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_gntp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - snaka
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2009-11-07 00:00:00 +09:00
13
+ date: 2009-11-09 00:00:00 +09:00
14
14
  default_executable:
15
15
  dependencies: []
16
16