agent_xmpp 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.rvmrc +1 -0
- data/README.rdoc +258 -44
- data/Rakefile +6 -5
- data/VERSION +1 -1
- data/agent_xmpp.gemspec +84 -106
- data/default.gems +9 -0
- data/lib/agent_xmpp.rb +1 -0
- data/lib/agent_xmpp/admin.rb +1 -1
- data/lib/agent_xmpp/client/message_delegate.rb +26 -2
- data/lib/agent_xmpp/config.rb +1 -1
- data/lib/agent_xmpp/main.rb +15 -2
- metadata +75 -88
- data/.gitignore +0 -11
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use 1.9.2@agent_xmpp
|
data/README.rdoc
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
=
|
1
|
+
= AgentXMPP
|
2
2
|
|
3
|
-
|
4
|
-
Events. An application that responds to an Ad-Hoc
|
3
|
+
AgentXMPP is an application framework for writing XMPP clients that support Messaging, Ad-Hoc Commands and Publish Subscribe
|
4
|
+
Events. An application that responds to an Ad-Hoc Command can be written with few lines of code.
|
5
5
|
|
6
6
|
# myapp.rb
|
7
7
|
require 'rubygems'
|
@@ -11,7 +11,7 @@ Events. An application that responds to an Ad-Hoc command can be written with fe
|
|
11
11
|
'Hello World'
|
12
12
|
end
|
13
13
|
|
14
|
-
Specify the application Jabber ID (JID), password and roster in <tt>agent_xmpp.yml</tt>.
|
14
|
+
Specify the application Jabber ID (JID), password and contact roster in <tt>agent_xmpp.yml</tt>.
|
15
15
|
|
16
16
|
jid: myapp@nowhere.com
|
17
17
|
password: none
|
@@ -27,7 +27,7 @@ Be sure libxml2 headers are available and that libsqlite3-ruby1.9.1 is installed
|
|
27
27
|
|
28
28
|
Install the gem,
|
29
29
|
|
30
|
-
sudo gem install
|
30
|
+
sudo gem install agent_xmpp
|
31
31
|
|
32
32
|
Install the Gajim XMPP Client version 0.12.3 or higher, http://www.gajim.org, and connect to <i>you@home.com</i>.
|
33
33
|
|
@@ -35,10 +35,11 @@ Run the application,
|
|
35
35
|
|
36
36
|
ruby myapp.rb
|
37
37
|
|
38
|
-
When started for the first time <tt>myapp.rb</tt> will automatically send
|
39
|
-
in <tt>agent_xmpp.yml</tt
|
40
|
-
and select _execute_ _commands_ from the drop down menu. A list of Ad-Hoc Commands will be displayed containing _hello_.
|
41
|
-
|
38
|
+
When started for the first time <tt>myapp.rb</tt> will automatically send contact requests to all contacts specified
|
39
|
+
in the <tt>agent_xmpp.yml</tt> contact roster. If you accept the contact request _myapp_ will appear in the Gajim contact roster.
|
40
|
+
Right click on _myapp_ and select _execute_ _commands_ from the drop down menu. A list of Ad-Hoc Commands will be displayed containing _hello_. Select it and click the _forward_ _button_ to execute.
|
41
|
+
|
42
|
+
See http://github.com/troystribling/agent_xmpp/blob/master/test/app/app.rb for many examples.
|
42
43
|
|
43
44
|
== Supported Environment
|
44
45
|
|
@@ -50,10 +51,46 @@ The following Operating Systems are supported
|
|
50
51
|
|
51
52
|
Ubuntu 10.4
|
52
53
|
|
54
|
+
== Contact Groups
|
55
|
+
|
56
|
+
Contact groups may be specified in <tt>agent_xmpp.yml</tt>.
|
57
|
+
|
58
|
+
jid: myapp@nowhere.com
|
59
|
+
password: none
|
60
|
+
roster:
|
61
|
+
-
|
62
|
+
jid:you@home.com
|
63
|
+
groups: [good group, owners]
|
64
|
+
|
65
|
+
-
|
66
|
+
jid: someone@somewhere.com
|
67
|
+
groups: [bad group]
|
68
|
+
|
69
|
+
== Agent Administrator Commands
|
70
|
+
|
71
|
+
Any contact that is in the <tt>admin</tt> contact group can execute <em>Administrator Commands</em>. At least one administrator should be specified in <tt>agent_xmpp.yml</tt>. The following commands are available to agent administrators.
|
72
|
+
|
73
|
+
* <b>contacts</b>: List the contact roster.
|
74
|
+
|
75
|
+
* <b>online users</b>: List all online users.
|
76
|
+
|
77
|
+
* <b>add contact</b>: Add a contact.
|
78
|
+
|
79
|
+
* <b>delete contact</b>: Delete a contact.
|
80
|
+
|
81
|
+
* <b>subscriptions</b>: List all subscriptions with statistics.
|
82
|
+
|
83
|
+
* <b>publications</b>: List all publications with statistics.
|
84
|
+
|
85
|
+
* <b>messages by type</b>: List message statistics by message type.
|
86
|
+
|
87
|
+
* <b>messages by contact</b>: List message statistics by contact.
|
88
|
+
|
89
|
+
* <b>messages by command</b>: List message statistics by command.
|
90
|
+
|
53
91
|
== Ad-Hoc Command Response Payload
|
54
92
|
|
55
|
-
|
56
|
-
response payloads (see XEP-0004 http://xmpp.org/extensions/xep-0004.html for a description of jabber:x:data).
|
93
|
+
<em>Ad-Hoc Commands</em> allow XMPP clients to send and receive structured parameterized commands. To process an <em>Ad-Hoc Command</em> request in an AgentXMPP application use <tt>command</tt> blocks. AgentXMPP will map native ruby scalars, arrays and hashes returned by <tt>command</tt> blocks to jabber:x:data command response payloads (see XEP-0004 http://xmpp.org/extensions/xep-0004.html for a description of jabber:x:data).
|
57
94
|
|
58
95
|
command 'scalar' do
|
59
96
|
'scalar'
|
@@ -83,16 +120,136 @@ response payloads (see XEP-0004 http://xmpp.org/extensions/xep-0004.html for a d
|
|
83
120
|
{:a1 => ['v31', 'v31'], :a2 => 'v32'}]
|
84
121
|
end
|
85
122
|
|
86
|
-
|
123
|
+
== Ad-Hoc Command Data Forms
|
124
|
+
|
125
|
+
XMPP provides a simple form specification for entry of <em>Ad-Hoc Command</em> parameters, http://xmpp.org/extensions/xep-0004.html#protocol-fieldtypes. AgentXMPP supports the following form controls.
|
126
|
+
|
127
|
+
* <b>title</b>: The form title.
|
128
|
+
|
129
|
+
* <b>instructions</b>: Form usage instructions for the user.
|
130
|
+
|
131
|
+
* <b>fixed</b>: Static text.
|
132
|
+
|
133
|
+
* <b>text-single</b>: Single line text entry.
|
134
|
+
|
135
|
+
* <b>text-private</b>: Single line private text entry for passwords.
|
136
|
+
|
137
|
+
* <b>jid-single</b>: Single JID entry with syntax validation.
|
138
|
+
|
139
|
+
* <b>text-multi</b>: Muli-line text entry.
|
140
|
+
|
141
|
+
* <b>list-single</b>: Select a single item from a list items.
|
142
|
+
|
143
|
+
* <b>boolean</b>: Select a boolean value for an item.
|
144
|
+
|
145
|
+
Form controls are specified in an <tt>on</tt> bloc which takes the command <tt>action</tt> as an argument and <tt>yields</tt> the <tt>form</tt>. Valid values for the action are <tt>:execute</tt> and <tt>:submit</tt>. In a simple form the controls are specified in <tt>on(:execute)</tt> and the response in <tt>on(:submit)</tt>.
|
146
|
+
|
147
|
+
command 'long_form' do
|
148
|
+
on(:execute) do |form|
|
149
|
+
form.add_title('The Long Form')
|
150
|
+
form.add_instructions('Make the correct choices and provide the required information.')
|
151
|
+
form.add_fixed("Your name is required.")
|
152
|
+
form.add_text_single('first_name', 'First Name')
|
153
|
+
form.add_text_single('last_name', 'Last Name')
|
154
|
+
form.add_fixed("Your address is required.")
|
155
|
+
form.add_text_single('street', 'Street')
|
156
|
+
form.add_text_single('city', 'City')
|
157
|
+
form.add_text_single('state', 'State')
|
158
|
+
form.add_text_single('zip', 'Zip Code')
|
159
|
+
form.add_fixed("Enter two friends.")
|
160
|
+
form.add_jid_single('contact_1', 'contact JID')
|
161
|
+
form.add_jid_single('contact_2', 'contact JID')
|
162
|
+
form.add_fixed("Your password is required.")
|
163
|
+
form.add_text_private('password', 'Password')
|
164
|
+
form.add_text_private('renter_password', 'Renter Password')
|
165
|
+
form.add_fixed("Choose your food.")
|
166
|
+
form.add_list_single('fruits', [:apple, :orange, :lemon, :lime, :kiwi_fruit], 'Select a Fruit')
|
167
|
+
form.add_list_single('nuts', [:peanut, :almond, :cashew, :pecan, :walnut], 'Select a Nut')
|
168
|
+
form.add_list_single('vegetables', [:broccoli, :carrot, :corn, :tomato, :onion], 'Select a Vegtable')
|
169
|
+
form.add_fixed("Answer the questions.")
|
170
|
+
form.add_boolean('yes_or_no', 'Yes or No please?')
|
171
|
+
form.add_boolean('flux_capcitors', 'Enable flux capacitors for superluminal transport')
|
172
|
+
form.add_fixed("A story of at least 250 characters is required")
|
173
|
+
form.add_text_multi('story', 'Your Story')
|
174
|
+
end
|
175
|
+
on(:submit) do
|
176
|
+
params[:data]
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
If command parameters have dependencies multi-step forms can be used. Multi-step forms are specified by a sequence of <tt>on(:submit)</tt> blocks that are called in the order listed.
|
181
|
+
|
182
|
+
command 'multiple_steps' do
|
183
|
+
on(:execute) do |form|
|
184
|
+
form.add_title('Account Features')
|
185
|
+
form.add_instructions('Enter and Account')
|
186
|
+
form.add_jid_single('jid', 'account JID')
|
187
|
+
end
|
188
|
+
on(:submit) do |form|
|
189
|
+
form.add_title("Account '#{params[:data]['jid']}'")
|
190
|
+
form.add_instructions('Enable/Disbale features')
|
191
|
+
form.add_boolean('idle_logout', 'On or Off please')
|
192
|
+
form.add_boolean('electrocution', 'Electrocute on login failure?')
|
193
|
+
form.add_text_multi('mod', 'Message of the day')
|
194
|
+
form.add_text_multi('warn', 'Warning message')
|
195
|
+
end
|
196
|
+
on(:submit) do
|
197
|
+
params_list.inject({}){|r,p| r.merge(p[:data])}
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
== Command Authorization
|
202
|
+
|
203
|
+
AgentXMPP allows command authorization groups to be specified by XMPP contact groups.
|
204
|
+
|
205
|
+
command 'do_something', :access => 'good' do
|
206
|
+
Something.do_it(params[:data])
|
207
|
+
end
|
208
|
+
|
209
|
+
command 'do_something', :access => ['bad', 'good'] do
|
210
|
+
SomethingElse.do_it(params[:data])
|
211
|
+
end
|
212
|
+
|
213
|
+
== Command Before Filters
|
214
|
+
|
215
|
+
AgentXMPP supports specification of filters executed before command execution that must return a boolean value. If the filter returns <tt>true</tt> the command executes. If <tt>false</tt> is returned the command does not execute.
|
216
|
+
|
217
|
+
before :command => :all do
|
218
|
+
jid = params[:from]
|
219
|
+
AgentXmpp::Roster.find_by_jid(jid) or AgentXmpp.is_account_jid?(jid)
|
220
|
+
end
|
87
221
|
|
88
|
-
|
222
|
+
before :command => 'do_something' do
|
223
|
+
Something.do_it?(params)
|
224
|
+
end
|
225
|
+
|
226
|
+
before :command => ['do_something', 'and_something_else'] do
|
227
|
+
Something.do_it?(params)
|
228
|
+
end
|
229
|
+
|
230
|
+
== Deferred Command Execution
|
231
|
+
|
232
|
+
By default AgentXMPP executes commands in the main event loop. If a command requires a lot of time for execution it can be deferred to a thread pool.
|
233
|
+
|
234
|
+
command 'starship_engine_configuration', :defer => true do
|
235
|
+
on(:execute) do |form|
|
236
|
+
form.add_title('Hyper Drive Configuration')
|
237
|
+
form.add_instructions('Choose the hyperdrive configuration which best suits your needs')
|
238
|
+
form.add_boolean('answer', 'On or Off please')
|
239
|
+
form.add_boolean('flux_capcitors', 'Enable flux capacitors for superluminal transport')
|
240
|
+
form.add_fixed('Enable SQUIDs for enhanced quantum decoherence')
|
241
|
+
form.add_boolean('squids')
|
242
|
+
end
|
243
|
+
on(:submit) do
|
244
|
+
StarshipEngineering.engage(params[:data])
|
245
|
+
end
|
246
|
+
end
|
89
247
|
|
90
|
-
Agent XMPP supports
|
91
248
|
== Send Commands
|
92
249
|
|
93
250
|
Commands may be sent with or without a response callback,
|
94
251
|
|
95
|
-
send_command(:to=>'thatapp@
|
252
|
+
send_command(:to=>'thatapp@aplace.com/ahost', :node=> 'hello') do |status, data|
|
96
253
|
puts "COMMAND RESPONSE: #{status}, #{data.inspect}"
|
97
254
|
end
|
98
255
|
|
@@ -107,6 +264,77 @@ and within <tt>command</tt> blocks.
|
|
107
264
|
{:a1 => 'v1', :a2 => 'v2'}
|
108
265
|
end
|
109
266
|
|
267
|
+
== Command Error Response
|
268
|
+
|
269
|
+
Error responses to <em>Ad-Hoc Command</em> requests can be sent if an error is encountered during command execution.
|
270
|
+
|
271
|
+
command 'do_something' do
|
272
|
+
if MyValidator.can_do_something?(params)
|
273
|
+
'I did it'
|
274
|
+
else
|
275
|
+
error(:bad_request, params, 'jid not specified')
|
276
|
+
end
|
277
|
+
end
|
278
|
+
|
279
|
+
In general the error response syntax has the form,
|
280
|
+
|
281
|
+
error(error_type, params, error_message)
|
282
|
+
|
283
|
+
Valid <tt>error_types</tt> are,
|
284
|
+
|
285
|
+
:bad-request
|
286
|
+
:conflict
|
287
|
+
:feature-not-implemented
|
288
|
+
:forbidden
|
289
|
+
:gone
|
290
|
+
:internal-server-error
|
291
|
+
:item-not-found
|
292
|
+
:jid-malformed
|
293
|
+
:not-acceptable
|
294
|
+
:not-allowed
|
295
|
+
:not-authorized
|
296
|
+
:payment-required
|
297
|
+
:recipient-unavailable
|
298
|
+
:redirect
|
299
|
+
:registration-required
|
300
|
+
:remote-server-not-found
|
301
|
+
:remote-server-timeout
|
302
|
+
:resource-constraint
|
303
|
+
:service-unavailable
|
304
|
+
:subscription-required
|
305
|
+
:undefined-condition
|
306
|
+
:unexpected-request
|
307
|
+
|
308
|
+
== Command Response Delegation
|
309
|
+
|
310
|
+
Command responses may be delegated to one or more <em>Message Processing Callbacks</em> (see the last section <em>Message Processing Callbacks</em> for a list). <em>Message Processing Callbacks</em> give applications the ability to interface with the framework message processing workflow. <em>Command Response Delegation</em> is useful when a command must send another message and the response of this secondary message is processed by the framework. The command then delegates its response to the secondary message response. In the example below of the <tt>add_contact</tt> administration message the command sends a command to the server to add a roster item and does not respond to the original request until the response of the add roster item request is received from the server.
|
311
|
+
|
312
|
+
command 'admin/add_contact', :access => 'admin' do
|
313
|
+
on(:execute) do |form|
|
314
|
+
form.add_title('Add Contact')
|
315
|
+
form.add_jid_single('jid', 'contact JID')
|
316
|
+
form.add_text_single('groups', 'groups comma seperated')
|
317
|
+
end
|
318
|
+
on(:submit) do
|
319
|
+
contact = params[:data]
|
320
|
+
if contact["jid"]
|
321
|
+
AgentXmpp::Contact.update(contact)
|
322
|
+
xmpp_msg(AgentXmpp::Xmpp::IqRoster.update(pipe, contact["jid"], contact["groups"].split(/,/)))
|
323
|
+
xmpp_msg(AgentXmpp::Xmpp::Presence.subscribe(contact["jid"]))
|
324
|
+
delegate_to(
|
325
|
+
:on_update_roster_item_result => lambda do |pipe, item_jid|
|
326
|
+
command_completed if item_jid.eql?(contact["jid"])
|
327
|
+
end,
|
328
|
+
:on_update_roster_item_error => lambda do |pipe, item_jid|
|
329
|
+
error(:bad_request, params, 'roster updated failed') if item_jid.eql?(contact["jid"])
|
330
|
+
end
|
331
|
+
)
|
332
|
+
else
|
333
|
+
error(:bad_request, params, 'jid not specified')
|
334
|
+
end
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
110
338
|
== Publish
|
111
339
|
|
112
340
|
Publish nodes are configured in <tt>agent_xmpp.yml</tt>.
|
@@ -162,7 +390,7 @@ Declare <tt>event</tt> blocks in <tt>myapp.rb</tt> to subscribe to published eve
|
|
162
390
|
message(:to=>'someone@somewhere.com', :body=>"Got the event at: " + Time.now.to_s)
|
163
391
|
end
|
164
392
|
|
165
|
-
|
393
|
+
AgentXMPP will verify subscription to the event and subscribe if required. Subscriptions
|
166
394
|
discovered that are not declared by an event block will be deleted.
|
167
395
|
|
168
396
|
== Receive Chat Messages
|
@@ -183,23 +411,6 @@ If the <tt>chat</tt> block returns a <tt>String</tt> a response will be sent to
|
|
183
411
|
|
184
412
|
send_chat(:to=>'thatapp@a-place.com/onahost', :body=>"Hello from #{AgentXmpp.jid.to_s} at " + Time.now.to_s)
|
185
413
|
|
186
|
-
== Roster
|
187
|
-
|
188
|
-
Roster groups may be specified in <tt>agent_xmpp.yml</tt>.
|
189
|
-
|
190
|
-
jid: myapp@nowhere.com
|
191
|
-
password: none
|
192
|
-
roster:
|
193
|
-
-
|
194
|
-
jid:you@home.com
|
195
|
-
groups: [good group, owners]
|
196
|
-
|
197
|
-
-
|
198
|
-
jid: someone@somewhere.com
|
199
|
-
groups: [bad group]
|
200
|
-
|
201
|
-
Agent XMPP will update the roster maintained on the XMPP server to be consistent with to the roster specified in <tt>agent_xmpp.yml</tt>.
|
202
|
-
|
203
414
|
== Routing Priority
|
204
415
|
|
205
416
|
The routing priority may be configured in <tt>agent_xmpp.yml</tt>. The default value is 1. Valid values are between -127 and 128.
|
@@ -213,9 +424,15 @@ See http://xmpp.org/rfcs/rfc3921.html for a details.
|
|
213
424
|
jid:you@home.com
|
214
425
|
groups: [good group, owners]
|
215
426
|
|
427
|
+
== Message Processing Context Extension
|
428
|
+
|
429
|
+
You can add methods to the <tt>command</tt> and <tt>chat</tt> context by adding your methods to a module and calling,
|
430
|
+
|
431
|
+
include_module MyExtensions
|
432
|
+
|
216
433
|
== Major Event Callbacks
|
217
434
|
|
218
|
-
|
435
|
+
AgentXMPP provides callbacks for applications to respond to major events that occur during execution.
|
219
436
|
|
220
437
|
# application starting
|
221
438
|
before_start{}
|
@@ -242,10 +459,7 @@ Agent XMPP provides callbacks for applications to respond to major events that o
|
|
242
459
|
== Development with XMPP Clients
|
243
460
|
|
244
461
|
Ad-Hoc Commands, jabber:x:data Forms nor Service Discovery are widely supported by XMPP clients and I have not found
|
245
|
-
a client that supports Publish-Subscribe. Gajim http://www.gajim.org provides support for Ad-Hoc Commands and jabber:x:data Forms. Service Discovery,
|
246
|
-
which is useful for Publish-Subscibe development, is supported by Gajim, but Psi http://psi-im.org provides a much better
|
247
|
-
implementation. Both Gajim and Psi provide an interface for manual entry of XML messages. Since Publish-Subscribe is not supported on
|
248
|
-
the user interface manual entry of messages is required for development. Example messages can be found at http://gist.github.com/160344
|
462
|
+
a client that adequately supports Publish-Subscribe. Gajim http://www.gajim.org provides support for Ad-Hoc Commands and jabber:x:data Forms. Service Discovery, which is useful for Publish-Subscibe development, is supported by Gajim, but Psi http://psi-im.org provides a much better implementation. Both Gajim and Psi provide an interface for manual entry of XML messages. Since Publish-Subscribe is not supported on the user interface manual entry of messages is required for development. Example messages can be found at http://gist.github.com/160344
|
249
463
|
|
250
464
|
== Logging
|
251
465
|
|
@@ -265,15 +479,15 @@ More examples can be found at http://gist.github.com/160338
|
|
265
479
|
|
266
480
|
== Supported XEPs
|
267
481
|
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
482
|
+
* XEP-0004 jabber:x:data Forms http://xmpp.org/extensions/xep-0004.html
|
483
|
+
* XEP-0030 Service Discovery http://xmpp.org/extensions/xep-0030.html
|
484
|
+
* XEP-0050 Ad-Hoc Commands http://xmpp.org/extensions/xep-0050.html
|
485
|
+
* XEP-0060 Publish Subscribe http://xmpp.org/extensions/xep-0060.html
|
486
|
+
* XEP-0092 Software Version http://xmpp.org/extensions/xep-0092.html
|
273
487
|
|
274
488
|
== Message Processing Callbacks
|
275
489
|
|
276
|
-
Message
|
490
|
+
<em>Message Processing Callbacks</em> are available to applications to extend the agent message processing work flow. To receive
|
277
491
|
callbacks a delegate object must be provided that implements the callbacks of interest.
|
278
492
|
|
279
493
|
after_connected do |connection|
|
data/Rakefile
CHANGED
@@ -12,15 +12,16 @@ begin
|
|
12
12
|
require 'jeweler'
|
13
13
|
Jeweler::Tasks.new do |gem|
|
14
14
|
gem.name = "agent_xmpp"
|
15
|
-
gem.summary = %Q{Agent XMPP is a ruby XMPP bot framework inspired by
|
15
|
+
gem.summary = %Q{Agent XMPP is a ruby XMPP bot framework inspired by web frameworks.}
|
16
16
|
gem.email = "troy.stribling@gmail.com"
|
17
17
|
gem.homepage = "http://github.com/troystribling/agent_xmpp"
|
18
18
|
gem.authors = ["Troy Stribling"]
|
19
19
|
gem.files.include %w(lib/jeweler/templates/.gitignore VERSION)
|
20
|
-
gem.add_dependency('rake',
|
21
|
-
gem.add_dependency('eventmachine',
|
22
|
-
gem.add_dependency('sequel',
|
23
|
-
gem.add_dependency('evma_xmlpushparser',
|
20
|
+
gem.add_dependency('rake', '>= 0.8.3')
|
21
|
+
gem.add_dependency('eventmachine', '>= 0.12.6')
|
22
|
+
gem.add_dependency('sequel', '>= 3.9.0')
|
23
|
+
gem.add_dependency('evma_xmlpushparser', '>= 0.0.1')
|
24
|
+
gem.add_dependency('sqlite3', '>= 1.3.3')
|
24
25
|
end
|
25
26
|
rescue LoadError
|
26
27
|
abort "jeweler is not available. In order to run test, you must: sudo gem install technicalpickles-jeweler --source=http://gems.github.com"
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.1
|
data/agent_xmpp.gemspec
CHANGED
@@ -1,144 +1,122 @@
|
|
1
1
|
# Generated by jeweler
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{agent_xmpp}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.1"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = [
|
12
|
-
s.date = %q{
|
11
|
+
s.authors = [%q{Troy Stribling}]
|
12
|
+
s.date = %q{2011-06-12}
|
13
13
|
s.email = %q{troy.stribling@gmail.com}
|
14
14
|
s.extra_rdoc_files = [
|
15
15
|
"LICENSE",
|
16
|
-
|
16
|
+
"README.rdoc"
|
17
17
|
]
|
18
18
|
s.files = [
|
19
19
|
".document",
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
"test/cases/test_application_message_processing.rb",
|
71
|
-
"test/cases/test_errors.rb",
|
72
|
-
"test/cases/test_presence_management.rb",
|
73
|
-
"test/cases/test_roster_management.rb",
|
74
|
-
"test/cases/test_service_discovery.rb",
|
75
|
-
"test/cases/test_session_management.rb",
|
76
|
-
"test/cases/test_version_discovery.rb",
|
77
|
-
"test/helpers/matchers.rb",
|
78
|
-
"test/helpers/mocks.rb",
|
79
|
-
"test/helpers/test_case_extensions.rb",
|
80
|
-
"test/helpers/test_client.rb",
|
81
|
-
"test/helpers/test_delegate.rb",
|
82
|
-
"test/helpers/test_helper.rb",
|
83
|
-
"test/messages/application_messages.rb",
|
84
|
-
"test/messages/error_messages.rb",
|
85
|
-
"test/messages/presence_messages.rb",
|
86
|
-
"test/messages/roster_messages.rb",
|
87
|
-
"test/messages/service_discovery_messages.rb",
|
88
|
-
"test/messages/session_messages.rb",
|
89
|
-
"test/messages/version_discovery_messages.rb",
|
90
|
-
"test/peer/peer.rb"
|
91
|
-
]
|
92
|
-
s.homepage = %q{http://github.com/troystribling/agent_xmpp}
|
93
|
-
s.rdoc_options = ["--charset=UTF-8"]
|
94
|
-
s.require_paths = ["lib"]
|
95
|
-
s.rubygems_version = %q{1.3.5}
|
96
|
-
s.summary = %q{Agent XMPP is a ruby XMPP bot framework inspired by MVC web frameworks.}
|
97
|
-
s.test_files = [
|
20
|
+
".rvmrc",
|
21
|
+
"LICENSE",
|
22
|
+
"README.rdoc",
|
23
|
+
"Rakefile",
|
24
|
+
"VERSION",
|
25
|
+
"agent_xmpp.gemspec",
|
26
|
+
"default.gems",
|
27
|
+
"lib/agent_xmpp.rb",
|
28
|
+
"lib/agent_xmpp/admin.rb",
|
29
|
+
"lib/agent_xmpp/client.rb",
|
30
|
+
"lib/agent_xmpp/client/boot.rb",
|
31
|
+
"lib/agent_xmpp/client/client.rb",
|
32
|
+
"lib/agent_xmpp/client/connection.rb",
|
33
|
+
"lib/agent_xmpp/client/controller.rb",
|
34
|
+
"lib/agent_xmpp/client/message_delegate.rb",
|
35
|
+
"lib/agent_xmpp/client/message_pipe.rb",
|
36
|
+
"lib/agent_xmpp/client/response.rb",
|
37
|
+
"lib/agent_xmpp/config.rb",
|
38
|
+
"lib/agent_xmpp/main.rb",
|
39
|
+
"lib/agent_xmpp/models.rb",
|
40
|
+
"lib/agent_xmpp/models/contact.rb",
|
41
|
+
"lib/agent_xmpp/models/message.rb",
|
42
|
+
"lib/agent_xmpp/models/publication.rb",
|
43
|
+
"lib/agent_xmpp/models/roster.rb",
|
44
|
+
"lib/agent_xmpp/models/service.rb",
|
45
|
+
"lib/agent_xmpp/models/subscription.rb",
|
46
|
+
"lib/agent_xmpp/models/table_definitions.rb",
|
47
|
+
"lib/agent_xmpp/patches.rb",
|
48
|
+
"lib/agent_xmpp/patches/array.rb",
|
49
|
+
"lib/agent_xmpp/patches/float.rb",
|
50
|
+
"lib/agent_xmpp/patches/hash.rb",
|
51
|
+
"lib/agent_xmpp/patches/object.rb",
|
52
|
+
"lib/agent_xmpp/patches/rexml.rb",
|
53
|
+
"lib/agent_xmpp/patches/string.rb",
|
54
|
+
"lib/agent_xmpp/xmpp.rb",
|
55
|
+
"lib/agent_xmpp/xmpp/element.rb",
|
56
|
+
"lib/agent_xmpp/xmpp/entry.rb",
|
57
|
+
"lib/agent_xmpp/xmpp/error_response.rb",
|
58
|
+
"lib/agent_xmpp/xmpp/iq.rb",
|
59
|
+
"lib/agent_xmpp/xmpp/iq_command.rb",
|
60
|
+
"lib/agent_xmpp/xmpp/iq_disco.rb",
|
61
|
+
"lib/agent_xmpp/xmpp/iq_pubsub.rb",
|
62
|
+
"lib/agent_xmpp/xmpp/iq_roster.rb",
|
63
|
+
"lib/agent_xmpp/xmpp/iq_version.rb",
|
64
|
+
"lib/agent_xmpp/xmpp/jid.rb",
|
65
|
+
"lib/agent_xmpp/xmpp/message.rb",
|
66
|
+
"lib/agent_xmpp/xmpp/presence.rb",
|
67
|
+
"lib/agent_xmpp/xmpp/sasl.rb",
|
68
|
+
"lib/agent_xmpp/xmpp/stanza.rb",
|
69
|
+
"lib/agent_xmpp/xmpp/x_data.rb",
|
98
70
|
"test/app/app.rb",
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
71
|
+
"test/cases/test_application_message_processing.rb",
|
72
|
+
"test/cases/test_errors.rb",
|
73
|
+
"test/cases/test_presence_management.rb",
|
74
|
+
"test/cases/test_roster_management.rb",
|
75
|
+
"test/cases/test_service_discovery.rb",
|
76
|
+
"test/cases/test_session_management.rb",
|
77
|
+
"test/cases/test_version_discovery.rb",
|
78
|
+
"test/helpers/matchers.rb",
|
79
|
+
"test/helpers/mocks.rb",
|
80
|
+
"test/helpers/test_case_extensions.rb",
|
81
|
+
"test/helpers/test_client.rb",
|
82
|
+
"test/helpers/test_delegate.rb",
|
83
|
+
"test/helpers/test_helper.rb",
|
84
|
+
"test/messages/application_messages.rb",
|
85
|
+
"test/messages/error_messages.rb",
|
86
|
+
"test/messages/presence_messages.rb",
|
87
|
+
"test/messages/roster_messages.rb",
|
88
|
+
"test/messages/service_discovery_messages.rb",
|
89
|
+
"test/messages/session_messages.rb",
|
90
|
+
"test/messages/version_discovery_messages.rb",
|
91
|
+
"test/peer/peer.rb"
|
120
92
|
]
|
93
|
+
s.homepage = %q{http://github.com/troystribling/agent_xmpp}
|
94
|
+
s.require_paths = [%q{lib}]
|
95
|
+
s.rubygems_version = %q{1.8.4}
|
96
|
+
s.summary = %q{Agent XMPP is a ruby XMPP bot framework inspired by web frameworks.}
|
121
97
|
|
122
98
|
if s.respond_to? :specification_version then
|
123
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
124
99
|
s.specification_version = 3
|
125
100
|
|
126
|
-
if Gem::Version.new(Gem::
|
101
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
127
102
|
s.add_runtime_dependency(%q<rake>, [">= 0.8.3"])
|
128
103
|
s.add_runtime_dependency(%q<eventmachine>, [">= 0.12.6"])
|
129
104
|
s.add_runtime_dependency(%q<sequel>, [">= 3.9.0"])
|
130
105
|
s.add_runtime_dependency(%q<evma_xmlpushparser>, [">= 0.0.1"])
|
106
|
+
s.add_runtime_dependency(%q<sqlite3>, [">= 1.3.3"])
|
131
107
|
else
|
132
108
|
s.add_dependency(%q<rake>, [">= 0.8.3"])
|
133
109
|
s.add_dependency(%q<eventmachine>, [">= 0.12.6"])
|
134
110
|
s.add_dependency(%q<sequel>, [">= 3.9.0"])
|
135
111
|
s.add_dependency(%q<evma_xmlpushparser>, [">= 0.0.1"])
|
112
|
+
s.add_dependency(%q<sqlite3>, [">= 1.3.3"])
|
136
113
|
end
|
137
114
|
else
|
138
115
|
s.add_dependency(%q<rake>, [">= 0.8.3"])
|
139
116
|
s.add_dependency(%q<eventmachine>, [">= 0.12.6"])
|
140
117
|
s.add_dependency(%q<sequel>, [">= 3.9.0"])
|
141
118
|
s.add_dependency(%q<evma_xmlpushparser>, [">= 0.0.1"])
|
119
|
+
s.add_dependency(%q<sqlite3>, [">= 1.3.3"])
|
142
120
|
end
|
143
121
|
end
|
144
122
|
|
data/default.gems
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# default.gems generated gem export file. Note that any env variable settings will be missing. Append these after using a ';' field separator
|
2
|
+
agent_xmpp -v0.1.0
|
3
|
+
bundler -v1.0.15
|
4
|
+
eventmachine -v0.12.10
|
5
|
+
evma_xmlpushparser -v0.0.1
|
6
|
+
git -v1.2.5
|
7
|
+
jeweler -v1.6.2
|
8
|
+
rake -v0.8.7
|
9
|
+
sequel -v3.24.1
|
data/lib/agent_xmpp.rb
CHANGED
data/lib/agent_xmpp/admin.rb
CHANGED
@@ -20,7 +20,7 @@ command 'admin/contacts', :access => 'admin' do
|
|
20
20
|
end
|
21
21
|
|
22
22
|
#.........................................................................................................
|
23
|
-
command 'admin/
|
23
|
+
command 'admin/online_users', :access => 'admin' do
|
24
24
|
AgentXmpp.logger.info "ACTION: admin/on_line_users"
|
25
25
|
AgentXmpp::Roster.find_all_by_status(:available).map do |r|
|
26
26
|
jid = AgentXmpp::Xmpp::Jid.new(r[:jid])
|
@@ -464,6 +464,8 @@ module AgentXmpp
|
|
464
464
|
req = [Xmpp::IqPubSub.subscriptions(pipe, jid.to_s)]
|
465
465
|
if /#{AgentXmpp.jid.domain}/.match(jid.to_s)
|
466
466
|
add_publish_methods(pipe, jid)
|
467
|
+
add_publish_method(pipe, jid)
|
468
|
+
add_create_pubsub_node(pipe, jid)
|
467
469
|
@pubsub_service = jid
|
468
470
|
req += [Xmpp::IqDiscoItems.get(pipe, jid.to_s)] + init_remote_services(pipe)
|
469
471
|
end; req
|
@@ -646,7 +648,29 @@ module AgentXmpp
|
|
646
648
|
end
|
647
649
|
end
|
648
650
|
end
|
649
|
-
|
651
|
+
|
652
|
+
#.........................................................................................................
|
653
|
+
def add_publish_method(pipe, pubsub)
|
654
|
+
unless AgentXmpp.respond_to?(:publish)
|
655
|
+
AgentXmpp.define_meta_class_method(:publish) do |node, payload|
|
656
|
+
pipe.send_resp(Xmpp::IqPublish.set(pipe, :node => node, :to => pubsub, :payload => payload.to_x_data))
|
657
|
+
end
|
658
|
+
AgentXmpp.logger.info "ADDED PUBLISH METHOD FOR: #{pubsub}"
|
659
|
+
Delegator.delegate(AgentXmpp, :publish)
|
660
|
+
end
|
661
|
+
end
|
662
|
+
|
663
|
+
#.........................................................................................................
|
664
|
+
def add_create_pubsub_node(pipe, pubsub)
|
665
|
+
unless AgentXmpp.respond_to?(:create_pubsub_node)
|
666
|
+
AgentXmpp.define_meta_class_method(:create_pubsub_node) do |node|
|
667
|
+
pipe.send_resp(Xmpp::IqPubSub.create_node(pipe, pubsub, node))
|
668
|
+
end
|
669
|
+
AgentXmpp.logger.info "ADDED CREATE_PUBSUB_NODE FOR: #{pubsub}"
|
670
|
+
Delegator.delegate(AgentXmpp, :create_pubsub_node)
|
671
|
+
end
|
672
|
+
end
|
673
|
+
|
650
674
|
#.........................................................................................................
|
651
675
|
def add_send_command_request_method(pipe)
|
652
676
|
AgentXmpp.define_meta_class_method(:send_command_request) do |args, &blk|
|
@@ -707,7 +731,7 @@ module AgentXmpp
|
|
707
731
|
|
708
732
|
#.........................................................................................................
|
709
733
|
private :init_remote_services, :update_publish_nodes, :create_user_pubsub_root, :add_send_chat_method,
|
710
|
-
:add_send_command_request_method, :add_publish_methods, :process_roster_items, :process_pubsub_discoinfo,
|
734
|
+
:add_send_command_request_method, :add_publish_methods, :add_publish_method, :add_create_pubsub_node, :process_roster_items, :process_pubsub_discoinfo,
|
711
735
|
:check_roster_item_group
|
712
736
|
|
713
737
|
#### self
|
data/lib/agent_xmpp/config.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module AgentXmpp
|
2
2
|
|
3
3
|
#.........................................................................................................
|
4
|
-
VERSION = "0.1.
|
4
|
+
VERSION = "0.1.1"
|
5
5
|
AGENT_XMPP_NAME = 'AgentXMPP'
|
6
6
|
OS_VERSION = IO.popen('uname -sr').readlines.first.to_s.strip
|
7
7
|
SUBSCRIBE_RETRY_PERIOD = 60
|
data/lib/agent_xmpp/main.rb
CHANGED
@@ -15,14 +15,22 @@ end
|
|
15
15
|
module AgentXmpp
|
16
16
|
|
17
17
|
#...........................................................................................................
|
18
|
+
@settings = {}
|
18
19
|
@config = {}
|
19
20
|
|
20
21
|
#####-------------------------------------------------------------------------------------------------------
|
21
22
|
class << self
|
22
23
|
|
23
24
|
#.........................................................................................................
|
24
|
-
attr_accessor :config
|
25
|
+
attr_accessor :config, :settings
|
25
26
|
|
27
|
+
#####.....................................................................................................
|
28
|
+
# settings
|
29
|
+
#.........................................................................................................
|
30
|
+
def set(key, value)
|
31
|
+
@settings[key] = value
|
32
|
+
end
|
33
|
+
|
26
34
|
#####.....................................................................................................
|
27
35
|
# database
|
28
36
|
#.........................................................................................................
|
@@ -32,7 +40,11 @@ module AgentXmpp
|
|
32
40
|
|
33
41
|
#.........................................................................................................
|
34
42
|
def agent_xmpp_db
|
35
|
-
@agent_xmpp_db ||=
|
43
|
+
@agent_xmpp_db ||= if settings[:agent_xmpp_db_adapter]
|
44
|
+
settings[:agent_xmpp_db_adapter].call
|
45
|
+
else
|
46
|
+
Sequel.sqlite("#{AgentXmpp.app_path}/agent_xmpp.db")
|
47
|
+
end
|
36
48
|
end
|
37
49
|
|
38
50
|
#.........................................................................................................
|
@@ -156,6 +168,7 @@ module AgentXmpp
|
|
156
168
|
#### self
|
157
169
|
end
|
158
170
|
|
171
|
+
delegate AgentXmpp, :set
|
159
172
|
delegate AgentXmpp::BaseController, :command, :chat, :event, :before, :include_module
|
160
173
|
delegate AgentXmpp::Boot, :before_start, :after_connected, :restarting_client, :discovered_pubsub_node,
|
161
174
|
:discovered_command_nodes, :received_presence
|
metadata
CHANGED
@@ -1,74 +1,87 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: agent_xmpp
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
|
-
authors:
|
7
|
+
authors:
|
7
8
|
- Troy Stribling
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
dependencies:
|
15
|
-
- !ruby/object:Gem::Dependency
|
12
|
+
date: 2011-06-12 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
16
15
|
name: rake
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
- !ruby/object:Gem::Version
|
16
|
+
requirement: &2152765720 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
23
21
|
version: 0.8.3
|
24
|
-
version:
|
25
|
-
- !ruby/object:Gem::Dependency
|
26
|
-
name: eventmachine
|
27
22
|
type: :runtime
|
28
|
-
|
29
|
-
version_requirements:
|
30
|
-
|
31
|
-
|
32
|
-
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2152765720
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: eventmachine
|
27
|
+
requirement: &2152765240 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
33
32
|
version: 0.12.6
|
34
|
-
version:
|
35
|
-
- !ruby/object:Gem::Dependency
|
36
|
-
name: sequel
|
37
33
|
type: :runtime
|
38
|
-
|
39
|
-
version_requirements:
|
40
|
-
|
41
|
-
|
42
|
-
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *2152765240
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: sequel
|
38
|
+
requirement: &2152764760 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
43
|
version: 3.9.0
|
44
|
-
version:
|
45
|
-
- !ruby/object:Gem::Dependency
|
46
|
-
name: evma_xmlpushparser
|
47
44
|
type: :runtime
|
48
|
-
|
49
|
-
version_requirements:
|
50
|
-
|
51
|
-
|
52
|
-
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *2152764760
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: evma_xmlpushparser
|
49
|
+
requirement: &2152764280 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
53
54
|
version: 0.0.1
|
54
|
-
|
55
|
+
type: :runtime
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *2152764280
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: sqlite3
|
60
|
+
requirement: &2152763800 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 1.3.3
|
66
|
+
type: :runtime
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *2152763800
|
55
69
|
description:
|
56
70
|
email: troy.stribling@gmail.com
|
57
71
|
executables: []
|
58
|
-
|
59
72
|
extensions: []
|
60
|
-
|
61
|
-
extra_rdoc_files:
|
73
|
+
extra_rdoc_files:
|
62
74
|
- LICENSE
|
63
75
|
- README.rdoc
|
64
|
-
files:
|
76
|
+
files:
|
65
77
|
- .document
|
66
|
-
- .
|
78
|
+
- .rvmrc
|
67
79
|
- LICENSE
|
68
80
|
- README.rdoc
|
69
81
|
- Rakefile
|
70
82
|
- VERSION
|
71
83
|
- agent_xmpp.gemspec
|
84
|
+
- default.gems
|
72
85
|
- lib/agent_xmpp.rb
|
73
86
|
- lib/agent_xmpp/admin.rb
|
74
87
|
- lib/agent_xmpp/client.rb
|
@@ -134,54 +147,28 @@ files:
|
|
134
147
|
- test/messages/session_messages.rb
|
135
148
|
- test/messages/version_discovery_messages.rb
|
136
149
|
- test/peer/peer.rb
|
137
|
-
has_rdoc: true
|
138
150
|
homepage: http://github.com/troystribling/agent_xmpp
|
139
151
|
licenses: []
|
140
|
-
|
141
152
|
post_install_message:
|
142
|
-
rdoc_options:
|
143
|
-
|
144
|
-
require_paths:
|
153
|
+
rdoc_options: []
|
154
|
+
require_paths:
|
145
155
|
- lib
|
146
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
156
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
157
|
+
none: false
|
158
|
+
requirements:
|
159
|
+
- - ! '>='
|
160
|
+
- !ruby/object:Gem::Version
|
161
|
+
version: '0'
|
162
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
163
|
+
none: false
|
164
|
+
requirements:
|
165
|
+
- - ! '>='
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '0'
|
158
168
|
requirements: []
|
159
|
-
|
160
169
|
rubyforge_project:
|
161
|
-
rubygems_version: 1.
|
170
|
+
rubygems_version: 1.8.5
|
162
171
|
signing_key:
|
163
172
|
specification_version: 3
|
164
|
-
summary: Agent XMPP is a ruby XMPP bot framework inspired by
|
165
|
-
test_files:
|
166
|
-
- test/app/app.rb
|
167
|
-
- test/cases/test_application_message_processing.rb
|
168
|
-
- test/cases/test_errors.rb
|
169
|
-
- test/cases/test_presence_management.rb
|
170
|
-
- test/cases/test_roster_management.rb
|
171
|
-
- test/cases/test_service_discovery.rb
|
172
|
-
- test/cases/test_session_management.rb
|
173
|
-
- test/cases/test_version_discovery.rb
|
174
|
-
- test/helpers/matchers.rb
|
175
|
-
- test/helpers/mocks.rb
|
176
|
-
- test/helpers/test_case_extensions.rb
|
177
|
-
- test/helpers/test_client.rb
|
178
|
-
- test/helpers/test_delegate.rb
|
179
|
-
- test/helpers/test_helper.rb
|
180
|
-
- test/messages/application_messages.rb
|
181
|
-
- test/messages/error_messages.rb
|
182
|
-
- test/messages/presence_messages.rb
|
183
|
-
- test/messages/roster_messages.rb
|
184
|
-
- test/messages/service_discovery_messages.rb
|
185
|
-
- test/messages/session_messages.rb
|
186
|
-
- test/messages/version_discovery_messages.rb
|
187
|
-
- test/peer/peer.rb
|
173
|
+
summary: Agent XMPP is a ruby XMPP bot framework inspired by web frameworks.
|
174
|
+
test_files: []
|