blather 0.3.4 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/README.rdoc +41 -12
- data/examples/echo.rb +1 -1
- data/examples/execute.rb +0 -5
- data/examples/pubsub/cli.rb +64 -0
- data/examples/pubsub/ping_pong.rb +18 -0
- data/examples/rosterprint.rb +14 -0
- data/examples/xmpp4r/echo.rb +35 -0
- data/lib/blather.rb +35 -12
- data/lib/blather/client.rb +1 -1
- data/lib/blather/client/client.rb +19 -13
- data/lib/blather/client/dsl.rb +16 -0
- data/lib/blather/client/dsl/pubsub.rb +133 -0
- data/lib/blather/core_ext/active_support.rb +1 -117
- data/lib/blather/core_ext/active_support/inheritable_attributes.rb +117 -0
- data/lib/blather/core_ext/nokogiri.rb +35 -0
- data/lib/blather/errors.rb +3 -20
- data/lib/blather/errors/sasl_error.rb +3 -1
- data/lib/blather/errors/stanza_error.rb +10 -17
- data/lib/blather/errors/stream_error.rb +11 -14
- data/lib/blather/jid.rb +1 -0
- data/lib/blather/roster.rb +9 -0
- data/lib/blather/roster_item.rb +6 -1
- data/lib/blather/stanza.rb +35 -18
- data/lib/blather/stanza/disco.rb +7 -1
- data/lib/blather/stanza/disco/disco_info.rb +45 -33
- data/lib/blather/stanza/disco/disco_items.rb +32 -21
- data/lib/blather/stanza/iq.rb +13 -8
- data/lib/blather/stanza/iq/query.rb +16 -8
- data/lib/blather/stanza/iq/roster.rb +33 -22
- data/lib/blather/stanza/message.rb +20 -31
- data/lib/blather/stanza/presence.rb +3 -5
- data/lib/blather/stanza/presence/status.rb +13 -21
- data/lib/blather/stanza/presence/subscription.rb +11 -16
- data/lib/blather/stanza/pubsub.rb +63 -0
- data/lib/blather/stanza/pubsub/affiliations.rb +50 -0
- data/lib/blather/stanza/pubsub/create.rb +43 -0
- data/lib/blather/stanza/pubsub/errors.rb +9 -0
- data/lib/blather/stanza/pubsub/event.rb +77 -0
- data/lib/blather/stanza/pubsub/items.rb +63 -0
- data/lib/blather/stanza/pubsub/publish.rb +58 -0
- data/lib/blather/stanza/pubsub/retract.rb +53 -0
- data/lib/blather/stanza/pubsub/subscribe.rb +42 -0
- data/lib/blather/stanza/pubsub/subscription.rb +66 -0
- data/lib/blather/stanza/pubsub/subscriptions.rb +55 -0
- data/lib/blather/stanza/pubsub/unsubscribe.rb +42 -0
- data/lib/blather/stanza/pubsub_owner.rb +41 -0
- data/lib/blather/stanza/pubsub_owner/delete.rb +34 -0
- data/lib/blather/stanza/pubsub_owner/purge.rb +34 -0
- data/lib/blather/stream.rb +76 -168
- data/lib/blather/stream/client.rb +1 -2
- data/lib/blather/stream/component.rb +9 -5
- data/lib/blather/stream/features.rb +53 -0
- data/lib/blather/stream/features/resource.rb +63 -0
- data/lib/blather/stream/{sasl.rb → features/sasl.rb} +53 -52
- data/lib/blather/stream/features/session.rb +44 -0
- data/lib/blather/stream/features/tls.rb +28 -0
- data/lib/blather/stream/parser.rb +70 -46
- data/lib/blather/xmpp_node.rb +113 -52
- data/spec/blather/client/client_spec.rb +44 -58
- data/spec/blather/client/dsl/pubsub_spec.rb +465 -0
- data/spec/blather/client/dsl_spec.rb +19 -6
- data/spec/blather/core_ext/nokogiri_spec.rb +83 -0
- data/spec/blather/errors/sasl_error_spec.rb +8 -8
- data/spec/blather/errors/stanza_error_spec.rb +25 -33
- data/spec/blather/errors/stream_error_spec.rb +21 -16
- data/spec/blather/errors_spec.rb +4 -11
- data/spec/blather/jid_spec.rb +31 -30
- data/spec/blather/roster_item_spec.rb +34 -23
- data/spec/blather/roster_spec.rb +27 -12
- data/spec/blather/stanza/discos/disco_info_spec.rb +61 -42
- data/spec/blather/stanza/discos/disco_items_spec.rb +47 -35
- data/spec/blather/stanza/iq/query_spec.rb +34 -11
- data/spec/blather/stanza/iq/roster_spec.rb +47 -30
- data/spec/blather/stanza/iq_spec.rb +19 -14
- data/spec/blather/stanza/message_spec.rb +30 -17
- data/spec/blather/stanza/presence/status_spec.rb +43 -20
- data/spec/blather/stanza/presence/subscription_spec.rb +41 -21
- data/spec/blather/stanza/presence_spec.rb +34 -21
- data/spec/blather/stanza/pubsub/affiliations_spec.rb +57 -0
- data/spec/blather/stanza/pubsub/create_spec.rb +56 -0
- data/spec/blather/stanza/pubsub/event_spec.rb +84 -0
- data/spec/blather/stanza/pubsub/items_spec.rb +79 -0
- data/spec/blather/stanza/pubsub/publish_spec.rb +83 -0
- data/spec/blather/stanza/pubsub/retract_spec.rb +75 -0
- data/spec/blather/stanza/pubsub/subscribe_spec.rb +61 -0
- data/spec/blather/stanza/pubsub/subscription_spec.rb +97 -0
- data/spec/blather/stanza/pubsub/subscriptions_spec.rb +59 -0
- data/spec/blather/stanza/pubsub/unsubscribe_spec.rb +61 -0
- data/spec/blather/stanza/pubsub_owner/delete_spec.rb +50 -0
- data/spec/blather/stanza/pubsub_owner/purge_spec.rb +50 -0
- data/spec/blather/stanza/pubsub_owner_spec.rb +27 -0
- data/spec/blather/stanza/pubsub_spec.rb +62 -0
- data/spec/blather/stanza_spec.rb +53 -38
- data/spec/blather/stream/client_spec.rb +231 -88
- data/spec/blather/stream/component_spec.rb +14 -5
- data/spec/blather/stream/parser_spec.rb +145 -0
- data/spec/blather/xmpp_node_spec.rb +192 -96
- data/spec/fixtures/pubsub.rb +311 -0
- data/spec/spec_helper.rb +5 -4
- metadata +54 -18
- data/Rakefile +0 -139
- data/ext/extconf.rb +0 -65
- data/ext/push_parser.c +0 -209
- data/lib/blather/core_ext/libxml.rb +0 -28
- data/lib/blather/stream/resource.rb +0 -48
- data/lib/blather/stream/session.rb +0 -36
- data/lib/blather/stream/stream_handler.rb +0 -39
- data/lib/blather/stream/tls.rb +0 -33
- data/spec/blather/core_ext/libxml_spec.rb +0 -58
data/LICENSE
CHANGED
data/README.rdoc
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
= Blather
|
2
2
|
|
3
|
-
|
3
|
+
XMPP DSL (and more) for Ruby written on EventMachine and Nokogiri.
|
4
4
|
|
5
5
|
== Features
|
6
6
|
|
7
7
|
* evented architecture
|
8
|
-
* uses
|
8
|
+
* uses Nokogiri
|
9
9
|
* simplified starting point
|
10
10
|
|
11
11
|
== Project Pages
|
@@ -18,11 +18,7 @@ GitHub Docs:: http://docs.github.com/sprsquish/blather
|
|
18
18
|
|
19
19
|
RubyForge:: http://rubyforge.org/projects/squishtech
|
20
20
|
|
21
|
-
RDocs:: http://squishtech.rubyforge.org/blather
|
22
|
-
|
23
|
-
== Author
|
24
|
-
|
25
|
-
Jeff Smick <sprsquish@gmail.com>
|
21
|
+
RDocs:: http://squishtech.rubyforge.org/blather
|
26
22
|
|
27
23
|
= Usage
|
28
24
|
|
@@ -32,7 +28,7 @@ Jeff Smick <sprsquish@gmail.com>
|
|
32
28
|
|
33
29
|
== Example
|
34
30
|
|
35
|
-
See the
|
31
|
+
See the examples directory for more advanced examples.
|
36
32
|
|
37
33
|
This will auto-accept any subscription requests and echo back any chat messages.
|
38
34
|
|
@@ -73,7 +69,7 @@ The different types of guards are:
|
|
73
69
|
# Equivalent to stanza.chat?
|
74
70
|
message :chat?
|
75
71
|
|
76
|
-
# Hash with value (:body => 'exit')
|
72
|
+
# Hash with any value (:body => 'exit')
|
77
73
|
# Calls the key on the stanza and checks for equality
|
78
74
|
# Equivalent to stanza.body == 'exit'
|
79
75
|
message :body => 'exit'
|
@@ -99,6 +95,12 @@ The different types of guards are:
|
|
99
95
|
# Equivalent to stanza.body == 'foo' || stanza.body == 'baz'
|
100
96
|
message [{:body => 'foo'}, {:body => 'baz'}]
|
101
97
|
|
98
|
+
# XPath
|
99
|
+
# Runs the xpath query on the stanza and checks for results
|
100
|
+
# This guard type cannot be combined with other guards
|
101
|
+
# Equivalent to !stanza.find('/iq/ns:pubsub', :ns => 'pubsub:namespace').empty?
|
102
|
+
iq '/iq/ns:pubsub', :ns => 'pubsub:namespace'
|
103
|
+
|
102
104
|
== On the Command Line:
|
103
105
|
|
104
106
|
Default usage is:
|
@@ -117,11 +119,38 @@ Command line options:
|
|
117
119
|
|
118
120
|
= TODO
|
119
121
|
|
120
|
-
* Add XPath guard that passes the result to the handler
|
121
122
|
* Add Disco the the DSL
|
122
|
-
* PubSub (XEP-0060: http://xmpp.org/extensions/xep-0060.html)
|
123
123
|
* More examples (Re-write XMPP4R examples into Blather)
|
124
124
|
|
125
|
+
= Author
|
126
|
+
|
127
|
+
Jeff Smick <sprsquish@gmail.com>
|
128
|
+
|
129
|
+
= Contributors
|
130
|
+
|
131
|
+
Nolan Darilek <nolan@thewordnerd.info>
|
132
|
+
|
125
133
|
= License
|
126
134
|
|
127
|
-
|
135
|
+
Blather
|
136
|
+
|
137
|
+
Copyright (c) 2009 Jeff Smick
|
138
|
+
|
139
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
140
|
+
a copy of this software and associated documentation files (the
|
141
|
+
"Software"), to deal in the Software without restriction, including
|
142
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
143
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
144
|
+
permit persons to whom the Software is furnished to do so, subject to
|
145
|
+
the following conditions:
|
146
|
+
|
147
|
+
The above copyright notice and this permission notice shall be
|
148
|
+
included in all copies or substantial portions of the Software.
|
149
|
+
|
150
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
151
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
152
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
153
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
154
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
155
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
156
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/examples/echo.rb
CHANGED
data/examples/execute.rb
CHANGED
@@ -0,0 +1,64 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'blather/client'
|
4
|
+
|
5
|
+
#ls
|
6
|
+
#cd
|
7
|
+
#cat
|
8
|
+
#Blather::LOG.level = Logger::DEBUG
|
9
|
+
module CliHandler
|
10
|
+
include EM::Protocols::LineText2
|
11
|
+
|
12
|
+
def ls(node)
|
13
|
+
pubsub.node(parse_dir(node)) do |result|
|
14
|
+
cur = node.split('/')
|
15
|
+
puts
|
16
|
+
puts result.items.map { |i| (i.node.split('/') - cur).join('/') }.join("\n")
|
17
|
+
start_line
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def cd(node)
|
22
|
+
@node = parse_dir(node)
|
23
|
+
start_line
|
24
|
+
end
|
25
|
+
|
26
|
+
def cat(item)
|
27
|
+
end
|
28
|
+
|
29
|
+
def connect(who)
|
30
|
+
@who = who
|
31
|
+
puts "connected to '#{who}'"
|
32
|
+
end
|
33
|
+
|
34
|
+
def exit(_)
|
35
|
+
EM.stop
|
36
|
+
end
|
37
|
+
|
38
|
+
def initialize
|
39
|
+
$stdout.sync = true
|
40
|
+
@node = ''
|
41
|
+
@who = ''
|
42
|
+
start_line
|
43
|
+
end
|
44
|
+
|
45
|
+
def start_line
|
46
|
+
puts "\n/#{@node}> "
|
47
|
+
end
|
48
|
+
|
49
|
+
def receive_line(line)
|
50
|
+
return unless line =~ /(connect|exit|ls|cd|cat)\s?(.*)/i
|
51
|
+
__send__ $1, $2
|
52
|
+
end
|
53
|
+
|
54
|
+
def parse_dir(list)
|
55
|
+
return '' if list == '/'
|
56
|
+
cur = @node.split('/')
|
57
|
+
list.split('/').each { |dir| dir == '..' ? cur.pop : (cur << dir) }
|
58
|
+
cur * '/'
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
setup 'echo@jabber.local', 'echo'
|
63
|
+
pubsub_host 'pubsub.jabber.local'
|
64
|
+
when_ready { EM.open_keyboard CliHandler }
|
@@ -0,0 +1,18 @@
|
|
1
|
+
setup 'ping-pong@jabber.local', 'ping-pong'
|
2
|
+
|
3
|
+
pubsub.host = 'pubsub.jabber.local'
|
4
|
+
|
5
|
+
pubsub_event :node => 'ping' do |node|
|
6
|
+
pubsub.publish 'pong', node.payload
|
7
|
+
end
|
8
|
+
|
9
|
+
pubsub_event :node => 'pong' do |node|
|
10
|
+
x = node.payload.to_i
|
11
|
+
if x > 0
|
12
|
+
pubsub.publish 'ping', (x - 1)
|
13
|
+
else
|
14
|
+
shutdown
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
when_ready { pubsub.publish 'ping', 3 }
|
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# Prints out each roster entry
|
4
|
+
|
5
|
+
require 'blather/client'
|
6
|
+
|
7
|
+
when_ready do
|
8
|
+
roster.grouped.each do |group, items|
|
9
|
+
puts "#{'*'*3} #{group || 'Ungrouped'} #{'*'*3}"
|
10
|
+
items.each { |item| puts "- #{item.name} (#{item.jid})" }
|
11
|
+
puts
|
12
|
+
end
|
13
|
+
shutdown
|
14
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
# This bot will reply to every message it receives. To end the game, send 'exit'
|
4
|
+
|
5
|
+
require 'xmpp4r/client'
|
6
|
+
include Jabber
|
7
|
+
|
8
|
+
# settings
|
9
|
+
if ARGV.length != 2
|
10
|
+
puts "Run with ./echo_thread.rb user@server/resource password"
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
myJID = JID.new(ARGV[0])
|
14
|
+
myPassword = ARGV[1]
|
15
|
+
cl = Client.new(myJID)
|
16
|
+
cl.connect
|
17
|
+
cl.auth(myPassword)
|
18
|
+
cl.send(Presence.new)
|
19
|
+
puts "Connected ! send messages to #{myJID.strip.to_s}."
|
20
|
+
mainthread = Thread.current
|
21
|
+
cl.add_message_callback do |m|
|
22
|
+
if m.type != :error
|
23
|
+
m2 = Message.new(m.from, "You sent: #{m.body}")
|
24
|
+
m2.type = m.type
|
25
|
+
cl.send(m2)
|
26
|
+
if m.body == 'exit'
|
27
|
+
m2 = Message.new(m.from, "Exiting ...")
|
28
|
+
m2.type = m.type
|
29
|
+
cl.send(m2)
|
30
|
+
mainthread.wakeup
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
Thread.stop
|
35
|
+
cl.close
|
data/lib/blather.rb
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
# Require the necessary files
|
2
|
-
require File.join(File.dirname(__FILE__), *%w[.. ext push_parser])
|
3
2
|
%w[
|
4
3
|
rubygems
|
5
4
|
eventmachine
|
6
|
-
|
5
|
+
nokogiri
|
7
6
|
digest/md5
|
8
7
|
logger
|
9
8
|
|
10
9
|
blather/core_ext/active_support
|
11
|
-
blather/core_ext/
|
10
|
+
blather/core_ext/nokogiri
|
12
11
|
|
13
12
|
blather/errors
|
14
13
|
blather/errors/sasl_error
|
@@ -31,20 +30,44 @@ require File.join(File.dirname(__FILE__), *%w[.. ext push_parser])
|
|
31
30
|
blather/stanza/presence/status
|
32
31
|
blather/stanza/presence/subscription
|
33
32
|
|
33
|
+
blather/stanza/pubsub
|
34
|
+
blather/stanza/pubsub/affiliations
|
35
|
+
blather/stanza/pubsub/create
|
36
|
+
blather/stanza/pubsub/event
|
37
|
+
blather/stanza/pubsub/items
|
38
|
+
blather/stanza/pubsub/publish
|
39
|
+
blather/stanza/pubsub/retract
|
40
|
+
blather/stanza/pubsub/subscribe
|
41
|
+
blather/stanza/pubsub/subscription
|
42
|
+
blather/stanza/pubsub/subscriptions
|
43
|
+
blather/stanza/pubsub/unsubscribe
|
44
|
+
|
45
|
+
blather/stanza/pubsub_owner
|
46
|
+
blather/stanza/pubsub_owner/delete
|
47
|
+
blather/stanza/pubsub_owner/purge
|
48
|
+
|
34
49
|
blather/stream
|
35
50
|
blather/stream/client
|
36
51
|
blather/stream/component
|
37
|
-
blather/stream/stream_handler
|
38
52
|
blather/stream/parser
|
39
|
-
blather/stream/
|
40
|
-
blather/stream/
|
41
|
-
blather/stream/
|
42
|
-
blather/stream/
|
53
|
+
blather/stream/features
|
54
|
+
blather/stream/features/resource
|
55
|
+
blather/stream/features/sasl
|
56
|
+
blather/stream/features/session
|
57
|
+
blather/stream/features/tls
|
43
58
|
].each { |r| require r }
|
44
59
|
|
45
|
-
XML.indent_tree_output = false
|
46
|
-
|
47
60
|
module Blather
|
48
|
-
|
49
|
-
|
61
|
+
@@logger = nil
|
62
|
+
def self.logger
|
63
|
+
unless @@logger
|
64
|
+
self.logger = Logger.new($stdout)
|
65
|
+
self.logger.level = Logger::INFO
|
66
|
+
end
|
67
|
+
@@logger
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.logger=(logger)
|
71
|
+
@@logger = logger
|
72
|
+
end
|
50
73
|
end
|
data/lib/blather/client.rb
CHANGED
@@ -60,7 +60,7 @@ at_exit do
|
|
60
60
|
if options[:log]
|
61
61
|
log = File.new(options[:log], 'a')
|
62
62
|
log.sync = options[:debug]
|
63
|
-
Blather
|
63
|
+
Blather.logger.level = Logger::DEBUG if options[:debug]
|
64
64
|
$stdout.reopen log
|
65
65
|
$stderr.reopen $stdout
|
66
66
|
end
|
@@ -40,7 +40,8 @@ module Blather #:nodoc:
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def setup(jid, password, host = nil, port = nil)
|
43
|
-
@
|
43
|
+
@jid = JID.new(jid)
|
44
|
+
@setup = [@jid, password]
|
44
45
|
@setup << host if host
|
45
46
|
@setup << port if port
|
46
47
|
self
|
@@ -63,7 +64,6 @@ module Blather #:nodoc:
|
|
63
64
|
end
|
64
65
|
|
65
66
|
def write(stanza)
|
66
|
-
stanza.from ||= jid if stanza.respond_to?(:from)
|
67
67
|
@stream.send(stanza) if @stream
|
68
68
|
end
|
69
69
|
|
@@ -73,11 +73,7 @@ module Blather #:nodoc:
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def post_init
|
76
|
-
|
77
|
-
when Stream::Component then ready!
|
78
|
-
when Stream::Client then client_post_init
|
79
|
-
else raise "Don't know #{@stream.class} stream type. How the hell did this happen!?"
|
80
|
-
end
|
76
|
+
self.jid.node ? client_post_init : ready!
|
81
77
|
end
|
82
78
|
|
83
79
|
def close
|
@@ -93,7 +89,7 @@ module Blather #:nodoc:
|
|
93
89
|
handler.call stanza
|
94
90
|
else
|
95
91
|
stanza.handler_heirarchy.each do |type|
|
96
|
-
break if call_handler_for(type, stanza) && (stanza.is_a?(BlatherError) || stanza.type == :iq)
|
92
|
+
break if call_handler_for(type, stanza)# && (stanza.is_a?(BlatherError) || stanza.type == :iq)
|
97
93
|
end
|
98
94
|
end
|
99
95
|
end
|
@@ -132,8 +128,15 @@ module Blather #:nodoc:
|
|
132
128
|
|
133
129
|
def call_handler_for(type, stanza)
|
134
130
|
if @handlers[type]
|
135
|
-
@handlers[type].find
|
136
|
-
|
131
|
+
@handlers[type].find do |guards, handler|
|
132
|
+
if guards.first.is_a?(String)
|
133
|
+
unless (result = stanza.find(*guards)).empty?
|
134
|
+
handler.call(stanza, result)
|
135
|
+
end
|
136
|
+
elsif !guarded?(guards, stanza)
|
137
|
+
handler.call(stanza)
|
138
|
+
end
|
139
|
+
end
|
137
140
|
end
|
138
141
|
end
|
139
142
|
|
@@ -171,9 +174,12 @@ module Blather #:nodoc:
|
|
171
174
|
def check_guards(guards)
|
172
175
|
guards.each do |guard|
|
173
176
|
case guard
|
174
|
-
when Array
|
175
|
-
|
176
|
-
|
177
|
+
when Array
|
178
|
+
guard.each { |g| check_guards([g]) }
|
179
|
+
when Symbol, Proc, Hash, String
|
180
|
+
nil
|
181
|
+
else
|
182
|
+
raise "Bad guard: #{guard.inspect}"
|
177
183
|
end
|
178
184
|
end
|
179
185
|
end
|
data/lib/blather/client/dsl.rb
CHANGED
@@ -2,11 +2,27 @@ require File.join(File.dirname(__FILE__), 'client')
|
|
2
2
|
|
3
3
|
module Blather
|
4
4
|
module DSL
|
5
|
+
|
6
|
+
autoload :PubSub, File.expand_path(File.join(File.dirname(__FILE__), *%w[dsl pubsub]))
|
7
|
+
|
5
8
|
def client
|
6
9
|
@client ||= Client.new
|
7
10
|
end
|
8
11
|
module_function :client
|
9
12
|
|
13
|
+
def pubsub
|
14
|
+
@pubsub ||= PubSub.new jid.domain
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# Push data to the stream
|
19
|
+
# This works such that it can be chained:
|
20
|
+
# self << stanza1 << stanza2 << "raw data"
|
21
|
+
def <<(stanza)
|
22
|
+
write stanza
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
10
26
|
##
|
11
27
|
# Prepare server settings
|
12
28
|
# setup [node@domain/resource], [password], [host], [port]
|
@@ -0,0 +1,133 @@
|
|
1
|
+
module Blather
|
2
|
+
module DSL
|
3
|
+
|
4
|
+
class PubSub
|
5
|
+
attr_accessor :host
|
6
|
+
|
7
|
+
def initialize(host)
|
8
|
+
@host = host
|
9
|
+
end
|
10
|
+
|
11
|
+
##
|
12
|
+
# Retrieve Affiliations
|
13
|
+
# Yields a hash of affiliations in the form:
|
14
|
+
# {:aff_type => ['node1', 'node2']}
|
15
|
+
def affiliations(host = nil, &callback)
|
16
|
+
request Stanza::PubSub::Affiliations.new(:get, send_to(host)), :list, callback
|
17
|
+
end
|
18
|
+
|
19
|
+
##
|
20
|
+
# Retrieve Subscriptions
|
21
|
+
# Yields a hash of subscriptions in the form:
|
22
|
+
# {:sub_type => [{:node => 'node1', :jid => 'j@d'}]}
|
23
|
+
def subscriptions(host = nil, &callback)
|
24
|
+
request Stanza::PubSub::Subscriptions.new(:get, send_to(host)), :list, callback
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Discover Nodes
|
29
|
+
# Yields a list of DiscoItem::Item objects
|
30
|
+
# +path+ is the node's path. Default is '/'
|
31
|
+
def nodes(path = nil, host = nil, &callback)
|
32
|
+
path ||= '/'
|
33
|
+
stanza = Stanza::DiscoItems.new(:get, path)
|
34
|
+
stanza.to = send_to(host)
|
35
|
+
request stanza, :items, callback
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# Discover node information
|
40
|
+
# Yields a DiscoInfo node
|
41
|
+
# +path+ is the node's path
|
42
|
+
def node(path, host = nil, &callback)
|
43
|
+
stanza = Stanza::DiscoInfo.new(:get, path)
|
44
|
+
stanza.to = send_to(host)
|
45
|
+
request stanza, nil, callback
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Retrieve items for a node
|
50
|
+
# +path+ is the node's path
|
51
|
+
# +list+ can be an array of items to retrieve
|
52
|
+
# +max+ can be the maximum number of items to return
|
53
|
+
def items(path, list = [], max = nil, host = nil, &callback)
|
54
|
+
request Stanza::PubSub::Items.request(send_to(host), path, list, max), :items, callback
|
55
|
+
end
|
56
|
+
|
57
|
+
##
|
58
|
+
# Subscribe to a node
|
59
|
+
# Yields the resulting Subscription object
|
60
|
+
# +node+ is the node to subscribe to
|
61
|
+
# +jid+ is the jid that should be used. Defaults to the stripped current JID
|
62
|
+
def subscribe(node, jid = nil, host = nil)
|
63
|
+
jid ||= DSL.client.jid.stripped
|
64
|
+
request(Stanza::PubSub::Subscribe.new(:set, send_to(host), node, jid)) { |n| yield n if block_given? }
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# Unsubscribe from a node
|
69
|
+
# Yields the resulting Unsubscribe object
|
70
|
+
# +node+ is the node to subscribe to
|
71
|
+
# +jid+ is the jid that should be used. Defaults to the stripped current JID
|
72
|
+
def unsubscribe(node, jid = nil, host = nil)
|
73
|
+
jid ||= DSL.client.jid.stripped
|
74
|
+
request(Stanza::PubSub::Unsubscribe.new(:set, send_to(host), node, jid)) { |n| yield n if block_given? }
|
75
|
+
end
|
76
|
+
|
77
|
+
##
|
78
|
+
# Publish an item to a node
|
79
|
+
# Yields the resulting Publish node
|
80
|
+
# +node+ is the node to publish to
|
81
|
+
# +payload+ is the payload to send (see Blather::Stanza::PubSub::Publish for details)
|
82
|
+
def publish(node, payload, host = nil)
|
83
|
+
request(Stanza::PubSub::Publish.new(send_to(host), node, :set, payload)) { |n| yield n if block_given? }
|
84
|
+
end
|
85
|
+
|
86
|
+
##
|
87
|
+
# Delete items from a node
|
88
|
+
# Yields the resulting node
|
89
|
+
# +node+ is the node to retract items from
|
90
|
+
# +ids+ is a list of ids to retract. This can also be a single id
|
91
|
+
def retract(node, ids = [], host = nil)
|
92
|
+
request(Stanza::PubSub::Retract.new(send_to(host), node, :set, ids)) { |n| yield n if block_given? }
|
93
|
+
end
|
94
|
+
|
95
|
+
##
|
96
|
+
# Create a node
|
97
|
+
# Yields the resulting node
|
98
|
+
# This does not (yet) handle configuration
|
99
|
+
# +node+ is the node to create
|
100
|
+
def create(node, host = nil)
|
101
|
+
request(Stanza::PubSub::Create.new(:set, send_to(host), node)) { |n| yield n if block_given? }
|
102
|
+
end
|
103
|
+
|
104
|
+
##
|
105
|
+
# Purge all node items
|
106
|
+
# Yields the resulting node
|
107
|
+
# +node+ is the node to purge
|
108
|
+
def purge(node, host = nil)
|
109
|
+
request(Stanza::PubSubOwner::Purge.new(:set, send_to(host), node)) { |n| yield n if block_given? }
|
110
|
+
end
|
111
|
+
|
112
|
+
##
|
113
|
+
# Delete a node
|
114
|
+
# Yields the resulting node
|
115
|
+
# +node+ is the node to delete
|
116
|
+
def delete(node, host = nil)
|
117
|
+
request(Stanza::PubSubOwner::Delete.new(:set, send_to(host), node)) { |n| yield n if block_given? }
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
def request(node, method = nil, callback = nil, &block)
|
122
|
+
block = lambda { |node| callback.call(method ? node.__send__(method) : node) } unless block_given?
|
123
|
+
DSL.client.write_with_handler(node, &block)
|
124
|
+
end
|
125
|
+
|
126
|
+
def send_to(host = nil)
|
127
|
+
raise 'You must provide a host' unless (host ||= @host)
|
128
|
+
host
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
end
|
133
|
+
end
|