blather 0.7.0 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +20 -13
- data/README.md +337 -94
- data/blather.gemspec +2 -2
- data/lib/blather/errors/stream_error.rb +2 -1
- data/lib/blather/roster_item.rb +5 -5
- data/lib/blather/stanza.rb +10 -0
- data/lib/blather/stanza/iq/roster.rb +7 -1
- data/lib/blather/stanza/pubsub/create.rb +1 -1
- data/lib/blather/stanza/x.rb +8 -6
- data/lib/blather/stream.rb +5 -5
- data/lib/blather/version.rb +1 -1
- data/lib/blather/xmpp_node.rb +2 -0
- data/spec/blather/stanza/presence_spec.rb +7 -0
- data/spec/blather/stanza/x_spec.rb +6 -5
- metadata +91 -31
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,13 @@
|
|
1
|
-
# develop
|
1
|
+
# [develop](https://github.com/sprsquish/blather/compare/master...develop)
|
2
2
|
|
3
|
-
# v0.7.0
|
3
|
+
# [v0.7.1](https://github.com/sprsquish/blather/compare/v0.7.0...v0.7.1) - [2012-04-29](https://rubygems.org/gems/blather/versions/0.7.1)
|
4
|
+
* Documentation updates
|
5
|
+
* Bugfix(benlangfeld): Relax Nokogiri dependency to allow 1.5
|
6
|
+
* Bugfix(benlangfeld): Fix some nokogiri 1.5 related bugs on JRuby (some remain)
|
7
|
+
* Bugfix(benlangfeld): Set namespaces correctly on some tricky nodes
|
8
|
+
* Bugfix(benlangfeld): Ensure all presence sub-types trigger the correct handlers
|
9
|
+
|
10
|
+
# [v0.7.0](https://github.com/sprsquish/blather/compare/v0.6.2...v0.7.0) - [2012-03-15](https://rubygems.org/gems/blather/versions/0.7.0)
|
4
11
|
* Change(benlangfeld): Drop Ruby 1.8.7 compatability
|
5
12
|
* Change(bklang): Remove the wire log, which duplicated the parsed logging
|
6
13
|
* Feature(benlangfeld): Stanza handlers are now executed outside of the EM reactor, so it is not blocked on stanza processing
|
@@ -10,34 +17,34 @@
|
|
10
17
|
* Bugfix(benlangfeld): Presence stanzas are now composed on import, including all children
|
11
18
|
* Bugfix(mtrudel): JIDs in roster item stanzas are now stripped of resources
|
12
19
|
|
13
|
-
# v0.6.2
|
14
|
-
* Feature(benlangfeld): Add password support to MUCUser
|
15
|
-
* Feature(benlangfeld): Add support for invitation elements to MUCUser messages
|
20
|
+
# [v0.6.2](https://github.com/sprsquish/blather/compare/v0.6.1...v0.6.2) - [2012-02-28](https://rubygems.org/gems/blather/versions/0.6.2)
|
21
|
+
* Feature(benlangfeld): Add password support to `MUCUser`
|
22
|
+
* Feature(benlangfeld): Add support for invitation elements to `MUCUser` messages
|
16
23
|
* Feature(benlangfeld): Add support for MUC invite declines
|
17
24
|
* Bugfix(benlangfeld): Don't implicitly create an invite node when checking invite status
|
18
25
|
* Bugfix(benlangfeld): Ensure that form nodes are not duplicated on muc/muc_user presence stanzas
|
19
26
|
|
20
|
-
# v0.6.1
|
27
|
+
# [v0.6.1](https://github.com/sprsquish/blather/compare/v0.6.0...v0.6.1) - [2012-02-25](https://rubygems.org/gems/blather/versions/0.6.1)
|
21
28
|
* Bugfix(benlangfeld): Ensure MUC presence nodes (joining) have a form element on creation
|
22
29
|
|
23
|
-
# v0.6.0
|
30
|
+
# [v0.6.0](https://github.com/sprsquish/blather/compare/v0.5.12...v0.6.0) - [2012-02-24](https://rubygems.org/gems/blather/versions/0.6.0)
|
24
31
|
* Feature(benlangfeld): Very basic MUC and delayed message support
|
25
32
|
* Bugfix(theozaurus): Disable connection timeout timer if client deliberately disconnects
|
26
|
-
* Bugfix(mtrudel): Fix Roster#each to return roster_items as per documentation
|
33
|
+
* Bugfix(mtrudel): Fix `Roster#each` to return roster_items as per documentation
|
27
34
|
|
28
|
-
# v0.5.12
|
35
|
+
# [v0.5.12](https://github.com/sprsquish/blather/compare/v0.5.11...v0.5.12) - [2012-01-06](https://rubygems.org/gems/blather/versions/0.5.12)
|
29
36
|
* Bugfix(benlangfeld): Allow specifying the connection timeout in DSL setup
|
30
37
|
|
31
|
-
# v0.5.11
|
38
|
+
# [v0.5.11](https://github.com/sprsquish/blather/compare/v0.5.10...v0.5.11) - [2012-01-06](https://rubygems.org/gems/blather/versions/0.5.11)
|
32
39
|
* Feature(benlangfeld): Allow specifying a connection timeout
|
33
|
-
* Raise Blather::Stream::ConnectionTimeout if timeout is exceeded
|
40
|
+
* Raise `Blather::Stream::ConnectionTimeout` if timeout is exceeded
|
34
41
|
* Default to 180 seconds
|
35
42
|
|
36
|
-
# v0.5.10
|
43
|
+
# [v0.5.10](https://github.com/sprsquish/blather/compare/v0.5.9...v0.5.10) - [2011-12-02](https://rubygems.org/gems/blather/versions/0.5.10)
|
37
44
|
* Feature(juandebravo): Allow configuring the wire log level
|
38
45
|
* Bugfix(benlangfeld): Checking connection status before the stream is established
|
39
46
|
|
40
|
-
# v0.5.9
|
47
|
+
# [v0.5.9](https://github.com/sprsquish/blather/compare/v0.5.8...v0.5.9) - [2011-11-24](https://rubygems.org/gems/blather/versions/0.5.9)
|
41
48
|
* Bugfix(benlangfeld): Failed connections now raise a Blather::Stream::ConnectionFailed exception
|
42
49
|
* Bugfix(crohr): Blather now supports EventMachine 1.0
|
43
50
|
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Blather [ ![Build status](http://travis-ci.org/sprsquish/blather.png) ](http://travis-ci.org/sprsquish/blather)
|
2
2
|
|
3
|
-
XMPP DSL (and more) for Ruby written on EventMachine and Nokogiri.
|
3
|
+
XMPP DSL (and more) for Ruby written on [EventMachine](http://rubyeventmachine.com/) and [Nokogiri](http://nokogiri.org/).
|
4
4
|
|
5
5
|
## Features
|
6
6
|
|
@@ -10,9 +10,9 @@ XMPP DSL (and more) for Ruby written on EventMachine and Nokogiri.
|
|
10
10
|
|
11
11
|
## Project Pages
|
12
12
|
|
13
|
-
* [Docs](http://blather.squishtech.com)
|
14
13
|
* [GitHub](https://github.com/sprsquish/blather)
|
15
14
|
* [Gemcutter](http://gemcutter.org/gems/blather)
|
15
|
+
* [API Documentation](http://rdoc.info/gems/blather/file/README.md)
|
16
16
|
* [Google Group](http://groups.google.com/group/xmpp-blather)
|
17
17
|
|
18
18
|
# Usage
|
@@ -23,99 +23,138 @@ XMPP DSL (and more) for Ruby written on EventMachine and Nokogiri.
|
|
23
23
|
|
24
24
|
## Example
|
25
25
|
|
26
|
-
See the examples directory for more advanced examples.
|
26
|
+
Blather comes with a DSL that makes writing XMPP bots quick and easy. See the examples directory for more advanced examples.
|
27
27
|
|
28
|
-
|
28
|
+
```ruby
|
29
|
+
require 'rubygems'
|
30
|
+
require 'blather/client'
|
29
31
|
|
30
|
-
|
31
|
-
require 'blather/client'
|
32
|
+
setup 'echo@jabber.local', 'echo'
|
32
33
|
|
33
|
-
|
34
|
+
# Auto approve subscription requests
|
35
|
+
subscription :request? do |s|
|
36
|
+
write_to_stream s.approve!
|
37
|
+
end
|
34
38
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
# Echo back what was said
|
41
|
-
message :chat?, :body do |m|
|
42
|
-
write_to_stream m.reply
|
43
|
-
end
|
39
|
+
# Echo back what was said
|
40
|
+
message :chat?, :body do |m|
|
41
|
+
write_to_stream m.reply
|
42
|
+
end
|
43
|
+
```
|
44
44
|
|
45
45
|
## Handlers
|
46
46
|
|
47
|
-
|
47
|
+
Handlers let Blather know how you'd like each type of stanza to be well.. handled. Each type of stanza has an associated handler which is part of a handler hierarchy. In the example above we're handling message and subscription stanzas.
|
48
|
+
|
49
|
+
XMPP is built on top of three main stanza types (presence, message, and iq). All other stanzas are built on these three base types. This creates a natural hierarchy of handlers. For example a subscription stanza is a type of presence stanza and can be processed by a subscription handler or a presence handler. Likewise, a PubSub::Items stanza has its own identifier :pubsub_items but it's also a :pubsub_node, :iq and :staza. Any or each of these could be used to handle the PubSub::Items stanza. If you've done any DOM programming you'll be familiar with this.
|
50
|
+
|
51
|
+
Incoming stanzas will be handled by the first handler found. Unlike the DOM this will stop the handling bubble unless the handler returns false.
|
52
|
+
|
53
|
+
The entire handler hierarchy can be seen below.
|
54
|
+
|
55
|
+
### Example
|
56
|
+
|
57
|
+
Here we have a presence handler and a subscription handler. When this script receives a subscription stanza the subscription handler will be notified first. If that handler doesn't know what to do it can return false and let the stanza bubble up to the presence handler.
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
# Handle all presence stanzas
|
61
|
+
presence do |stanza|
|
62
|
+
# do stuff
|
63
|
+
end
|
64
|
+
|
65
|
+
# Handle all subscription stanzas
|
66
|
+
subscription do |stanza|
|
67
|
+
# do stuff
|
68
|
+
end
|
69
|
+
```
|
48
70
|
|
49
|
-
|
50
|
-
|
51
|
-
|
71
|
+
Additionally, handlers may be 'guarded'. That is, they may have conditions set declaratively, against which the stanza must match in order to trigger the handler.
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
# Will only be called for messages where #chat? responds positively
|
75
|
+
# and #body == 'exit'
|
76
|
+
message :chat?, :body => 'exit'
|
77
|
+
```
|
52
78
|
|
53
79
|
### Non-Stanza Handlers
|
54
80
|
|
55
81
|
So far there are two non-stanza related handlers.
|
56
82
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
83
|
+
```ruby
|
84
|
+
# Called after the connection has been connected. It's good for initializing
|
85
|
+
# your system.
|
86
|
+
# DSL:
|
87
|
+
when_ready {}
|
88
|
+
# Client:
|
89
|
+
client.register_handler(:ready) {}
|
90
|
+
|
91
|
+
# Called after the connection has been terminated. Good for teardown or
|
92
|
+
# automatic reconnection.
|
93
|
+
# DSL:
|
94
|
+
disconnected {}
|
95
|
+
# Client
|
96
|
+
client.register_handler(:disconnected) {}
|
97
|
+
# The following will reconnect every time the connection is lost:
|
98
|
+
disconnected { client.connect }
|
99
|
+
```
|
72
100
|
|
73
101
|
### Handler Guards
|
74
102
|
|
75
|
-
Guards
|
103
|
+
Guards are a concept borrowed from Erlang. They help to better compartmentalize handlers.
|
104
|
+
|
105
|
+
There are a number of guard types and one bit of special syntax. Guards act like AND statements. Each condition must be met if the handler is to
|
76
106
|
be used.
|
77
107
|
|
78
|
-
|
79
|
-
|
108
|
+
```ruby
|
109
|
+
# Equivalent to saying (stanza.chat? && stanza.body)
|
110
|
+
message :chat?, :body
|
111
|
+
```
|
80
112
|
|
81
113
|
The different types of guards are:
|
82
114
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
115
|
+
```ruby
|
116
|
+
# Symbol
|
117
|
+
# Checks for a non-false reply to calling the symbol on the stanza
|
118
|
+
# Equivalent to stanza.chat?
|
119
|
+
message :chat?
|
120
|
+
|
121
|
+
# Hash with any value (:body => 'exit')
|
122
|
+
# Calls the key on the stanza and checks for equality
|
123
|
+
# Equivalent to stanza.body == 'exit'
|
124
|
+
message :body => 'exit'
|
125
|
+
|
126
|
+
# Hash with regular expression (:body => /exit/)
|
127
|
+
# Calls the key on the stanza and checks for a match
|
128
|
+
# Equivalent to stanza.body.match /exit/
|
129
|
+
message :body => /exit/
|
130
|
+
|
131
|
+
# Hash with array (:name => [:gone, :forbidden])
|
132
|
+
# Calls the key on the stanza and check for inclusion in the array
|
133
|
+
# Equivalent to [:gone, :forbidden].include?(stanza.name)
|
134
|
+
stanza_error :name => [:gone, :fobidden]
|
135
|
+
|
136
|
+
# Proc
|
137
|
+
# Calls the proc passing in the stanza
|
138
|
+
# Checks that the ID is modulo 3
|
139
|
+
message proc { |m| m.id % 3 == 0 }
|
140
|
+
|
141
|
+
# Array
|
142
|
+
# Use arrays with the previous types effectively turns the guard into
|
143
|
+
# an OR statement.
|
144
|
+
# Equivalent to stanza.body == 'foo' || stanza.body == 'baz'
|
145
|
+
message [{:body => 'foo'}, {:body => 'baz'}]
|
146
|
+
|
147
|
+
# XPath
|
148
|
+
# Runs the xpath query on the stanza and checks for results
|
149
|
+
# This guard type cannot be combined with other guards
|
150
|
+
# Equivalent to !stanza.find('/iq/ns:pubsub', :ns => 'pubsub:namespace').empty?
|
151
|
+
# It also passes two arguments into the handler block: the stanza and the result
|
152
|
+
# of the xpath query.
|
153
|
+
iq '/iq/ns:pubsub', :ns => 'pubsub:namespace' do |stanza, xpath_result|
|
154
|
+
# stanza will be the original stanza
|
155
|
+
# xpath_result will be the pubsub node in the stanza
|
156
|
+
end
|
157
|
+
```
|
119
158
|
|
120
159
|
### Filters
|
121
160
|
|
@@ -123,37 +162,241 @@ Blather provides before and after filters that work much the way regular
|
|
123
162
|
handlers work. Filters come in a before and after flavor. They're called in
|
124
163
|
order of definition and can be guarded like handlers.
|
125
164
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
165
|
+
```ruby
|
166
|
+
before { |s| "I'm run before any handler" }
|
167
|
+
before { |s| "I'm run next" }
|
168
|
+
|
169
|
+
before(:message) { |s| "I'm only run in front of message stanzas" }
|
170
|
+
before(nil, :id => 1) { |s| "I'll only be run when the stanza's ID == 1" }
|
171
|
+
|
172
|
+
# ... handlers
|
173
|
+
|
174
|
+
after { |s| "I'm run after everything" }
|
175
|
+
```
|
176
|
+
|
177
|
+
### Handlers Hierarchy
|
178
|
+
|
179
|
+
```
|
180
|
+
stanza
|
181
|
+
|- iq
|
182
|
+
| |- pubsub_node
|
183
|
+
| | |- pubsub_affiliations
|
184
|
+
| | |- pubsub_create
|
185
|
+
| | |- pubsub_items
|
186
|
+
| | |- pubsub_publish
|
187
|
+
| | |- pubsub_retract
|
188
|
+
| | |- pubsub_subscribe
|
189
|
+
| | |- pubsub_subscription
|
190
|
+
| | |- pubsub_subscriptions
|
191
|
+
| | `- pubsub_unsubscribe
|
192
|
+
| |- pubsub_owner
|
193
|
+
| | |- pubsub_delete
|
194
|
+
| | `- pubsub_purge
|
195
|
+
| `- query
|
196
|
+
| |- disco_info
|
197
|
+
| |- disco_items
|
198
|
+
| `- roster
|
199
|
+
|- message
|
200
|
+
| `- pubsub_event
|
201
|
+
`- presence
|
202
|
+
|- status
|
203
|
+
`- subscription
|
204
|
+
|
205
|
+
error
|
206
|
+
|- argument_error
|
207
|
+
|- parse_error
|
208
|
+
|- sasl_error
|
209
|
+
|- sasl_unknown_mechanism
|
210
|
+
|- stanza_error
|
211
|
+
|- stream_error
|
212
|
+
|- tls_failure
|
213
|
+
`- unknown_response_error
|
214
|
+
```
|
215
|
+
|
216
|
+
## On the Command Line
|
137
217
|
|
138
218
|
Default usage is:
|
139
219
|
|
140
|
-
|
220
|
+
```
|
221
|
+
[blather_script] [options] node@domain.com/resource password [host] [port]
|
222
|
+
```
|
141
223
|
|
142
224
|
Command line options:
|
143
225
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
226
|
+
```
|
227
|
+
-D, --debug Run in debug mode (you will see all XMPP communication)
|
228
|
+
-d, --daemonize Daemonize the process
|
229
|
+
--pid=[PID] Write the PID to this file
|
230
|
+
--log=[LOG] Write to the [LOG] file instead of stdout/stderr
|
231
|
+
-h, --help Show this message
|
232
|
+
-v, --version Show version
|
233
|
+
```
|
150
234
|
|
151
|
-
## Health warning
|
235
|
+
## Health warning
|
152
236
|
|
153
237
|
Some parts of Blather will allow you to do stupid things that don't conform to XMPP
|
154
238
|
spec. You should exercise caution and read the relevant specifications (indicated in
|
155
239
|
the preamble to most relevant classes).
|
156
240
|
|
241
|
+
## Spec compliance
|
242
|
+
|
243
|
+
Blather provides support in one way or another for many XMPP specifications. Below is a list of specifications and the status of support for them in Blather. This list *may not be correct*. If the list indicates a lack of support for a specification you wish to use, you are encouraged to check that this is correct. Likewise, if you find an overstatement of Blather's spec compliance, please point this out. Also note that even without built-in support for a specification, you can still manually construct and parse stanzas alongside use of Blather's built-in helpers.
|
244
|
+
|
245
|
+
Specification | Support | Notes
|
246
|
+
------------- | ------- | -----
|
247
|
+
RFC 6120 | Full |
|
248
|
+
RFC 6121 | Full |
|
249
|
+
RFC 6122 | Full |
|
250
|
+
XEP-0001 | N/A |
|
251
|
+
XEP-0002 | N/A |
|
252
|
+
XEP-0004 | Partial |
|
253
|
+
XEP-0009 | None |
|
254
|
+
XEP-0012 | None |
|
255
|
+
XEP-0013 | None |
|
256
|
+
XEP-0016 | None |
|
257
|
+
XEP-0019 | N/A |
|
258
|
+
XEP-0020 | Partial |
|
259
|
+
XEP-0027 | None |
|
260
|
+
XEP-0030 | Partial |
|
261
|
+
XEP-0033 | None |
|
262
|
+
XEP-0045 | Partial |
|
263
|
+
XEP-0047 | None |
|
264
|
+
XEP-0048 | None |
|
265
|
+
XEP-0049 | None |
|
266
|
+
XEP-0050 | Partial |
|
267
|
+
XEP-0053 | None |
|
268
|
+
XEP-0054 | None |
|
269
|
+
XEP-0055 | None |
|
270
|
+
XEP-0059 | None |
|
271
|
+
XEP-0060 | Partial |
|
272
|
+
XEP-0065 | None |
|
273
|
+
XEP-0066 | None |
|
274
|
+
XEP-0068 | None |
|
275
|
+
XEP-0070 | None |
|
276
|
+
XEP-0071 | Partial |
|
277
|
+
XEP-0072 | None |
|
278
|
+
XEP-0076 | None |
|
279
|
+
XEP-0077 | None |
|
280
|
+
XEP-0079 | None |
|
281
|
+
XEP-0080 | None |
|
282
|
+
XEP-0082 | None |
|
283
|
+
XEP-0083 | None |
|
284
|
+
XEP-0084 | None |
|
285
|
+
XEP-0085 | Partial |
|
286
|
+
XEP-0092 | None |
|
287
|
+
XEP-0095 | Partial |
|
288
|
+
XEP-0096 | Partial |
|
289
|
+
XEP-0100 | None |
|
290
|
+
XEP-0106 | None |
|
291
|
+
XEP-0107 | None |
|
292
|
+
XEP-0108 | None |
|
293
|
+
XEP-0114 | None |
|
294
|
+
XEP-0115 | Partial |
|
295
|
+
XEP-0118 | None |
|
296
|
+
XEP-0122 | None |
|
297
|
+
XEP-0124 | None |
|
298
|
+
XEP-0126 | None |
|
299
|
+
XEP-0127 | None |
|
300
|
+
XEP-0128 | None |
|
301
|
+
XEP-0130 | None |
|
302
|
+
XEP-0131 | None |
|
303
|
+
XEP-0132 | None |
|
304
|
+
XEP-0133 | None |
|
305
|
+
XEP-0134 | None |
|
306
|
+
XEP-0136 | None |
|
307
|
+
XEP-0137 | None |
|
308
|
+
XEP-0138 | None |
|
309
|
+
XEP-0141 | None |
|
310
|
+
XEP-0143 | None |
|
311
|
+
XEP-0144 | N/A |
|
312
|
+
XEP-0145 | None |
|
313
|
+
XEP-0146 | None |
|
314
|
+
XEP-0147 | None |
|
315
|
+
XEP-0148 | None |
|
316
|
+
XEP-0149 | None |
|
317
|
+
XEP-0153 | None |
|
318
|
+
XEP-0155 | None |
|
319
|
+
XEP-0156 | None |
|
320
|
+
XEP-0157 | None |
|
321
|
+
XEP-0158 | None |
|
322
|
+
XEP-0160 | None |
|
323
|
+
XEP-0163 | Partial |
|
324
|
+
XEP-0166 | None |
|
325
|
+
XEP-0167 | None |
|
326
|
+
XEP-0169 | None |
|
327
|
+
XEP-0170 | None |
|
328
|
+
XEP-0171 | None |
|
329
|
+
XEP-0172 | None |
|
330
|
+
XEP-0174 | None |
|
331
|
+
XEP-0175 | None |
|
332
|
+
XEP-0176 | None |
|
333
|
+
XEP-0177 | None |
|
334
|
+
XEP-0178 | None |
|
335
|
+
XEP-0182 | N/A |
|
336
|
+
XEP-0183 | None |
|
337
|
+
XEP-0184 | None |
|
338
|
+
XEP-0185 | None |
|
339
|
+
XEP-0191 | None |
|
340
|
+
XEP-0198 | None |
|
341
|
+
XEP-0199 | Partial |
|
342
|
+
XEP-0201 | None |
|
343
|
+
XEP-0202 | None |
|
344
|
+
XEP-0203 | Partial |
|
345
|
+
XEP-0205 | None |
|
346
|
+
XEP-0206 | None |
|
347
|
+
XEP-0207 | None |
|
348
|
+
XEP-0220 | None |
|
349
|
+
XEP-0221 | None |
|
350
|
+
XEP-0222 | None |
|
351
|
+
XEP-0223 | None |
|
352
|
+
XEP-0224 | None |
|
353
|
+
XEP-0227 | None |
|
354
|
+
XEP-0229 | None |
|
355
|
+
XEP-0231 | None |
|
356
|
+
XEP-0233 | None |
|
357
|
+
XEP-0234 | None |
|
358
|
+
XEP-0239 | None |
|
359
|
+
XEP-0242 | None |
|
360
|
+
XEP-0243 | None |
|
361
|
+
XEP-0245 | None |
|
362
|
+
XEP-0249 | None |
|
363
|
+
XEP-0256 | None |
|
364
|
+
XEP-0258 | None |
|
365
|
+
XEP-0260 | None |
|
366
|
+
XEP-0261 | None |
|
367
|
+
XEP-0262 | None |
|
368
|
+
XEP-0263 | None |
|
369
|
+
XEP-0266 | None |
|
370
|
+
XEP-0267 | None |
|
371
|
+
XEP-0270 | None |
|
372
|
+
XEP-0273 | None |
|
373
|
+
XEP-0277 | None |
|
374
|
+
XEP-0278 | None |
|
375
|
+
XEP-0280 | None |
|
376
|
+
XEP-0288 | None |
|
377
|
+
XEP-0292 | None |
|
378
|
+
XEP-0293 | None |
|
379
|
+
XEP-0294 | None |
|
380
|
+
XEP-0295 | None |
|
381
|
+
XEP-0296 | None |
|
382
|
+
XEP-0297 | None |
|
383
|
+
XEP-0298 | None |
|
384
|
+
XEP-0299 | None |
|
385
|
+
XEP-0300 | None |
|
386
|
+
XEP-0301 | None |
|
387
|
+
XEP-0302 | None |
|
388
|
+
XEP-0303 | None |
|
389
|
+
XEP-0304 | None |
|
390
|
+
XEP-0305 | None |
|
391
|
+
XEP-0306 | None |
|
392
|
+
XEP-0307 | None |
|
393
|
+
XEP-0308 | None |
|
394
|
+
XEP-0309 | None |
|
395
|
+
XEP-0310 | None |
|
396
|
+
XEP-0311 | None |
|
397
|
+
XEP-0312 | None |
|
398
|
+
|
399
|
+
|
157
400
|
# Contributions
|
158
401
|
|
159
402
|
All contributions are welcome, even encouraged. However, contributions must be
|
@@ -167,4 +410,4 @@ than a change set made directly on master.
|
|
167
410
|
|
168
411
|
# Copyright
|
169
412
|
|
170
|
-
Copyright (c)
|
413
|
+
Copyright (c) 2012 Jeff Smick. See LICENSE for details.
|
data/blather.gemspec
CHANGED
@@ -34,8 +34,8 @@ Gem::Specification.new do |s|
|
|
34
34
|
s.extra_rdoc_files = %w{LICENSE README.md}
|
35
35
|
|
36
36
|
s.add_dependency "eventmachine", [">= 0.12.6"]
|
37
|
-
s.add_dependency "nokogiri", ["~> 1.4
|
38
|
-
s.add_dependency "niceogiri", ["~> 1.0
|
37
|
+
s.add_dependency "nokogiri", ["~> 1.4"]
|
38
|
+
s.add_dependency "niceogiri", ["~> 1.0"]
|
39
39
|
s.add_dependency "activesupport", [">= 3.0.7"]
|
40
40
|
s.add_dependency "girl_friday"
|
41
41
|
|
@@ -50,7 +50,8 @@ class StreamError < BlatherError
|
|
50
50
|
#
|
51
51
|
# @return [Blather::XMPPNode]
|
52
52
|
def to_node
|
53
|
-
node = XMPPNode.new('
|
53
|
+
node = XMPPNode.new('error')
|
54
|
+
node.namespace = {'stream' => Blather::Stream::STREAM_NS}
|
54
55
|
|
55
56
|
node << (err = XMPPNode.new(@name, node.document))
|
56
57
|
err.namespace = 'urn:ietf:params:xml:ns:xmpp-streams'
|
data/lib/blather/roster_item.rb
CHANGED
@@ -113,11 +113,11 @@ module Blather
|
|
113
113
|
#
|
114
114
|
# @return [Blather::Stanza::Iq::Roster]
|
115
115
|
def to_stanza(type = nil)
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
116
|
+
Stanza::Iq::Roster.new type, to_node
|
117
|
+
end
|
118
|
+
|
119
|
+
def to_node
|
120
|
+
Stanza::Iq::Roster::RosterItem.new jid, name, subscription, ask, groups
|
121
121
|
end
|
122
122
|
|
123
123
|
# Compare two RosterItems by their JID
|
data/lib/blather/stanza.rb
CHANGED
@@ -13,6 +13,7 @@ module Blather
|
|
13
13
|
@@handler_list = []
|
14
14
|
|
15
15
|
class_attribute :handler_hierarchy
|
16
|
+
attr_writer :handler_hierarchy
|
16
17
|
|
17
18
|
# Registers a callback onto the callback stack
|
18
19
|
#
|
@@ -30,6 +31,15 @@ module Blather
|
|
30
31
|
super name, ns
|
31
32
|
end
|
32
33
|
|
34
|
+
def initialize(*args)
|
35
|
+
super
|
36
|
+
@handler_hierarchy = []
|
37
|
+
end
|
38
|
+
|
39
|
+
def handler_hierarchy
|
40
|
+
@handler_hierarchy + self.class.handler_hierarchy
|
41
|
+
end
|
42
|
+
|
33
43
|
# The handler stack for the current stanza class
|
34
44
|
#
|
35
45
|
# @return [Array<Symbol>]
|
@@ -48,6 +48,8 @@ class Iq
|
|
48
48
|
# This is a convenience class to attach methods to the node
|
49
49
|
class RosterItem < XMPPNode
|
50
50
|
|
51
|
+
register :item, Roster.registered_ns
|
52
|
+
|
51
53
|
# Create a new RosterItem
|
52
54
|
# @overload new(XML::Node)
|
53
55
|
# Create a RosterItem by inheriting a node
|
@@ -61,6 +63,7 @@ class Iq
|
|
61
63
|
# the RosterItem must be one of
|
62
64
|
# Blather::RosterItem::VALID_SUBSCRIPTION_TYPES
|
63
65
|
# @option opts [:subscribe, nil] :ask the ask value of the RosterItem
|
66
|
+
# @option opts [Array<#to_s>] :groups the group names the RosterItem is a member of
|
64
67
|
# @overload new(jid = nil, name = nil, subscription = nil, ask = nil)
|
65
68
|
# @param [Blather::JID, String, nil] jid the JID of the item
|
66
69
|
# @param [String, nil] name the alias to give the JID
|
@@ -68,7 +71,8 @@ class Iq
|
|
68
71
|
# RosterItem must be one of
|
69
72
|
# Blather::RosterItem::VALID_SUBSCRIPTION_TYPES
|
70
73
|
# @param [:subscribe, nil] ask the ask value of the RosterItem
|
71
|
-
|
74
|
+
# @param [Array<#to_s>] groups the group names the RosterItem is a member of
|
75
|
+
def self.new(jid = nil, name = nil, subscription = nil, ask = nil, groups = nil)
|
72
76
|
new_node = super :item
|
73
77
|
|
74
78
|
case jid
|
@@ -79,11 +83,13 @@ class Iq
|
|
79
83
|
new_node.name = jid[:name]
|
80
84
|
new_node.subscription = jid[:subscription]
|
81
85
|
new_node.ask = jid[:ask]
|
86
|
+
new_node.groups = jid[:groups]
|
82
87
|
else
|
83
88
|
new_node.jid = jid
|
84
89
|
new_node.name = name
|
85
90
|
new_node.subscription = subscription
|
86
91
|
new_node.ask = ask
|
92
|
+
new_node.groups = groups
|
87
93
|
end
|
88
94
|
new_node
|
89
95
|
end
|
@@ -39,7 +39,7 @@ class PubSub
|
|
39
39
|
|
40
40
|
# Get or create the actual create node on the stanza
|
41
41
|
#
|
42
|
-
# @return [
|
42
|
+
# @return [Blather::XMPPNode]
|
43
43
|
def create_node
|
44
44
|
unless create_node = pubsub.find_first('ns:create', :ns => self.class.registered_ns)
|
45
45
|
self.pubsub << (create_node = XMPPNode.new('create', self.document))
|
data/lib/blather/stanza/x.rb
CHANGED
@@ -300,10 +300,10 @@ class Stanza
|
|
300
300
|
#
|
301
301
|
# @param [true, false]
|
302
302
|
def required?
|
303
|
-
if self.namespace
|
304
|
-
|
303
|
+
!!if self.namespace
|
304
|
+
self.find_first 'ns:required', :ns => self.namespace.href
|
305
305
|
else
|
306
|
-
|
306
|
+
self.find_first 'required'
|
307
307
|
end
|
308
308
|
end
|
309
309
|
|
@@ -311,8 +311,10 @@ class Stanza
|
|
311
311
|
#
|
312
312
|
# @param [true, false] required the field's required flag
|
313
313
|
def required=(required)
|
314
|
-
self.remove_children(:required) unless required
|
315
|
-
|
314
|
+
return self.remove_children(:required) unless required
|
315
|
+
|
316
|
+
self << (r = XMPPNode.new(:required))
|
317
|
+
r.namespace = self.namespace
|
316
318
|
end
|
317
319
|
|
318
320
|
# Extract list of option objects
|
@@ -331,7 +333,7 @@ class Stanza
|
|
331
333
|
def options=(options)
|
332
334
|
remove_children :option
|
333
335
|
if options
|
334
|
-
|
336
|
+
Array(options).each { |o| self << Option.new(o) }
|
335
337
|
end
|
336
338
|
end
|
337
339
|
|
data/lib/blather/stream.rb
CHANGED
@@ -69,7 +69,7 @@ module Blather
|
|
69
69
|
# to use the domain on the JID
|
70
70
|
# @param [Fixnum, nil] port the port to connect on. Default is the XMPP
|
71
71
|
# default of 5222
|
72
|
-
# @param [String, nil] certs the trusted cert store in pem format to verify
|
72
|
+
# @param [String, nil] certs the trusted cert store in pem format to verify
|
73
73
|
# communication with the server is trusted.
|
74
74
|
# @param [Fixnum, nil] connect_timeout the number of seconds for which to wait for a successful connection
|
75
75
|
def self.start(client, jid, pass, host = nil, port = nil, certs_directory = nil, connect_timeout = nil)
|
@@ -126,7 +126,7 @@ module Blather
|
|
126
126
|
# @param [#to_xml, #to_s] stanza the stanza to send over the wire
|
127
127
|
def send(stanza)
|
128
128
|
data = stanza.respond_to?(:to_xml) ? stanza.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML) : stanza.to_s
|
129
|
-
Blather.log "SENDING: (#{caller[1]}) #{
|
129
|
+
Blather.log "SENDING: (#{caller[1]}) #{stanza}"
|
130
130
|
send_data data
|
131
131
|
end
|
132
132
|
|
@@ -168,15 +168,15 @@ module Blather
|
|
168
168
|
send "<stream:error><xml-not-well-formed xmlns='#{StreamError::STREAM_ERR_NS}'/></stream:error>"
|
169
169
|
stop
|
170
170
|
end
|
171
|
-
|
172
|
-
# Called by EM to verify the peer certificate. If a certificate store directory
|
171
|
+
|
172
|
+
# Called by EM to verify the peer certificate. If a certificate store directory
|
173
173
|
# has not been configured don't worry about peer verification. At least it is encrypted
|
174
174
|
# We Log the certificate so that you can add it to the trusted store easily if desired
|
175
175
|
# @private
|
176
176
|
def ssl_verify_peer(pem)
|
177
177
|
# EM is supposed to close the connection when this returns false,
|
178
178
|
# but it only does that for inbound connections, not when we
|
179
|
-
# make a connection to another server.
|
179
|
+
# make a connection to another server.
|
180
180
|
Blather.log "Checking SSL cert: #{pem}"
|
181
181
|
return true if !@@store
|
182
182
|
@@store.trusted?(pem).tap do |trusted|
|
data/lib/blather/version.rb
CHANGED
data/lib/blather/xmpp_node.rb
CHANGED
@@ -45,24 +45,28 @@ describe Blather::Stanza::Presence do
|
|
45
45
|
s = Blather::Stanza::Presence.parse string
|
46
46
|
s.should be_kind_of Blather::Stanza::Presence::C::InstanceMethods
|
47
47
|
s.node.should == 'http://www.chatopus.com'
|
48
|
+
s.handler_hierarchy.should include(:c)
|
48
49
|
end
|
49
50
|
|
50
51
|
it 'creates a Status object when importing a node with type == nil' do
|
51
52
|
s = Blather::Stanza::Presence.parse('<presence/>')
|
52
53
|
s.should be_kind_of Blather::Stanza::Presence::Status::InstanceMethods
|
53
54
|
s.state.should == :available
|
55
|
+
s.handler_hierarchy.should include(Blather::Stanza::Presence::Status.registered_name.to_sym)
|
54
56
|
end
|
55
57
|
|
56
58
|
it 'creates a Status object when importing a node with type == "unavailable"' do
|
57
59
|
s = Blather::Stanza::Presence.parse('<presence type="unavailable"/>')
|
58
60
|
s.should be_kind_of Blather::Stanza::Presence::Status::InstanceMethods
|
59
61
|
s.state.should == :unavailable
|
62
|
+
s.handler_hierarchy.should include(Blather::Stanza::Presence::Status.registered_name.to_sym)
|
60
63
|
end
|
61
64
|
|
62
65
|
it 'creates a Subscription object when importing a node with type == "subscribe"' do
|
63
66
|
s = Blather::Stanza::Presence.parse('<presence type="subscribe"/>')
|
64
67
|
s.should be_kind_of Blather::Stanza::Presence::Subscription::InstanceMethods
|
65
68
|
s.type.should == :subscribe
|
69
|
+
s.handler_hierarchy.should include(Blather::Stanza::Presence::Subscription.registered_name.to_sym)
|
66
70
|
end
|
67
71
|
|
68
72
|
it 'creates a MUC object when importing a node with a form in the MUC namespace' do
|
@@ -90,6 +94,7 @@ describe Blather::Stanza::Presence do
|
|
90
94
|
s = Blather::Stanza::Presence.parse string
|
91
95
|
s.should be_kind_of Blather::Stanza::Presence
|
92
96
|
s.type.should == :foo
|
97
|
+
s.handler_hierarchy.should include(Blather::Stanza::Presence.registered_name.to_sym)
|
93
98
|
end
|
94
99
|
|
95
100
|
it 'behaves like a C, a Status, and a MUCUser when all types of children are present' do
|
@@ -114,5 +119,7 @@ describe Blather::Stanza::Presence do
|
|
114
119
|
s.state.should == :chat
|
115
120
|
s.node.should == 'http://www.chatopus.com'
|
116
121
|
s.role.should == :participant
|
122
|
+
s.handler_hierarchy.should include(Blather::Stanza::Presence::C.registered_name.to_sym)
|
123
|
+
s.handler_hierarchy.should include(Blather::Stanza::Presence::Status.registered_name.to_sym)
|
117
124
|
end
|
118
125
|
end
|
@@ -137,6 +137,10 @@ describe Blather::Stanza::X do
|
|
137
137
|
end
|
138
138
|
|
139
139
|
describe Blather::Stanza::X::Field do
|
140
|
+
subject { Blather::Stanza::X::Field.new nil }
|
141
|
+
|
142
|
+
its(:namespace) { subject.href.should be == 'jabber:x:data' }
|
143
|
+
|
140
144
|
it 'will auto-inherit nodes' do
|
141
145
|
n = parse_stanza "<field type='text-single' var='music' label='Music from the time of Shakespeare' />"
|
142
146
|
i = Blather::Stanza::X::Field.new n.root
|
@@ -193,13 +197,10 @@ describe Blather::Stanza::X::Field do
|
|
193
197
|
n.value.should == 'book2'
|
194
198
|
end
|
195
199
|
|
196
|
-
|
197
|
-
it 'allows adding of options' do
|
200
|
+
it 'allows setting options' do
|
198
201
|
di = Blather::Stanza::X::Field.new nil
|
199
202
|
di.options.size.should == 0
|
200
|
-
di.options
|
201
|
-
di.options.size.should == 1
|
202
|
-
di.options += [Blather::Stanza::X::Field::Option.new(*%w[person1 Person1])]
|
203
|
+
di.options = [{:label => 'Person', :value => 'person'}, Blather::Stanza::X::Field::Option.new(*%w[person1 Person1])]
|
203
204
|
di.options.size.should == 2
|
204
205
|
end
|
205
206
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: blather
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.7.
|
4
|
+
version: 0.7.1
|
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-
|
12
|
+
date: 2012-04-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: eventmachine
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,32 +21,47 @@ dependencies:
|
|
21
21
|
version: 0.12.6
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.12.6
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: nokogiri
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ~>
|
31
36
|
- !ruby/object:Gem::Version
|
32
|
-
version: 1.4
|
37
|
+
version: '1.4'
|
33
38
|
type: :runtime
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '1.4'
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: niceogiri
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
51
|
- - ~>
|
42
52
|
- !ruby/object:Gem::Version
|
43
|
-
version: 1.0
|
53
|
+
version: '1.0'
|
44
54
|
type: :runtime
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.0'
|
47
62
|
- !ruby/object:Gem::Dependency
|
48
63
|
name: activesupport
|
49
|
-
requirement:
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
50
65
|
none: false
|
51
66
|
requirements:
|
52
67
|
- - ! '>='
|
@@ -54,10 +69,15 @@ dependencies:
|
|
54
69
|
version: 3.0.7
|
55
70
|
type: :runtime
|
56
71
|
prerelease: false
|
57
|
-
version_requirements:
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 3.0.7
|
58
78
|
- !ruby/object:Gem::Dependency
|
59
79
|
name: girl_friday
|
60
|
-
requirement:
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
61
81
|
none: false
|
62
82
|
requirements:
|
63
83
|
- - ! '>='
|
@@ -65,10 +85,15 @@ dependencies:
|
|
65
85
|
version: '0'
|
66
86
|
type: :runtime
|
67
87
|
prerelease: false
|
68
|
-
version_requirements:
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
69
94
|
- !ruby/object:Gem::Dependency
|
70
95
|
name: bundler
|
71
|
-
requirement:
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
72
97
|
none: false
|
73
98
|
requirements:
|
74
99
|
- - ~>
|
@@ -76,10 +101,15 @@ dependencies:
|
|
76
101
|
version: '1.0'
|
77
102
|
type: :development
|
78
103
|
prerelease: false
|
79
|
-
version_requirements:
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '1.0'
|
80
110
|
- !ruby/object:Gem::Dependency
|
81
111
|
name: rake
|
82
|
-
requirement:
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
83
113
|
none: false
|
84
114
|
requirements:
|
85
115
|
- - ! '>='
|
@@ -87,10 +117,15 @@ dependencies:
|
|
87
117
|
version: '0'
|
88
118
|
type: :development
|
89
119
|
prerelease: false
|
90
|
-
version_requirements:
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
91
126
|
- !ruby/object:Gem::Dependency
|
92
127
|
name: rspec
|
93
|
-
requirement:
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
94
129
|
none: false
|
95
130
|
requirements:
|
96
131
|
- - ~>
|
@@ -98,10 +133,15 @@ dependencies:
|
|
98
133
|
version: '2.7'
|
99
134
|
type: :development
|
100
135
|
prerelease: false
|
101
|
-
version_requirements:
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ~>
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '2.7'
|
102
142
|
- !ruby/object:Gem::Dependency
|
103
143
|
name: mocha
|
104
|
-
requirement:
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
105
145
|
none: false
|
106
146
|
requirements:
|
107
147
|
- - ~>
|
@@ -109,10 +149,15 @@ dependencies:
|
|
109
149
|
version: 0.9.12
|
110
150
|
type: :development
|
111
151
|
prerelease: false
|
112
|
-
version_requirements:
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ~>
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: 0.9.12
|
113
158
|
- !ruby/object:Gem::Dependency
|
114
159
|
name: guard-rspec
|
115
|
-
requirement:
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
116
161
|
none: false
|
117
162
|
requirements:
|
118
163
|
- - ! '>='
|
@@ -120,10 +165,15 @@ dependencies:
|
|
120
165
|
version: '0'
|
121
166
|
type: :development
|
122
167
|
prerelease: false
|
123
|
-
version_requirements:
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
124
174
|
- !ruby/object:Gem::Dependency
|
125
175
|
name: yard
|
126
|
-
requirement:
|
176
|
+
requirement: !ruby/object:Gem::Requirement
|
127
177
|
none: false
|
128
178
|
requirements:
|
129
179
|
- - ~>
|
@@ -131,10 +181,15 @@ dependencies:
|
|
131
181
|
version: 0.6.1
|
132
182
|
type: :development
|
133
183
|
prerelease: false
|
134
|
-
version_requirements:
|
184
|
+
version_requirements: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ~>
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: 0.6.1
|
135
190
|
- !ruby/object:Gem::Dependency
|
136
191
|
name: bluecloth
|
137
|
-
requirement:
|
192
|
+
requirement: !ruby/object:Gem::Requirement
|
138
193
|
none: false
|
139
194
|
requirements:
|
140
195
|
- - ! '>='
|
@@ -142,7 +197,12 @@ dependencies:
|
|
142
197
|
version: '0'
|
143
198
|
type: :development
|
144
199
|
prerelease: false
|
145
|
-
version_requirements:
|
200
|
+
version_requirements: !ruby/object:Gem::Requirement
|
201
|
+
none: false
|
202
|
+
requirements:
|
203
|
+
- - ! '>='
|
204
|
+
- !ruby/object:Gem::Version
|
205
|
+
version: '0'
|
146
206
|
description: An XMPP DSL for Ruby written on top of EventMachine and Nokogiri
|
147
207
|
email: sprsquish@gmail.com
|
148
208
|
executables: []
|
@@ -314,7 +374,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
314
374
|
version: '0'
|
315
375
|
segments:
|
316
376
|
- 0
|
317
|
-
hash:
|
377
|
+
hash: 4196042577194384774
|
318
378
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
319
379
|
none: false
|
320
380
|
requirements:
|
@@ -323,10 +383,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
323
383
|
version: '0'
|
324
384
|
segments:
|
325
385
|
- 0
|
326
|
-
hash:
|
386
|
+
hash: 4196042577194384774
|
327
387
|
requirements: []
|
328
388
|
rubyforge_project:
|
329
|
-
rubygems_version: 1.8.
|
389
|
+
rubygems_version: 1.8.21
|
330
390
|
signing_key:
|
331
391
|
specification_version: 3
|
332
392
|
summary: Simpler XMPP built for speed
|