em-xmpp 0.0.8 → 0.0.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/em-xmpp/connection.rb +1 -1
- data/lib/em-xmpp/context.rb +601 -363
- data/lib/em-xmpp/handler.rb +31 -15
- data/lib/em-xmpp/helpers.rb +2 -2
- data/lib/em-xmpp/namespaces.rb +10 -0
- data/lib/em-xmpp/version.rb +1 -1
- data/samples/hello.rb +13 -9
- metadata +8 -8
data/lib/em-xmpp/connection.rb
CHANGED
data/lib/em-xmpp/context.rb
CHANGED
@@ -7,7 +7,7 @@ require 'ostruct'
|
|
7
7
|
|
8
8
|
module EM::Xmpp
|
9
9
|
class Context
|
10
|
-
attr_reader :connection, :stanza, :env
|
10
|
+
attr_reader :connection, :stanza, :env, :bits
|
11
11
|
|
12
12
|
def []key
|
13
13
|
env[key]
|
@@ -40,6 +40,7 @@ module EM::Xmpp
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def initialize(conn, stanza, env={})
|
43
|
+
@bits = {}
|
43
44
|
@connection = conn
|
44
45
|
@stanza = stanza
|
45
46
|
@env = default_env.merge env
|
@@ -65,10 +66,18 @@ module EM::Xmpp
|
|
65
66
|
end
|
66
67
|
|
67
68
|
def with(modname)
|
69
|
+
if $DEBUG
|
70
|
+
$stderr.puts "using outdated <with> which is slow"
|
71
|
+
end
|
72
|
+
bit! modname
|
73
|
+
slow_with modname
|
74
|
+
end
|
75
|
+
|
76
|
+
def slow_with(modname)
|
68
77
|
mod = if modname.is_a?(Module)
|
69
78
|
modname
|
70
79
|
else
|
71
|
-
|
80
|
+
Contexts.const_get(modname.to_s.capitalize)
|
72
81
|
end
|
73
82
|
env['modules'] << mod
|
74
83
|
obj = self
|
@@ -76,429 +85,465 @@ module EM::Xmpp
|
|
76
85
|
obj
|
77
86
|
end
|
78
87
|
|
79
|
-
|
80
|
-
|
81
|
-
%w{type id lang}.each do |w|
|
82
|
-
define_method w do
|
83
|
-
read_attr stanza, w
|
84
|
-
end
|
85
|
-
end
|
86
|
-
def to
|
87
|
-
read_attr(stanza, 'to'){|j| @connection.entity(j)}
|
88
|
-
end
|
89
|
-
def from
|
90
|
-
read_attr(stanza, 'from'){|j| @connection.entity(j)}
|
91
|
-
end
|
92
|
-
def error?
|
93
|
-
type == 'error'
|
94
|
-
end
|
95
|
-
def delay?
|
96
|
-
false
|
97
|
-
end
|
88
|
+
def bit(klassname)
|
89
|
+
bits[bit_klass_name(klassname)]
|
98
90
|
end
|
99
91
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
92
|
+
def bit!(klassname)
|
93
|
+
ret = bit klassname
|
94
|
+
unless ret
|
95
|
+
klass = if klassname.is_a?(Class)
|
96
|
+
klassname
|
97
|
+
else
|
98
|
+
Bits.const_get(klassname.to_s.capitalize)
|
99
|
+
end
|
100
|
+
ret = bit_from_klass klass
|
101
|
+
end
|
102
|
+
ret
|
103
|
+
end
|
109
104
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
end
|
105
|
+
def bit?(klassname)
|
106
|
+
bits.has_key? bit_klass_name(klassname)
|
107
|
+
end
|
114
108
|
|
115
|
-
|
116
|
-
n = error_node
|
117
|
-
n.children.first if n
|
118
|
-
end
|
109
|
+
private
|
119
110
|
|
120
|
-
|
121
|
-
|
122
|
-
n.name if n
|
123
|
-
end
|
111
|
+
def bit_klass_name(obj)
|
112
|
+
obj.to_s.split('::').last.capitalize
|
124
113
|
end
|
125
114
|
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
{'from' => jid, 'to' => from, 'id' => id}
|
131
|
-
end
|
132
|
-
def reply(args={},&blk)
|
133
|
-
args = reply_default_params.merge args
|
134
|
-
@connection.presence_stanza(args,&blk)
|
135
|
-
end
|
136
|
-
def priority_node
|
137
|
-
xpath('//xmlns:priority',{'xmlns' => Client}).first
|
138
|
-
end
|
139
|
-
def status_node
|
140
|
-
xpath('//xmlns:status',{'xmlns' => Client}).first
|
141
|
-
end
|
142
|
-
def show_node
|
143
|
-
xpath('//xmlns:show',{'xmlns' => Client}).first
|
144
|
-
end
|
145
|
-
def priority
|
146
|
-
node = priority_node
|
147
|
-
node.content if node
|
148
|
-
end
|
149
|
-
def status
|
150
|
-
node = status_node
|
151
|
-
node.content if node
|
152
|
-
end
|
153
|
-
def show
|
154
|
-
node = show_node
|
155
|
-
node.content if node
|
156
|
-
end
|
157
|
-
def subscription_request?
|
158
|
-
type == 'subscribe'
|
159
|
-
end
|
160
|
-
def entity_left?
|
161
|
-
type == 'unavailable'
|
162
|
-
end
|
115
|
+
def bit_from_klass(klass)
|
116
|
+
obj = klass.new(self)
|
117
|
+
bits[bit_klass_name(klass)] = obj
|
118
|
+
obj
|
163
119
|
end
|
164
120
|
|
165
|
-
|
166
|
-
include IncomingStanza
|
167
|
-
def subject_node
|
168
|
-
xpath('//xmlns:subject',{'xmlns' => Client}).first
|
169
|
-
end
|
121
|
+
public
|
170
122
|
|
171
|
-
|
172
|
-
|
173
|
-
|
123
|
+
module Contexts
|
124
|
+
module IncomingStanza
|
125
|
+
include Namespaces
|
126
|
+
%w{type id lang}.each do |w|
|
127
|
+
define_method w do
|
128
|
+
read_attr stanza, w
|
129
|
+
end
|
130
|
+
end
|
131
|
+
def to
|
132
|
+
read_attr(stanza, 'to'){|j| connection.entity(j)}
|
133
|
+
end
|
134
|
+
def from
|
135
|
+
read_attr(stanza, 'from'){|j| connection.entity(j)}
|
136
|
+
end
|
137
|
+
def error?
|
138
|
+
type == 'error'
|
139
|
+
end
|
140
|
+
def delay?
|
141
|
+
false
|
142
|
+
end
|
174
143
|
end
|
175
144
|
|
176
|
-
|
177
|
-
|
178
|
-
|
145
|
+
module Error
|
146
|
+
def error_node
|
147
|
+
xpath('//xmlns:error',{'xmlns' => Client}).first
|
148
|
+
end
|
179
149
|
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
150
|
+
def error_code
|
151
|
+
n = error_node
|
152
|
+
read_attr(n, 'code') if n
|
153
|
+
end
|
184
154
|
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
end
|
155
|
+
def error_type
|
156
|
+
n = error_node
|
157
|
+
read_attr(n, 'type') if n
|
158
|
+
end
|
190
159
|
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
160
|
+
def error_condition_node
|
161
|
+
n = error_node
|
162
|
+
n.children.first if n
|
163
|
+
end
|
195
164
|
|
196
|
-
|
197
|
-
|
165
|
+
def error_condition
|
166
|
+
n = error_condition_node
|
167
|
+
n.name if n
|
168
|
+
end
|
198
169
|
end
|
199
|
-
end
|
200
170
|
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
171
|
+
module Presence
|
172
|
+
include IncomingStanza
|
173
|
+
def reply_default_params
|
174
|
+
jid = connection.jid.full
|
175
|
+
{'from' => jid, 'to' => from, 'id' => id}
|
176
|
+
end
|
177
|
+
def reply(args={},&blk)
|
178
|
+
args = reply_default_params.merge args
|
179
|
+
connection.presence_stanza(args,&blk)
|
180
|
+
end
|
181
|
+
def priority_node
|
182
|
+
xpath('//xmlns:priority',{'xmlns' => Client}).first
|
183
|
+
end
|
184
|
+
def status_node
|
185
|
+
xpath('//xmlns:status',{'xmlns' => Client}).first
|
186
|
+
end
|
187
|
+
def show_node
|
188
|
+
xpath('//xmlns:show',{'xmlns' => Client}).first
|
189
|
+
end
|
190
|
+
def priority
|
191
|
+
node = priority_node
|
192
|
+
node.content if node
|
193
|
+
end
|
194
|
+
def status
|
195
|
+
node = status_node
|
196
|
+
node.content if node
|
197
|
+
end
|
198
|
+
def show
|
199
|
+
node = show_node
|
200
|
+
node.content if node
|
201
|
+
end
|
202
|
+
def subscription_request?
|
203
|
+
type == 'subscribe'
|
204
|
+
end
|
205
|
+
def entity_left?
|
206
|
+
type == 'unavailable'
|
207
|
+
end
|
206
208
|
end
|
207
209
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
210
|
+
module Message
|
211
|
+
include IncomingStanza
|
212
|
+
def subject_node
|
213
|
+
xpath('//xmlns:subject',{'xmlns' => Client}).first
|
214
|
+
end
|
213
215
|
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
216
|
+
def subject
|
217
|
+
node = subject_node
|
218
|
+
node.text if node
|
219
|
+
end
|
220
|
+
|
221
|
+
def body_node
|
222
|
+
xpath('//xmlns:body',{'xmlns' => Client}).first
|
223
|
+
end
|
224
|
+
|
225
|
+
def body
|
226
|
+
node = body_node
|
227
|
+
node.text if node
|
228
|
+
end
|
229
|
+
|
230
|
+
def reply_default_params
|
231
|
+
h = {'to' => from, 'type' => type}
|
232
|
+
h['id'] = id.succ if id
|
233
|
+
h
|
234
|
+
end
|
235
|
+
|
236
|
+
def reply(args={},&blk)
|
237
|
+
args = reply_default_params.merge args
|
238
|
+
connection.message_stanza(args,&blk)
|
239
|
+
end
|
240
|
+
|
241
|
+
def groupchat?
|
242
|
+
type == 'groupchat'
|
243
|
+
end
|
225
244
|
end
|
226
|
-
end
|
227
245
|
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
246
|
+
module Iq
|
247
|
+
include IncomingStanza
|
248
|
+
def reply_default_params
|
249
|
+
jid = connection.jid.full
|
250
|
+
{'from' => jid, 'to' => from, 'type' => 'result', 'id' => id}
|
251
|
+
end
|
252
|
+
|
253
|
+
def reply(args={},&blk)
|
254
|
+
args = reply_default_params.merge args
|
255
|
+
connection.iq_stanza(args,&blk)
|
234
256
|
end
|
235
257
|
end
|
236
|
-
end
|
237
258
|
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
cat = read_attr(x, 'category')
|
250
|
-
type = read_attr(x, 'type')
|
251
|
-
name = read_attr(x, 'name')
|
252
|
-
Identity.new name, cat, type
|
253
|
-
end
|
259
|
+
module Delay
|
260
|
+
def delay?
|
261
|
+
true
|
262
|
+
end
|
263
|
+
#does not handle legacy delay
|
264
|
+
def delay_node
|
265
|
+
xpath('//xmlns:delay',{'xmlns' => EM::Xmpp::Namespaces::Delay}).first
|
266
|
+
end
|
267
|
+
def stamp
|
268
|
+
n = delay_node
|
269
|
+
Time.parse read_attr(n, 'stamp') if n
|
254
270
|
end
|
255
271
|
end
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
272
|
+
|
273
|
+
module Discoveries
|
274
|
+
include Iq
|
275
|
+
%w{node}.each do |word|
|
276
|
+
define_method word do
|
277
|
+
n = query_node
|
278
|
+
read_attr(n, word) if n
|
262
279
|
end
|
263
280
|
end
|
264
281
|
end
|
265
|
-
end
|
266
282
|
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
283
|
+
module Discoinfos
|
284
|
+
include Discoveries
|
285
|
+
Identity = Struct.new(:name, :category, :type)
|
286
|
+
Feature = Struct.new(:var)
|
287
|
+
def query_node
|
288
|
+
xpath('//xmlns:query',{'xmlns' => DiscoverInfos}).first
|
289
|
+
end
|
290
|
+
def identities
|
291
|
+
n = query_node
|
292
|
+
if n
|
293
|
+
n.xpath('xmlns:identity',{'xmlns' => DiscoverInfos}).map do |x|
|
294
|
+
cat = read_attr(x, 'category')
|
295
|
+
type = read_attr(x, 'type')
|
296
|
+
name = read_attr(x, 'name')
|
297
|
+
Identity.new name, cat, type
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
def features
|
302
|
+
n = query_node
|
303
|
+
if n
|
304
|
+
n.xpath('xmlns:feature',{'xmlns' => DiscoverInfos}).map do |x|
|
305
|
+
var = read_attr(x, 'var')
|
306
|
+
Feature.new var
|
307
|
+
end
|
308
|
+
end
|
282
309
|
end
|
283
310
|
end
|
284
|
-
end
|
285
311
|
|
286
|
-
|
287
|
-
|
288
|
-
|
312
|
+
module Discoitems
|
313
|
+
include Discoveries
|
314
|
+
Item = Struct.new(:entity, :node, :name)
|
315
|
+
def query_node
|
316
|
+
xpath('//xmlns:query',{'xmlns' => DiscoverItems}).first
|
317
|
+
end
|
318
|
+
def item_nodes
|
319
|
+
xpath('//xmlns:item',{'xmlns' => DiscoverItems})
|
320
|
+
end
|
321
|
+
def items
|
322
|
+
item_nodes.map do |n|
|
323
|
+
entity = read_attr(n, 'jid'){|x| connection.entity(x)}
|
324
|
+
node = read_attr(n, 'node')
|
325
|
+
name = read_attr(n, 'name')
|
326
|
+
Item.new(entity, node, name)
|
327
|
+
end
|
328
|
+
end
|
289
329
|
end
|
290
330
|
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
read_attr(n, word) if n
|
331
|
+
module Command
|
332
|
+
def command_node
|
333
|
+
xpath('//xmlns:command',{'xmlns' => Commands}).first
|
295
334
|
end
|
296
|
-
end
|
297
335
|
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
336
|
+
%w{node sessionid action}.each do |word|
|
337
|
+
define_method word do
|
338
|
+
n = command_node
|
339
|
+
read_attr(n, word) if n
|
340
|
+
end
|
341
|
+
end
|
302
342
|
|
303
|
-
|
304
|
-
|
305
|
-
Field = Struct.new(:var, :type, :values) do
|
306
|
-
def value
|
307
|
-
values.first
|
343
|
+
def previous?
|
344
|
+
action == 'prev'
|
308
345
|
end
|
309
346
|
end
|
310
347
|
|
311
|
-
|
312
|
-
|
313
|
-
|
348
|
+
module Dataforms
|
349
|
+
Form = Struct.new(:type, :fields)
|
350
|
+
Field = Struct.new(:var, :type, :values) do
|
351
|
+
def value
|
352
|
+
values.first
|
353
|
+
end
|
354
|
+
end
|
314
355
|
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
field_nodes = form.xpath('xmlns:field',{'xmlns' => Namespaces::DataForms})
|
319
|
-
fields = field_nodes.map do |field|
|
320
|
-
var = read_attr(field, 'var')
|
321
|
-
type = read_attr(field, 'type')
|
322
|
-
value_nodes = field.xpath('xmlns:value',{'xmlns' => Namespaces::DataForms})
|
323
|
-
values = value_nodes.map(&:content)
|
356
|
+
def x_form_nodes
|
357
|
+
xpath('//xmlns:x',{'xmlns' => Namespaces::DataForms})
|
358
|
+
end
|
324
359
|
|
325
|
-
|
360
|
+
def x_forms
|
361
|
+
x_form_nodes.map do |form|
|
362
|
+
form_type = read_attr(form, 'type')
|
363
|
+
field_nodes = form.xpath('xmlns:field',{'xmlns' => Namespaces::DataForms})
|
364
|
+
fields = field_nodes.map do |field|
|
365
|
+
var = read_attr(field, 'var')
|
366
|
+
type = read_attr(field, 'type')
|
367
|
+
value_nodes = field.xpath('//xmlns:value',{'xmlns' => Namespaces::DataForms})
|
368
|
+
values = value_nodes.map(&:content)
|
369
|
+
|
370
|
+
Field.new(var,type,values)
|
371
|
+
end
|
372
|
+
Form.new form_type, fields
|
326
373
|
end
|
327
|
-
Form.new form_type, fields
|
328
374
|
end
|
329
375
|
end
|
330
|
-
end
|
331
376
|
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
377
|
+
module Capabilities
|
378
|
+
def c_node
|
379
|
+
xpath('//xmlns:c',{'xmlns' => EM::Xmpp::Namespaces::Capabilities}).first
|
380
|
+
end
|
336
381
|
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
382
|
+
%w{node ver ext}.each do |word|
|
383
|
+
define_method word do
|
384
|
+
n = c_node
|
385
|
+
read_attr(n, word) if n
|
386
|
+
end
|
341
387
|
end
|
342
388
|
end
|
343
|
-
end
|
344
389
|
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
390
|
+
module Roster
|
391
|
+
def query_node
|
392
|
+
xpath('//xmlns:query',{'xmlns' => EM::Xmpp::Namespaces::Roster}).first
|
393
|
+
end
|
349
394
|
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
395
|
+
def items
|
396
|
+
n = query_node
|
397
|
+
if n
|
398
|
+
n.children.map do |xml|
|
399
|
+
new_subscription(xml)
|
400
|
+
end
|
355
401
|
end
|
356
402
|
end
|
357
|
-
end
|
358
403
|
|
359
|
-
|
404
|
+
private
|
360
405
|
|
361
|
-
|
406
|
+
Subscription = Struct.new(:type, :jid, :name, :groups)
|
362
407
|
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
408
|
+
def new_subscription(n)
|
409
|
+
type = read_attr(n,'subscription')
|
410
|
+
jid = read_attr(n,'jid') {|x| connection.entity x}
|
411
|
+
name = read_attr(n,'name')
|
412
|
+
groups = n.xpath('xmlns:group', 'xmlns' => EM::Xmpp::Namespaces::Roster).map{|n| n.content}
|
413
|
+
Subscription.new(type, jid, name, groups)
|
414
|
+
end
|
369
415
|
end
|
370
|
-
end
|
371
416
|
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
417
|
+
module Tune
|
418
|
+
def tune_node
|
419
|
+
xpath('//xmlns:tune',{'xmlns' => Namespaces::Tune}).first
|
420
|
+
end
|
376
421
|
|
377
|
-
|
378
|
-
|
422
|
+
DecimalFields = %w{length rating}.freeze
|
423
|
+
StringFields = %w{artist source title track uri}.freeze
|
379
424
|
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
425
|
+
DecimalFields.each do |decimal|
|
426
|
+
define_method(decimal) do
|
427
|
+
n = tune_node
|
428
|
+
if n
|
429
|
+
d = n.children.find{|c| c.name == decimal}
|
430
|
+
d.content.to_i if d
|
431
|
+
end
|
386
432
|
end
|
387
433
|
end
|
388
|
-
end
|
389
434
|
|
390
435
|
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
436
|
+
StringFields.each do |str|
|
437
|
+
define_method(str) do
|
438
|
+
n = tune_node
|
439
|
+
if n
|
440
|
+
d = n.children.find{|c| c.name == str}
|
441
|
+
d.content
|
442
|
+
end
|
397
443
|
end
|
398
444
|
end
|
399
|
-
end
|
400
445
|
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
446
|
+
def tune
|
447
|
+
ostruct = OpenStruct.new
|
448
|
+
(StringFields + DecimalFields).each do |field|
|
449
|
+
val = send field
|
450
|
+
ostruct.send("#{field}=", val)
|
451
|
+
end
|
452
|
+
ostruct
|
406
453
|
end
|
407
|
-
ostruct
|
408
454
|
end
|
409
|
-
end
|
410
455
|
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
456
|
+
module Nickname
|
457
|
+
def nickname_node
|
458
|
+
xpath('//xmlns:nick',{'xmlns' => Nick}).first
|
459
|
+
end
|
460
|
+
def nickname
|
461
|
+
n = nickname_node
|
462
|
+
n.content if n
|
463
|
+
end
|
418
464
|
end
|
419
|
-
end
|
420
465
|
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
466
|
+
module Geolocation
|
467
|
+
def geoloc_node
|
468
|
+
xpath('//xmlns:nick',{'xmlns' => Geoloc}).first
|
469
|
+
end
|
425
470
|
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
471
|
+
def geoloc
|
472
|
+
ostruct = OpenStruct.newt
|
473
|
+
(StringFields + DecimalFields + %w{timestamp}).each do |field|
|
474
|
+
val = send field
|
475
|
+
ostruct.send("#{field}=", val)
|
476
|
+
end
|
477
|
+
ostruct
|
431
478
|
end
|
432
|
-
ostruct
|
433
|
-
end
|
434
479
|
|
435
|
-
|
480
|
+
StringFields = %w{area building country countrycode datum description
|
436
481
|
floor locality postalcode region room street text uri}.freeze
|
437
|
-
|
482
|
+
DecimalFields = %w{accuracy error alt lat lon bearing speed}.freeze
|
483
|
+
|
484
|
+
DecimalFields.each do |decimal|
|
485
|
+
define_method(decimal) do
|
486
|
+
n = geoloc_node
|
487
|
+
if n
|
488
|
+
d = n.children.find{|c| c.name == decimal}
|
489
|
+
d.content.to_i if d
|
490
|
+
end
|
491
|
+
end
|
492
|
+
end
|
438
493
|
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
494
|
+
StringFields.each do |str|
|
495
|
+
define_method(str) do
|
496
|
+
n = geoloc_node
|
497
|
+
if n
|
498
|
+
d = n.children.find{|c| c.name == str}
|
499
|
+
d.content
|
500
|
+
end
|
445
501
|
end
|
446
502
|
end
|
447
|
-
end
|
448
503
|
|
449
|
-
|
450
|
-
define_method(str) do
|
504
|
+
def timestamp
|
451
505
|
n = geoloc_node
|
452
506
|
if n
|
453
|
-
d = n.children.find{|c| c.name ==
|
454
|
-
d.content
|
507
|
+
d = n.children.find{|c| c.name == 'timestamp'}
|
508
|
+
Time.parse d.content if d
|
455
509
|
end
|
456
510
|
end
|
457
511
|
end
|
458
512
|
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
d = n.children.find{|c| c.name == 'timestamp'}
|
463
|
-
Time.parse d.content if d
|
513
|
+
module Useractivity
|
514
|
+
def activity_node
|
515
|
+
xpath('//xmlns:mood',{'xmlns' => Namespaces::Activity}).first
|
464
516
|
end
|
465
|
-
end
|
466
|
-
end
|
467
|
-
|
468
|
-
module Useractivity
|
469
|
-
def activity_node
|
470
|
-
xpath('//xmlns:mood',{'xmlns' => Namespaces::Activity}).first
|
471
|
-
end
|
472
517
|
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
518
|
+
def activity_category_node
|
519
|
+
n = activity_node
|
520
|
+
n.children.first if n
|
521
|
+
end
|
477
522
|
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
523
|
+
def activity_text_node
|
524
|
+
n = activity_node
|
525
|
+
n.children.find{|n| n.name == 'text'} if n
|
526
|
+
end
|
482
527
|
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
528
|
+
def activity
|
529
|
+
ret = []
|
530
|
+
n = activity_category_node
|
531
|
+
if n
|
532
|
+
ret << n.name
|
533
|
+
detail = n.children.first
|
534
|
+
ret << detail.name if detail
|
535
|
+
end
|
536
|
+
ret
|
490
537
|
end
|
491
|
-
ret
|
492
|
-
end
|
493
538
|
|
494
|
-
|
495
|
-
|
496
|
-
|
539
|
+
def activity_text
|
540
|
+
n = activity_text_node
|
541
|
+
n.content if n
|
542
|
+
end
|
497
543
|
end
|
498
|
-
end
|
499
544
|
|
500
|
-
|
501
|
-
|
545
|
+
module Mood
|
546
|
+
DefinedMoods = %w{afraid amazed angry amorous annoyed anxious aroused
|
502
547
|
ashamed bored brave calm cautious cold confident confused contemplative
|
503
548
|
contented cranky crazy creative curious dejected depressed disappointed
|
504
549
|
disgusted dismayed distracted embarrassed envious excited flirtatious
|
@@ -509,60 +554,253 @@ relieved remorseful restless sad sarcastic serious shocked shy sick sleepy
|
|
509
554
|
spontaneous stressed strong surprised thankful thirsty tired undefined weak
|
510
555
|
worried}.freeze
|
511
556
|
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
557
|
+
def mood_node
|
558
|
+
xpath('//xmlns:mood',{'xmlns' => Namespaces::Mood}).first
|
559
|
+
end
|
560
|
+
def mood_name_node
|
561
|
+
n = mood_node
|
562
|
+
n.children.find{|c| DefinedMoods.include?(c.name)} if n
|
563
|
+
end
|
564
|
+
def mood_text_node
|
565
|
+
n = mood_node
|
566
|
+
n.children.find{|c| c.name == 'text'}
|
567
|
+
end
|
568
|
+
def mood
|
569
|
+
n = mood_name_node
|
570
|
+
n.name if n
|
571
|
+
end
|
572
|
+
def mood
|
573
|
+
n = mood_text_node
|
574
|
+
n.content if n
|
575
|
+
end
|
518
576
|
end
|
519
|
-
|
520
|
-
|
521
|
-
|
577
|
+
|
578
|
+
module Bytestreams
|
579
|
+
include Iq
|
580
|
+
StreamHost = Struct.new(:host, :port, :jid)
|
581
|
+
def query_node
|
582
|
+
xpath('//xmlns:query',{'xmlns' => Namespaces::ByteStreams}).first
|
583
|
+
end
|
584
|
+
def transport_mode
|
585
|
+
n = query_node
|
586
|
+
read_attr(n,'mode') if n
|
587
|
+
end
|
588
|
+
def sid
|
589
|
+
n = query_node
|
590
|
+
read_attr(n,'sid') if n
|
591
|
+
end
|
592
|
+
def stream_hosts
|
593
|
+
n = query_node
|
594
|
+
if n
|
595
|
+
n.children.select{|c| c.name == 'streamhost'}.map do |c|
|
596
|
+
host = read_attr(c,'host')
|
597
|
+
port = read_attr(c,'port',:to_i)
|
598
|
+
jid = read_attr(c,'jid')
|
599
|
+
StreamHost.new(host, port, jid)
|
600
|
+
end
|
601
|
+
else
|
602
|
+
[]
|
603
|
+
end
|
604
|
+
end
|
605
|
+
def used_stream_hosts
|
606
|
+
n = query_node
|
607
|
+
if n
|
608
|
+
n.children.select{|c| c.name == 'streamhost-used'}.map do |c|
|
609
|
+
host = read_attr(c,'host')
|
610
|
+
port = read_attr(c,'port',:to_i)
|
611
|
+
jid = read_attr(c,'jid')
|
612
|
+
StreamHost.new(host, port, jid)
|
613
|
+
end
|
614
|
+
else
|
615
|
+
[]
|
616
|
+
end
|
617
|
+
end
|
618
|
+
def support_fast_mode?
|
619
|
+
xpath('//xmnls:fast',{'xmlns'=> Namespaces::FastByteStreams}).any?
|
620
|
+
end
|
522
621
|
end
|
523
|
-
|
524
|
-
|
525
|
-
|
622
|
+
|
623
|
+
module Streaminitiation
|
624
|
+
include Iq
|
625
|
+
include Dataforms
|
626
|
+
def si_node
|
627
|
+
xpath('//xmlns:si',{'xmlns' => Namespaces::StreamInitiation}).first
|
628
|
+
end
|
629
|
+
def file_node
|
630
|
+
xpath('//xmlns:file',{'xmlns' => Namespaces::FileTransfer}).first
|
631
|
+
end
|
632
|
+
def mime_type
|
633
|
+
n = si_node
|
634
|
+
read_attr(n, 'mime-type') if n
|
635
|
+
end
|
636
|
+
def profile
|
637
|
+
n = si_node
|
638
|
+
read_attr(n, 'profile') if n
|
639
|
+
end
|
640
|
+
def file_name
|
641
|
+
n = file_node
|
642
|
+
read_attr(n, 'name') if n
|
643
|
+
end
|
644
|
+
def file_size
|
645
|
+
n = file_node
|
646
|
+
read_attr(n, 'size') if n
|
647
|
+
end
|
648
|
+
def file_date
|
649
|
+
n = file_node
|
650
|
+
read_attr(n, 'date') if n
|
651
|
+
end
|
652
|
+
def file_md5
|
653
|
+
n = file_node
|
654
|
+
read_attr(n, 'hash') if n
|
655
|
+
end
|
656
|
+
def can_do_range?
|
657
|
+
n = file_node
|
658
|
+
n.children.find{|n| n.name == 'range'} if n
|
659
|
+
end
|
660
|
+
# TODO: range on requests
|
661
|
+
def description
|
662
|
+
n = file_node
|
663
|
+
if n
|
664
|
+
node = n.children.find{|n| n.name == 'desc'}
|
665
|
+
node.content if node
|
666
|
+
end
|
667
|
+
end
|
668
|
+
def stream_methods
|
669
|
+
form = x_forms.first
|
670
|
+
if form
|
671
|
+
field = form.fields.first
|
672
|
+
field.values if field
|
673
|
+
end
|
674
|
+
end
|
526
675
|
end
|
527
|
-
|
528
|
-
|
529
|
-
|
676
|
+
|
677
|
+
module Mucuser
|
678
|
+
def x_nodstreaminitiation
|
679
|
+
xpath('//xmlns:x',{'xmlns' => EM::Xmpp::Namespaces::MucUser}).first
|
680
|
+
end
|
681
|
+
|
682
|
+
def item_node
|
683
|
+
xpath('//xmlns:item',{'xmlns' => EM::Xmpp::Namespaces::MucUser}).first
|
684
|
+
end
|
685
|
+
|
686
|
+
def status_node
|
687
|
+
xpath('//xmlns:status',{'xmlns' => EM::Xmpp::Namespaces::MucUser}).first
|
688
|
+
end
|
689
|
+
|
690
|
+
def status
|
691
|
+
n = status_node
|
692
|
+
read_attr(n, 'code') if n
|
693
|
+
end
|
694
|
+
|
695
|
+
def jid
|
696
|
+
n = item_node
|
697
|
+
jid_str = read_attr(n, 'jid') if n
|
698
|
+
connection.entity jid_str if jid_str
|
699
|
+
end
|
700
|
+
|
701
|
+
def affiliation
|
702
|
+
n = item_node
|
703
|
+
read_attr(n, 'affiliation') if n
|
704
|
+
end
|
705
|
+
|
706
|
+
def role
|
707
|
+
n = item_node
|
708
|
+
read_attr(n, 'role') if n
|
709
|
+
end
|
530
710
|
end
|
531
711
|
end
|
532
712
|
|
533
|
-
|
534
|
-
|
535
|
-
|
713
|
+
class Bit
|
714
|
+
include Namespaces
|
715
|
+
attr_reader :ctx
|
716
|
+
|
717
|
+
def initialize(ctx)
|
718
|
+
@ctx = ctx
|
536
719
|
end
|
537
720
|
|
538
|
-
def
|
539
|
-
|
721
|
+
def connection
|
722
|
+
ctx.connection
|
540
723
|
end
|
541
724
|
|
542
|
-
def
|
543
|
-
|
725
|
+
def stanza
|
726
|
+
ctx.stanza
|
544
727
|
end
|
545
728
|
|
546
|
-
def
|
547
|
-
|
548
|
-
read_attr(n, 'code') if n
|
729
|
+
def read_attr(*args,&blk)
|
730
|
+
ctx.read_attr(*args,&blk)
|
549
731
|
end
|
550
732
|
|
551
|
-
def
|
552
|
-
|
553
|
-
jid_str = read_attr(n, 'jid') if n
|
554
|
-
@connection.entity jid_str if jid_str
|
733
|
+
def xpath(*args)
|
734
|
+
ctx.xpath(*args)
|
555
735
|
end
|
556
736
|
|
557
|
-
def
|
558
|
-
|
559
|
-
read_attr(n, 'affiliation') if n
|
737
|
+
def xpath?(*args)
|
738
|
+
ctx.xpath(*args)
|
560
739
|
end
|
740
|
+
end
|
561
741
|
|
562
|
-
|
563
|
-
|
564
|
-
|
742
|
+
module Bits
|
743
|
+
class Stanza < Bit
|
744
|
+
include Contexts::IncomingStanza
|
745
|
+
end
|
746
|
+
class Error < Bit
|
747
|
+
include Contexts::Error
|
748
|
+
end
|
749
|
+
class Presence < Bit
|
750
|
+
include Contexts::Presence
|
751
|
+
end
|
752
|
+
class Message < Bit
|
753
|
+
include Contexts::Message
|
754
|
+
end
|
755
|
+
class Iq < Bit
|
756
|
+
include Contexts::Iq
|
757
|
+
end
|
758
|
+
class Delay < Bit
|
759
|
+
include Contexts::Delay
|
760
|
+
end
|
761
|
+
class Discoinfos < Bit
|
762
|
+
include Contexts::Discoinfos
|
763
|
+
end
|
764
|
+
class Discoitems < Bit
|
765
|
+
include Contexts::Discoitems
|
766
|
+
end
|
767
|
+
class Command < Bit
|
768
|
+
include Contexts::Command
|
769
|
+
end
|
770
|
+
class Dataforms < Bit
|
771
|
+
include Contexts::Dataforms
|
772
|
+
end
|
773
|
+
class Capabilities < Bit
|
774
|
+
include Contexts::Capabilities
|
775
|
+
end
|
776
|
+
class Roster < Bit
|
777
|
+
include Contexts::Roster
|
778
|
+
end
|
779
|
+
class Tune < Bit
|
780
|
+
include Contexts::Tune
|
781
|
+
end
|
782
|
+
class Nickname < Bit
|
783
|
+
include Contexts::Nickname
|
784
|
+
end
|
785
|
+
class Geolocation < Bit
|
786
|
+
include Contexts::Geolocation
|
787
|
+
end
|
788
|
+
class Useractivity < Bit
|
789
|
+
include Contexts::Useractivity
|
790
|
+
end
|
791
|
+
class Mood < Bit
|
792
|
+
include Contexts::Mood
|
793
|
+
end
|
794
|
+
class Bytestreams < Bit
|
795
|
+
include Contexts::Bytestreams
|
796
|
+
end
|
797
|
+
class Streaminitiation < Bit
|
798
|
+
include Contexts::Streaminitiation
|
799
|
+
end
|
800
|
+
class Mucuser < Bit
|
801
|
+
include Contexts::Mucuser
|
565
802
|
end
|
566
803
|
end
|
804
|
+
|
567
805
|
end
|
568
806
|
end
|