ln-xmpp4r 0.5
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/CHANGELOG +91 -0
- data/COPYING +340 -0
- data/LICENSE +59 -0
- data/README.rdoc +113 -0
- data/README_ruby19.txt +43 -0
- data/Rakefile +252 -0
- data/data/doc/xmpp4r/examples/advanced/adventure/README +56 -0
- data/data/doc/xmpp4r/examples/advanced/adventure/adventure.rb +23 -0
- data/data/doc/xmpp4r/examples/advanced/adventure/adventuremuc.rb +136 -0
- data/data/doc/xmpp4r/examples/advanced/adventure/cube.xml +15 -0
- data/data/doc/xmpp4r/examples/advanced/adventure/tower.xml +69 -0
- data/data/doc/xmpp4r/examples/advanced/adventure/world.rb +424 -0
- data/data/doc/xmpp4r/examples/advanced/fileserve.conf +11 -0
- data/data/doc/xmpp4r/examples/advanced/fileserve.rb +346 -0
- data/data/doc/xmpp4r/examples/advanced/getonline.rb +56 -0
- data/data/doc/xmpp4r/examples/advanced/gtkmucclient.rb +315 -0
- data/data/doc/xmpp4r/examples/advanced/migrate.rb +88 -0
- data/data/doc/xmpp4r/examples/advanced/minimuc.rb +266 -0
- data/data/doc/xmpp4r/examples/advanced/pep-aggregator/index.xsl +235 -0
- data/data/doc/xmpp4r/examples/advanced/pep-aggregator/pep-aggregator.rb +147 -0
- data/data/doc/xmpp4r/examples/advanced/recvfile.rb +84 -0
- data/data/doc/xmpp4r/examples/advanced/rosterdiscovery.rb +129 -0
- data/data/doc/xmpp4r/examples/advanced/sendfile.conf +10 -0
- data/data/doc/xmpp4r/examples/advanced/sendfile.rb +72 -0
- data/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr.rb +51 -0
- data/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr_jabber.rb +43 -0
- data/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr_test.rb +10 -0
- data/data/doc/xmpp4r/examples/advanced/versionpoll.rb +109 -0
- data/data/doc/xmpp4r/examples/advanced/xmpping.rb +146 -0
- data/data/doc/xmpp4r/examples/advanced/xmppingrc.sample +14 -0
- data/data/doc/xmpp4r/examples/basic/change_password.rb +41 -0
- data/data/doc/xmpp4r/examples/basic/client.rb +70 -0
- data/data/doc/xmpp4r/examples/basic/component.rb +11 -0
- data/data/doc/xmpp4r/examples/basic/echo.rb +37 -0
- data/data/doc/xmpp4r/examples/basic/jabbersend.rb +41 -0
- data/data/doc/xmpp4r/examples/basic/mass_sender.rb +68 -0
- data/data/doc/xmpp4r/examples/basic/muc_owner_config.rb +12 -0
- data/data/doc/xmpp4r/examples/basic/mucinfo.rb +41 -0
- data/data/doc/xmpp4r/examples/basic/mucsimplebot.rb +82 -0
- data/data/doc/xmpp4r/examples/basic/register.rb +42 -0
- data/data/doc/xmpp4r/examples/basic/remove_registration.rb +18 -0
- data/data/doc/xmpp4r/examples/basic/roster.rb +44 -0
- data/data/doc/xmpp4r/examples/basic/rosterprint.rb +50 -0
- data/data/doc/xmpp4r/examples/basic/rosterrename.rb +34 -0
- data/data/doc/xmpp4r/examples/basic/rosterwatch.rb +171 -0
- data/data/doc/xmpp4r/examples/basic/send_vcard.rb +67 -0
- data/data/doc/xmpp4r/examples/basic/tune_client.rb +56 -0
- data/data/doc/xmpp4r/examples/basic/tune_server.rb +58 -0
- data/data/doc/xmpp4r/examples/basic/versionbot.rb +75 -0
- data/lib/xmpp4r.rb +116 -0
- data/lib/xmpp4r/base64.rb +32 -0
- data/lib/xmpp4r/bytestreams.rb +15 -0
- data/lib/xmpp4r/bytestreams/helper/filetransfer.rb +319 -0
- data/lib/xmpp4r/bytestreams/helper/ibb/base.rb +257 -0
- data/lib/xmpp4r/bytestreams/helper/ibb/initiator.rb +31 -0
- data/lib/xmpp4r/bytestreams/helper/ibb/target.rb +54 -0
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/base.rb +152 -0
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/initiator.rb +86 -0
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb +198 -0
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/socks5.rb +65 -0
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/target.rb +79 -0
- data/lib/xmpp4r/bytestreams/iq/bytestreams.rb +170 -0
- data/lib/xmpp4r/bytestreams/iq/si.rb +206 -0
- data/lib/xmpp4r/callbacks.rb +133 -0
- data/lib/xmpp4r/caps.rb +1 -0
- data/lib/xmpp4r/caps/c.rb +67 -0
- data/lib/xmpp4r/caps/helper/generator.rb +160 -0
- data/lib/xmpp4r/caps/helper/helper.rb +84 -0
- data/lib/xmpp4r/client.rb +344 -0
- data/lib/xmpp4r/command/helper/responder.rb +53 -0
- data/lib/xmpp4r/command/iq/command.rb +154 -0
- data/lib/xmpp4r/component.rb +103 -0
- data/lib/xmpp4r/connection.rb +223 -0
- data/lib/xmpp4r/dataforms.rb +5 -0
- data/lib/xmpp4r/dataforms/x/data.rb +297 -0
- data/lib/xmpp4r/debuglog.rb +63 -0
- data/lib/xmpp4r/delay.rb +5 -0
- data/lib/xmpp4r/delay/x/delay.rb +99 -0
- data/lib/xmpp4r/discovery.rb +8 -0
- data/lib/xmpp4r/discovery/helper/helper.rb +58 -0
- data/lib/xmpp4r/discovery/helper/responder.rb +165 -0
- data/lib/xmpp4r/discovery/iq/discoinfo.rb +211 -0
- data/lib/xmpp4r/discovery/iq/discoitems.rb +147 -0
- data/lib/xmpp4r/errors.rb +284 -0
- data/lib/xmpp4r/feature_negotiation.rb +5 -0
- data/lib/xmpp4r/feature_negotiation/iq/feature.rb +28 -0
- data/lib/xmpp4r/framework/base.rb +55 -0
- data/lib/xmpp4r/framework/bot.rb +148 -0
- data/lib/xmpp4r/httpbinding.rb +5 -0
- data/lib/xmpp4r/httpbinding/client.rb +275 -0
- data/lib/xmpp4r/idgenerator.rb +37 -0
- data/lib/xmpp4r/iq.rb +221 -0
- data/lib/xmpp4r/jid.rb +167 -0
- data/lib/xmpp4r/last.rb +2 -0
- data/lib/xmpp4r/last/helper/helper.rb +37 -0
- data/lib/xmpp4r/last/iq/last.rb +67 -0
- data/lib/xmpp4r/location.rb +2 -0
- data/lib/xmpp4r/location/helper/helper.rb +56 -0
- data/lib/xmpp4r/location/location.rb +179 -0
- data/lib/xmpp4r/message.rb +180 -0
- data/lib/xmpp4r/muc.rb +14 -0
- data/lib/xmpp4r/muc/helper/mucbrowser.rb +92 -0
- data/lib/xmpp4r/muc/helper/mucclient.rb +462 -0
- data/lib/xmpp4r/muc/helper/simplemucclient.rb +332 -0
- data/lib/xmpp4r/muc/iq/mucadmin.rb +23 -0
- data/lib/xmpp4r/muc/iq/mucadminitem.rb +20 -0
- data/lib/xmpp4r/muc/iq/mucowner.rb +15 -0
- data/lib/xmpp4r/muc/item.rb +143 -0
- data/lib/xmpp4r/muc/x/muc.rb +70 -0
- data/lib/xmpp4r/muc/x/mucuserinvite.rb +60 -0
- data/lib/xmpp4r/muc/x/mucuseritem.rb +36 -0
- data/lib/xmpp4r/presence.rb +232 -0
- data/lib/xmpp4r/pubsub.rb +8 -0
- data/lib/xmpp4r/pubsub/children/configuration.rb +86 -0
- data/lib/xmpp4r/pubsub/children/event.rb +49 -0
- data/lib/xmpp4r/pubsub/children/item.rb +35 -0
- data/lib/xmpp4r/pubsub/children/items.rb +53 -0
- data/lib/xmpp4r/pubsub/children/node_config.rb +48 -0
- data/lib/xmpp4r/pubsub/children/publish.rb +38 -0
- data/lib/xmpp4r/pubsub/children/retract.rb +41 -0
- data/lib/xmpp4r/pubsub/children/subscription.rb +62 -0
- data/lib/xmpp4r/pubsub/children/subscription_config.rb +67 -0
- data/lib/xmpp4r/pubsub/children/unsubscribe.rb +48 -0
- data/lib/xmpp4r/pubsub/helper/nodebrowser.rb +129 -0
- data/lib/xmpp4r/pubsub/helper/nodehelper.rb +156 -0
- data/lib/xmpp4r/pubsub/helper/oauth_service_helper.rb +90 -0
- data/lib/xmpp4r/pubsub/helper/servicehelper.rb +456 -0
- data/lib/xmpp4r/pubsub/iq/pubsub.rb +19 -0
- data/lib/xmpp4r/query.rb +15 -0
- data/lib/xmpp4r/reliable.rb +168 -0
- data/lib/xmpp4r/rexmladdons.rb +157 -0
- data/lib/xmpp4r/roster.rb +7 -0
- data/lib/xmpp4r/roster/helper/roster.rb +522 -0
- data/lib/xmpp4r/roster/iq/roster.rb +215 -0
- data/lib/xmpp4r/roster/x/roster.rb +138 -0
- data/lib/xmpp4r/rpc.rb +2 -0
- data/lib/xmpp4r/rpc/helper/client.rb +123 -0
- data/lib/xmpp4r/rpc/helper/server.rb +74 -0
- data/lib/xmpp4r/rpc/helper/xmlrpcaddons.rb +67 -0
- data/lib/xmpp4r/rpc/iq/rpc.rb +23 -0
- data/lib/xmpp4r/sasl.rb +248 -0
- data/lib/xmpp4r/semaphore.rb +38 -0
- data/lib/xmpp4r/stream.rb +599 -0
- data/lib/xmpp4r/streamparser.rb +85 -0
- data/lib/xmpp4r/test/listener_mocker.rb +118 -0
- data/lib/xmpp4r/tune.rb +2 -0
- data/lib/xmpp4r/tune/helper/helper.rb +58 -0
- data/lib/xmpp4r/tune/tune.rb +113 -0
- data/lib/xmpp4r/vcard.rb +6 -0
- data/lib/xmpp4r/vcard/helper/vcard.rb +84 -0
- data/lib/xmpp4r/vcard/iq/vcard.rb +109 -0
- data/lib/xmpp4r/version.rb +7 -0
- data/lib/xmpp4r/version/helper/responder.rb +72 -0
- data/lib/xmpp4r/version/helper/simpleresponder.rb +44 -0
- data/lib/xmpp4r/version/iq/version.rb +105 -0
- data/lib/xmpp4r/x.rb +37 -0
- data/lib/xmpp4r/xhtml.rb +1 -0
- data/lib/xmpp4r/xhtml/html.rb +115 -0
- data/lib/xmpp4r/xmpp4r.rb +20 -0
- data/lib/xmpp4r/xmppelement.rb +168 -0
- data/lib/xmpp4r/xmppstanza.rb +162 -0
- data/setup.rb +1586 -0
- data/test/bytestreams/tc_ibb.rb +188 -0
- data/test/bytestreams/tc_socks5bytestreams.rb +114 -0
- data/test/caps/tc_helper.rb +158 -0
- data/test/dataforms/tc_data.rb +81 -0
- data/test/delay/tc_xdelay.rb +51 -0
- data/test/discovery/tc_responder.rb +91 -0
- data/test/last/tc_helper.rb +75 -0
- data/test/lib/assert_equal_xml.rb +14 -0
- data/test/lib/clienttester.rb +149 -0
- data/test/muc/tc_muc_mucclient.rb +834 -0
- data/test/muc/tc_muc_simplemucclient.rb +114 -0
- data/test/muc/tc_mucowner.rb +50 -0
- data/test/pubsub/tc_helper.rb +785 -0
- data/test/pubsub/tc_nodeconfig.rb +61 -0
- data/test/pubsub/tc_subscriptionconfig.rb +41 -0
- data/test/reliable/tc_disconnect_cleanup.rb +334 -0
- data/test/reliable/tc_disconnect_exception.rb +37 -0
- data/test/reliable/tc_listener_mocked_test.rb +68 -0
- data/test/reliable/tc_reliable_connection.rb +31 -0
- data/test/roster/tc_helper.rb +524 -0
- data/test/roster/tc_iqqueryroster.rb +173 -0
- data/test/roster/tc_xroster.rb +73 -0
- data/test/rpc/tc_helper.rb +96 -0
- data/test/tc_callbacks.rb +129 -0
- data/test/tc_class_names.rb +146 -0
- data/test/tc_client.rb +30 -0
- data/test/tc_errors.rb +146 -0
- data/test/tc_idgenerator.rb +30 -0
- data/test/tc_iq.rb +113 -0
- data/test/tc_iqquery.rb +31 -0
- data/test/tc_jid.rb +204 -0
- data/test/tc_message.rb +131 -0
- data/test/tc_presence.rb +150 -0
- data/test/tc_rexml.rb +139 -0
- data/test/tc_stream.rb +167 -0
- data/test/tc_streamComponent.rb +95 -0
- data/test/tc_streamError.rb +129 -0
- data/test/tc_streamSend.rb +59 -0
- data/test/tc_streamparser.rb +125 -0
- data/test/tc_xmppstanza.rb +135 -0
- data/test/ts_xmpp4r.rb +44 -0
- data/test/tune/tc_helper_recv.rb +82 -0
- data/test/tune/tc_helper_send.rb +74 -0
- data/test/tune/tc_tune.rb +79 -0
- data/test/vcard/tc_helper.rb +49 -0
- data/test/vcard/tc_iqvcard.rb +62 -0
- data/test/version/tc_helper.rb +60 -0
- data/test/version/tc_iqqueryversion.rb +97 -0
- data/test/xhtml/tc_html.rb +41 -0
- data/tools/gen_requires.bash +31 -0
- data/tools/xmpp4r-gemspec-test.rb +11 -0
- data/xmpp4r.gemspec +238 -0
- metadata +280 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# =XMPP4R - XMPP Library for Ruby
|
|
2
|
+
# License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
|
|
3
|
+
# Website::http://home.gna.org/xmpp4r/
|
|
4
|
+
|
|
5
|
+
require 'xmpp4r/discovery'
|
|
6
|
+
|
|
7
|
+
module Jabber
|
|
8
|
+
module PubSub
|
|
9
|
+
class NodeBrowser
|
|
10
|
+
##
|
|
11
|
+
# Initialize a new NodeBrowser
|
|
12
|
+
# new(stream,pubsubservice)
|
|
13
|
+
# stream:: [Jabber::Stream]
|
|
14
|
+
def initialize(stream)
|
|
15
|
+
@stream = stream
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
##
|
|
19
|
+
# Retrieve the nodes
|
|
20
|
+
# Throws an ServerError when receiving
|
|
21
|
+
# <tt><iq type='error'/></tt>
|
|
22
|
+
# jid:: [JID] Target entity (set only domain!)
|
|
23
|
+
# return:: [Array] of [String] or [nil]
|
|
24
|
+
def nodes(jid)
|
|
25
|
+
iq = Iq.new(:get,jid)
|
|
26
|
+
iq.from = @stream.jid
|
|
27
|
+
iq.add(Discovery::IqQueryDiscoItems.new)
|
|
28
|
+
nodes = []
|
|
29
|
+
@stream.send_with_id(iq) do |answer|
|
|
30
|
+
answer.query.each_element('item') { |item|
|
|
31
|
+
nodes.push(item.node)
|
|
32
|
+
}
|
|
33
|
+
end
|
|
34
|
+
nodes
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
##
|
|
38
|
+
# Retrieve the nodes with names
|
|
39
|
+
# Throws a ServerError when receiving
|
|
40
|
+
# <tt><iq type='error'/></tt>
|
|
41
|
+
# jid:: [Jabber::JID] Target entity (set only domain!)
|
|
42
|
+
# return:: [Array] of [Hash] with keys 'node' => [String] and 'name' => [String] or [nil]
|
|
43
|
+
def nodes_names(jid)
|
|
44
|
+
iq = Iq.new(:get,jid)
|
|
45
|
+
iq.from = @stream.jid
|
|
46
|
+
iq.add(Discovery::IqQueryDiscoItems.new)
|
|
47
|
+
nodes = []
|
|
48
|
+
@stream.send_with_id(iq) do |answer|
|
|
49
|
+
answer.query.each_element('item') do |item|
|
|
50
|
+
nodes.push( {'node' => item.node,'name' => item.iname } )
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
nodes
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
##
|
|
58
|
+
# Retrieve the items from a node
|
|
59
|
+
# Throws an ServerError when receiving
|
|
60
|
+
# <tt><iq type='error'/></tt>
|
|
61
|
+
# jid:: [Jabber::JID] Target entity (set only domain!)
|
|
62
|
+
# node:: [String]
|
|
63
|
+
# return:: [Array] of [Hash] with keys 'name' => [String] and 'jid' => [Jabber::JID]
|
|
64
|
+
def items(jid,node)
|
|
65
|
+
iq = Iq.new(:get,jid)
|
|
66
|
+
iq.from = @stream.jid
|
|
67
|
+
discoitems = Discovery::IqQueryDiscoItems.new
|
|
68
|
+
discoitems.node = node
|
|
69
|
+
iq.add(discoitems)
|
|
70
|
+
items = []
|
|
71
|
+
err = nil
|
|
72
|
+
@stream.send_with_id(iq) do |answer|
|
|
73
|
+
answer.query.each_element('item') { |item|
|
|
74
|
+
items.push( {'jid' => item.jid,'name' => item.iname } )
|
|
75
|
+
}
|
|
76
|
+
end
|
|
77
|
+
items
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
##
|
|
81
|
+
# get disco info for a node
|
|
82
|
+
# jid:: [Jabber::JID]
|
|
83
|
+
# node:: [String]
|
|
84
|
+
# return:: [Hash] with possible keys type:: [String] ,category:: [String],features:: [Array] of feature, nodeinformation:: [Jabber::XData]
|
|
85
|
+
# check http://www.xmpp.org/extensions/xep-0060.html#entity for more infos
|
|
86
|
+
def get_info(jid,node)
|
|
87
|
+
iq = Iq.new(:get,jid)
|
|
88
|
+
iq.from = @stream.jid
|
|
89
|
+
discoinfo = Discovery::IqQueryDiscoInfo.new
|
|
90
|
+
discoinfo.node = node
|
|
91
|
+
iq.add(discoinfo)
|
|
92
|
+
info = {}
|
|
93
|
+
@stream.send_with_id(iq) do |answer|
|
|
94
|
+
identity = answer.query.identity
|
|
95
|
+
info['type'] = identity.type
|
|
96
|
+
info['category'] = identity.category
|
|
97
|
+
info['features'] = answer.query.features
|
|
98
|
+
answer.query.each_element('x') { |x|
|
|
99
|
+
info['nodeinformation'] = x
|
|
100
|
+
}
|
|
101
|
+
end
|
|
102
|
+
info
|
|
103
|
+
end
|
|
104
|
+
# this is only for a xep <-> nodebrowser.rb understanding
|
|
105
|
+
alias get_metadata get_info
|
|
106
|
+
|
|
107
|
+
##
|
|
108
|
+
# get type of node
|
|
109
|
+
# jid:: [Jabber::JID]
|
|
110
|
+
# node:: [String]
|
|
111
|
+
#
|
|
112
|
+
def type(jid,node)
|
|
113
|
+
info = get_info(jid,node)
|
|
114
|
+
return info['type']
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
##
|
|
118
|
+
# get category of node
|
|
119
|
+
# jid:: [Jabber::JID]
|
|
120
|
+
# node:: [String]
|
|
121
|
+
#
|
|
122
|
+
def category(jid,node)
|
|
123
|
+
info = get_info(jid,node)
|
|
124
|
+
return info['category']
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
end #class
|
|
128
|
+
end #module
|
|
129
|
+
end #module
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# =XMPP4R - XMPP Library for Ruby
|
|
2
|
+
# License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
|
|
3
|
+
# Website::http://home.gna.org/xmpp4r/
|
|
4
|
+
#
|
|
5
|
+
# For documentation of the return values please see [Jabber::PubSub::ServiceHelper]
|
|
6
|
+
# This class is only a wrapper around [Jabber::PubSub::ServiceHelper]
|
|
7
|
+
#
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
require 'xmpp4r/pubsub/helper/servicehelper'
|
|
11
|
+
require 'xmpp4r/pubsub/helper/nodebrowser'
|
|
12
|
+
|
|
13
|
+
module Jabber
|
|
14
|
+
module PubSub
|
|
15
|
+
class NodeHelper < ServiceHelper
|
|
16
|
+
|
|
17
|
+
attr_reader :nodename
|
|
18
|
+
attr_reader :name
|
|
19
|
+
attr_reader :jid
|
|
20
|
+
attr_reader :my_subscriptions
|
|
21
|
+
##
|
|
22
|
+
# creates a new node
|
|
23
|
+
# new(client,service,nodename)
|
|
24
|
+
# stream:: [Jabber::Stream]
|
|
25
|
+
# jid:: [String] (jid of the pubsub service)
|
|
26
|
+
# nodename:: [String]
|
|
27
|
+
def initialize(stream, jid, nodename = nil, create_if_not_exist = true)
|
|
28
|
+
super(stream,jid)
|
|
29
|
+
@nodename = nodename
|
|
30
|
+
@jid = jid
|
|
31
|
+
@stream = stream
|
|
32
|
+
|
|
33
|
+
if create_if_not_exist and !node_exist?
|
|
34
|
+
# if no nodename is given a instant node will created
|
|
35
|
+
# (if the service supports instant nodes)
|
|
36
|
+
@nodename = create_node
|
|
37
|
+
else
|
|
38
|
+
get_subscriptions
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
##
|
|
43
|
+
# creates the node
|
|
44
|
+
# create(configuration=nil)
|
|
45
|
+
# configuration:: [Jabber::XData]
|
|
46
|
+
def create_node(configuration = Jabber::PubSub::NodeConfig.new)
|
|
47
|
+
unless node_exist?
|
|
48
|
+
super(@nodename,configuration)
|
|
49
|
+
else
|
|
50
|
+
false
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
##
|
|
55
|
+
# get the configuration of the node
|
|
56
|
+
# get_configuration(configuration=nil)
|
|
57
|
+
# configuration:: [Jabber::XData]
|
|
58
|
+
def get_configuration(subid = nil)
|
|
59
|
+
get_options(@nodename, subid)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
##
|
|
63
|
+
# set the configuration of the node
|
|
64
|
+
# set_configuration(configuration=nil)
|
|
65
|
+
# configuration:: [Jabber::XData]
|
|
66
|
+
# subid:: [String] default is nil
|
|
67
|
+
def set_configuration(configuration,subid = nil)
|
|
68
|
+
set_options(@nodename, configuration, subid)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
##
|
|
72
|
+
# deletes the node
|
|
73
|
+
# delete
|
|
74
|
+
def delete_node
|
|
75
|
+
delete(@nodename)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
##
|
|
79
|
+
# publishing content on this node
|
|
80
|
+
# publish_content(items)
|
|
81
|
+
# items:: [REXML::Element]
|
|
82
|
+
def publish_content(items)
|
|
83
|
+
publish_item_to(@nodename,items)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
##
|
|
87
|
+
# gets all items from the node
|
|
88
|
+
# get_all_items
|
|
89
|
+
def get_all_items
|
|
90
|
+
get_items_from(@nodename)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
##
|
|
94
|
+
# get a count of items
|
|
95
|
+
# get_items(count)
|
|
96
|
+
# count:: [Fixnum]
|
|
97
|
+
def get_items(count)
|
|
98
|
+
get_items_from(@nodename,count)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
##
|
|
102
|
+
# get all node affiliations
|
|
103
|
+
# get_affiliations
|
|
104
|
+
def get_affiliations
|
|
105
|
+
affiliations
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
##
|
|
109
|
+
# get all subscriptions on this node
|
|
110
|
+
# get_subscriptions
|
|
111
|
+
def get_subscriptions
|
|
112
|
+
get_subscriptions_from(@nodename)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
##
|
|
116
|
+
# get all subscribers subscribed on this node
|
|
117
|
+
# get_subscribers
|
|
118
|
+
def get_subscribers
|
|
119
|
+
@subscriptions = subscribers(@nodename)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
##
|
|
123
|
+
# subscribe to this node
|
|
124
|
+
# do_subscribe
|
|
125
|
+
def do_subscribe
|
|
126
|
+
subscribe_to(@nodename)
|
|
127
|
+
get_subscriptions
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
##
|
|
131
|
+
# unsubscribe from this node
|
|
132
|
+
# do_unsubscribe(subid = nil)
|
|
133
|
+
# subid:: [String]
|
|
134
|
+
def do_unsubscribe(subid)
|
|
135
|
+
unsubscribe(@nodename,subid)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
##
|
|
139
|
+
# purge all items from this node
|
|
140
|
+
# purge_items
|
|
141
|
+
def purge_items
|
|
142
|
+
purge(@nodename)
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
private
|
|
146
|
+
|
|
147
|
+
def node_exist?
|
|
148
|
+
nodebrowser = PubSub::NodeBrowser.new(@stream)
|
|
149
|
+
nodebrowser.nodes(@jid).include?(@nodename)
|
|
150
|
+
end
|
|
151
|
+
def disco_info
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
end #class
|
|
155
|
+
end #module
|
|
156
|
+
end #module
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
module Jabber
|
|
2
|
+
module PubSub
|
|
3
|
+
# Jabber::Stream helper that will transparently sign PubSub requests
|
|
4
|
+
module OAuthPubSubStreamHelper
|
|
5
|
+
attr_accessor :pubsubjid, :oauth_consumer, :oauth_token, :oauth_options
|
|
6
|
+
|
|
7
|
+
# enhanced #send_with_id method that signs stanzas
|
|
8
|
+
def send_with_id(iq)
|
|
9
|
+
if iq.first_element("pubsub")
|
|
10
|
+
oauth = OAuthServiceHelper.create_oauth_node(self.jid, self.pubsubjid, self.oauth_consumer, self.oauth_token, self.oauth_options)
|
|
11
|
+
iq.pubsub.add(oauth)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
super(iq)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# PubSub service helper for use with OAuth-authenticated nodes
|
|
19
|
+
class OAuthServiceHelper < ServiceHelper
|
|
20
|
+
def initialize(stream, pubsubjid, oauth_consumer, oauth_token, options = {})
|
|
21
|
+
# imbue the stream with magical OAuth signing powers
|
|
22
|
+
stream.extend(OAuthPubSubStreamHelper)
|
|
23
|
+
stream.oauth_consumer = oauth_consumer
|
|
24
|
+
stream.oauth_token = oauth_token
|
|
25
|
+
stream.oauth_options = options
|
|
26
|
+
stream.pubsubjid = pubsubjid
|
|
27
|
+
|
|
28
|
+
super(stream, pubsubjid)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# add the OAuth sauce (XEP-0235)
|
|
32
|
+
# The `options` hash may contain the following parameters:
|
|
33
|
+
# :oauth_nonce => nonce (one will be generated otherwise)
|
|
34
|
+
# :oauth_timestamp => timestamp (one will be generated otherwise)
|
|
35
|
+
# :oauth_signature_method => signature method (defaults to HMAC-SHA1)
|
|
36
|
+
# :oauth_version => OAuth version (defaults to "1.0")
|
|
37
|
+
def self.create_oauth_node(jid, pubsubjid, oauth_consumer, oauth_token, options = {})
|
|
38
|
+
require 'oauth'
|
|
39
|
+
|
|
40
|
+
request = OAuth::RequestProxy.proxy \
|
|
41
|
+
"method" => "iq",
|
|
42
|
+
"uri" => [jid.strip.to_s, pubsubjid.strip.to_s] * "&",
|
|
43
|
+
"parameters" => {
|
|
44
|
+
"oauth_consumer_key" => oauth_consumer.key,
|
|
45
|
+
"oauth_nonce" => options[:oauth_nonce] || OAuth::Helper.generate_nonce,
|
|
46
|
+
"oauth_timestamp" => options[:oauth_timestamp] || OAuth::Helper.generate_timestamp,
|
|
47
|
+
"oauth_token" => oauth_token.token,
|
|
48
|
+
"oauth_signature_method" => options[:oauth_signature_method] || "HMAC-SHA1",
|
|
49
|
+
"oauth_version" => options[:oauth_version] || "1.0"
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
request.sign!(:consumer => oauth_consumer, :token => oauth_token)
|
|
53
|
+
|
|
54
|
+
# TODO create XMPPElements for OAuth elements
|
|
55
|
+
oauth = REXML::Element.new("oauth")
|
|
56
|
+
oauth.attributes['xmlns'] = 'urn:xmpp:oauth:0'
|
|
57
|
+
|
|
58
|
+
oauth_consumer_key = REXML::Element.new("oauth_consumer_key")
|
|
59
|
+
oauth_consumer_key.text = request.oauth_consumer_key
|
|
60
|
+
oauth.add(oauth_consumer_key)
|
|
61
|
+
|
|
62
|
+
oauth_token_node = REXML::Element.new("oauth_token")
|
|
63
|
+
oauth_token_node.text = request.oauth_token
|
|
64
|
+
oauth.add(oauth_token_node)
|
|
65
|
+
|
|
66
|
+
oauth_signature_method = REXML::Element.new("oauth_signature_method")
|
|
67
|
+
oauth_signature_method.text = request.oauth_signature_method
|
|
68
|
+
oauth.add(oauth_signature_method)
|
|
69
|
+
|
|
70
|
+
oauth_signature = REXML::Element.new("oauth_signature")
|
|
71
|
+
oauth_signature.text = request.oauth_signature
|
|
72
|
+
oauth.add(oauth_signature)
|
|
73
|
+
|
|
74
|
+
oauth_timestamp = REXML::Element.new("oauth_timestamp")
|
|
75
|
+
oauth_timestamp.text = request.oauth_timestamp
|
|
76
|
+
oauth.add(oauth_timestamp)
|
|
77
|
+
|
|
78
|
+
oauth_nonce = REXML::Element.new("oauth_nonce")
|
|
79
|
+
oauth_nonce.text = request.oauth_nonce
|
|
80
|
+
oauth.add(oauth_nonce)
|
|
81
|
+
|
|
82
|
+
oauth_version = REXML::Element.new("oauth_version")
|
|
83
|
+
oauth_version.text = request.oauth_version
|
|
84
|
+
oauth.add(oauth_version)
|
|
85
|
+
|
|
86
|
+
oauth
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
# =XMPP4R - XMPP Library for Ruby
|
|
2
|
+
# License:: Ruby's license (see the LICENSE file) or GNU GPL, at your option.
|
|
3
|
+
# Website::http://home.gna.org/xmpp4r/
|
|
4
|
+
#
|
|
5
|
+
# It's recommented to read the XEP-0060 before you use this Helper. (Maybe its
|
|
6
|
+
# better not use the helper for now ) ;)
|
|
7
|
+
# The whole code is getting better, but may still contain bugs - be careful!
|
|
8
|
+
#
|
|
9
|
+
# Maybe the following structure is good
|
|
10
|
+
# ( taken from the xep-0060 )
|
|
11
|
+
#
|
|
12
|
+
# entity usecases
|
|
13
|
+
# retrieve all subscriptions
|
|
14
|
+
# retrieve all affiliations
|
|
15
|
+
# NOTE: the disco stuff will done by the nodebrowserhelper
|
|
16
|
+
# subscriber usecases
|
|
17
|
+
# subscribe
|
|
18
|
+
# unsubscribe
|
|
19
|
+
# configure subscription options
|
|
20
|
+
# retrieve items from a node
|
|
21
|
+
# publisher usecases
|
|
22
|
+
# publish a item to a node
|
|
23
|
+
# delete a item from a node
|
|
24
|
+
# owner usecases
|
|
25
|
+
# create a node
|
|
26
|
+
# configure a node
|
|
27
|
+
# request default configuration options
|
|
28
|
+
# delete a node
|
|
29
|
+
# purge all node items
|
|
30
|
+
# manage subscription requests
|
|
31
|
+
# process pending subscriptions
|
|
32
|
+
# manage subscriptions
|
|
33
|
+
# manage affiliations
|
|
34
|
+
#
|
|
35
|
+
# collection nodes
|
|
36
|
+
#
|
|
37
|
+
# If someone want to implement something i think its better to do this in
|
|
38
|
+
# this order because everyone who reads the xep-0060 do know where to search in the file
|
|
39
|
+
#
|
|
40
|
+
require 'xmpp4r/pubsub/iq/pubsub'
|
|
41
|
+
require 'xmpp4r/pubsub/children/event'
|
|
42
|
+
require 'xmpp4r/pubsub/children/item'
|
|
43
|
+
require 'xmpp4r/pubsub/children/items'
|
|
44
|
+
require 'xmpp4r/pubsub/children/subscription'
|
|
45
|
+
require 'xmpp4r/pubsub/children/unsubscribe'
|
|
46
|
+
require 'xmpp4r/pubsub/children/node_config'
|
|
47
|
+
require 'xmpp4r/pubsub/children/subscription_config'
|
|
48
|
+
require 'xmpp4r/pubsub/children/retract'
|
|
49
|
+
require 'xmpp4r/dataforms'
|
|
50
|
+
|
|
51
|
+
module Jabber
|
|
52
|
+
module PubSub
|
|
53
|
+
##
|
|
54
|
+
# A Helper representing a PubSub Service
|
|
55
|
+
class ServiceHelper
|
|
56
|
+
|
|
57
|
+
##
|
|
58
|
+
# Creates a new representation of a pubsub service
|
|
59
|
+
# stream:: [Jabber::Stream]
|
|
60
|
+
# pubsubjid:: [String] or [Jabber::JID]
|
|
61
|
+
def initialize(stream, pubsubjid)
|
|
62
|
+
@stream = stream
|
|
63
|
+
@pubsubjid = pubsubjid
|
|
64
|
+
@event_cbs = CallbackList.new
|
|
65
|
+
@stream.add_message_callback(200,self) { |message|
|
|
66
|
+
handle_message(message)
|
|
67
|
+
}
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
##
|
|
71
|
+
# get all subscriptions on a pubsub component
|
|
72
|
+
# return:: [Hash] of [PubSub::Subscription]
|
|
73
|
+
def get_subscriptions_from_all_nodes
|
|
74
|
+
iq = basic_pubsub_query(:get)
|
|
75
|
+
entities = iq.pubsub.add(REXML::Element.new('subscriptions'))
|
|
76
|
+
res = nil
|
|
77
|
+
@stream.send_with_id(iq) { |reply|
|
|
78
|
+
if reply.pubsub.first_element('subscriptions')
|
|
79
|
+
res = []
|
|
80
|
+
reply.pubsub.first_element('subscriptions').each_element('subscription') { |subscription|
|
|
81
|
+
res << Jabber::PubSub::Subscription.import(subscription)
|
|
82
|
+
}
|
|
83
|
+
end
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
res
|
|
87
|
+
end
|
|
88
|
+
##
|
|
89
|
+
# subscribe to a node
|
|
90
|
+
# node:: [String]
|
|
91
|
+
# return:: [Hash] of { attributename => value }
|
|
92
|
+
def subscribe_to(node)
|
|
93
|
+
iq = basic_pubsub_query(:set)
|
|
94
|
+
sub = REXML::Element.new('subscribe')
|
|
95
|
+
sub.attributes['node'] = node
|
|
96
|
+
sub.attributes['jid'] = @stream.jid.strip.to_s
|
|
97
|
+
iq.pubsub.add(sub)
|
|
98
|
+
res = nil
|
|
99
|
+
@stream.send_with_id(iq) do |reply|
|
|
100
|
+
pubsubanswer = reply.pubsub
|
|
101
|
+
if pubsubanswer.first_element('subscription')
|
|
102
|
+
res = PubSub::Subscription.import(pubsubanswer.first_element('subscription'))
|
|
103
|
+
end
|
|
104
|
+
end # @stream.send_with_id(iq)
|
|
105
|
+
res
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
##
|
|
109
|
+
# Unsubscribe from a node with an optional subscription id
|
|
110
|
+
#
|
|
111
|
+
# May raise ServerError
|
|
112
|
+
# node:: [String]
|
|
113
|
+
# subid:: [String] or nil (not supported)
|
|
114
|
+
# return:: true
|
|
115
|
+
def unsubscribe_from(node, subid=nil)
|
|
116
|
+
iq = basic_pubsub_query(:set)
|
|
117
|
+
unsub = PubSub::Unsubscribe.new
|
|
118
|
+
unsub.node = node
|
|
119
|
+
unsub.jid = @stream.jid.strip
|
|
120
|
+
iq.pubsub.add(unsub)
|
|
121
|
+
ret = false
|
|
122
|
+
@stream.send_with_id(iq) { |reply|
|
|
123
|
+
ret = reply.kind_of?(Jabber::Iq) and reply.type == :result
|
|
124
|
+
} # @stream.send_with_id(iq)
|
|
125
|
+
ret
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
##
|
|
129
|
+
# gets all items from a pubsub node
|
|
130
|
+
# node:: [String]
|
|
131
|
+
# count:: [Fixnum]
|
|
132
|
+
# return:: [Hash] { id => [Jabber::PubSub::Item] }
|
|
133
|
+
def get_items_from(node, count=nil)
|
|
134
|
+
iq = basic_pubsub_query(:get)
|
|
135
|
+
items = Jabber::PubSub::Items.new
|
|
136
|
+
items.max_items = count
|
|
137
|
+
items.node = node
|
|
138
|
+
iq.pubsub.add(items)
|
|
139
|
+
res = nil
|
|
140
|
+
@stream.send_with_id(iq) { |reply|
|
|
141
|
+
if reply.kind_of?(Iq) and reply.pubsub and reply.pubsub.first_element('items')
|
|
142
|
+
res = {}
|
|
143
|
+
reply.pubsub.first_element('items').each_element('item') do |item|
|
|
144
|
+
res[item.attributes['id']] = item.children.first if item.children.first
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
true
|
|
148
|
+
}
|
|
149
|
+
res
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
##
|
|
153
|
+
# NOTE: this method sends only one item per publish request because some services
|
|
154
|
+
# may not allow batch processing. Maybe this will changed in the future?
|
|
155
|
+
# node:: [String]
|
|
156
|
+
# item:: [Jabber::PubSub::Item]
|
|
157
|
+
# return:: true
|
|
158
|
+
def publish_item_to(node,item)
|
|
159
|
+
iq = basic_pubsub_query(:set)
|
|
160
|
+
publish = iq.pubsub.add(REXML::Element.new('publish'))
|
|
161
|
+
publish.attributes['node'] = node
|
|
162
|
+
|
|
163
|
+
if item.kind_of?(Jabber::PubSub::Item)
|
|
164
|
+
publish.add(item)
|
|
165
|
+
@stream.send_with_id(iq)
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
##
|
|
170
|
+
# node:: [String]
|
|
171
|
+
# item:: [REXML::Element]
|
|
172
|
+
# id:: [String]
|
|
173
|
+
# return:: true
|
|
174
|
+
def publish_item_with_id_to(node,item,id)
|
|
175
|
+
iq = basic_pubsub_query(:set)
|
|
176
|
+
publish = iq.pubsub.add(REXML::Element.new('publish'))
|
|
177
|
+
publish.attributes['node'] = node
|
|
178
|
+
|
|
179
|
+
if item.kind_of?(REXML::Element)
|
|
180
|
+
xmlitem = Jabber::PubSub::Item.new
|
|
181
|
+
xmlitem.id = id
|
|
182
|
+
xmlitem.import(item)
|
|
183
|
+
publish.add(xmlitem)
|
|
184
|
+
else
|
|
185
|
+
raise "given item is not a proper xml document or Jabber::PubSub::Item"
|
|
186
|
+
end
|
|
187
|
+
@stream.send_with_id(iq)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
##
|
|
191
|
+
# deletes an item from a persistent node
|
|
192
|
+
# node:: [String]
|
|
193
|
+
# item_id:: [String] or [Array] of [String]
|
|
194
|
+
# return:: true
|
|
195
|
+
def delete_item_from(node, item_id)
|
|
196
|
+
iq = basic_pubsub_query(:set)
|
|
197
|
+
retract = iq.pubsub.add(Jabber::PubSub::Retract.new)
|
|
198
|
+
retract.node = node
|
|
199
|
+
|
|
200
|
+
if item_id.kind_of? Array
|
|
201
|
+
item_id.each { |id|
|
|
202
|
+
xmlitem = Jabber::PubSub::Item.new
|
|
203
|
+
xmlitem.id = id
|
|
204
|
+
retract.add(xmlitem)
|
|
205
|
+
}
|
|
206
|
+
else
|
|
207
|
+
xmlitem = Jabber::PubSub::Item.new
|
|
208
|
+
xmlitem.id = item_id
|
|
209
|
+
retract.add(xmlitem)
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
@stream.send_with_id(iq)
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
##
|
|
217
|
+
# purges all items on a persistent node
|
|
218
|
+
# node:: [String]
|
|
219
|
+
# return:: true
|
|
220
|
+
def purge_items_from(node)
|
|
221
|
+
iq = basic_pubsub_query(:set)
|
|
222
|
+
purge = REXML::Element.new('purge')
|
|
223
|
+
purge.attributes['node'] = node
|
|
224
|
+
iq.pubsub.add(purge)
|
|
225
|
+
@stream.send_with_id(iq)
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
##
|
|
229
|
+
# Create a new node on the pubsub service
|
|
230
|
+
# node:: [String] the node name - otherwise you get a automatically generated one (in most cases)
|
|
231
|
+
# configure:: [Jabber::PubSub::NodeConfig] if you want to configure your node (default nil)
|
|
232
|
+
# return:: [String]
|
|
233
|
+
def create_node(node = nil, configure = Jabber::PubSub::NodeConfig.new)
|
|
234
|
+
rnode = nil
|
|
235
|
+
iq = basic_pubsub_query(:set)
|
|
236
|
+
iq.pubsub.add(REXML::Element.new('create')).attributes['node'] = node
|
|
237
|
+
if configure
|
|
238
|
+
if configure.kind_of?(Jabber::PubSub::NodeConfig)
|
|
239
|
+
iq.pubsub.add(configure)
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
|
|
243
|
+
@stream.send_with_id(iq) do |reply|
|
|
244
|
+
if reply.kind_of?(Jabber::Iq) and reply.type == :result
|
|
245
|
+
rnode = node
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
rnode
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
##
|
|
253
|
+
# Create a new collection node on the pubsub service
|
|
254
|
+
# node:: [String] the node name - otherwise you get an automatically generated one (in most cases)
|
|
255
|
+
# configure:: [Jabber::PubSub::NodeConfig] if you want to configure your node (default nil)
|
|
256
|
+
# return:: [String]
|
|
257
|
+
def create_collection_node(node = nil, configure = Jabber::PubSub::NodeConfig.new)
|
|
258
|
+
if configure.options['pubsub#node_type'] && configure.options['pubsub#node_type'] != 'collection'
|
|
259
|
+
raise Jabber::ArgumentError, "Invalid node_type specified in node configuration. Either do not specify one, or use 'collection'"
|
|
260
|
+
end
|
|
261
|
+
configure.options = configure.options.merge({'pubsub#node_type' => 'collection'})
|
|
262
|
+
create_node(node, configure)
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
##
|
|
266
|
+
# get configuration from a node
|
|
267
|
+
# node:: [String]
|
|
268
|
+
# return:: [Jabber::PubSub::Configure]
|
|
269
|
+
def get_config_from(node)
|
|
270
|
+
iq = basic_pubsub_query(:get, true)
|
|
271
|
+
iq.pubsub.add(Jabber::PubSub::OwnerNodeConfig.new(node))
|
|
272
|
+
ret = nil
|
|
273
|
+
@stream.send_with_id(iq) do |reply|
|
|
274
|
+
ret = reply.pubsub.first_element('configure')
|
|
275
|
+
end
|
|
276
|
+
ret
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
##
|
|
280
|
+
# set configuration for a node
|
|
281
|
+
# node:: [String]
|
|
282
|
+
# options:: [Jabber::PubSub::NodeConfig]
|
|
283
|
+
# return:: true on success
|
|
284
|
+
def set_config_for(node, config)
|
|
285
|
+
iq = basic_pubsub_query(:set, true)
|
|
286
|
+
iq.pubsub.add(config)
|
|
287
|
+
@stream.send_with_id(iq)
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
##
|
|
291
|
+
# Delete a pubsub node
|
|
292
|
+
# node:: [String]
|
|
293
|
+
# return:: true
|
|
294
|
+
def delete_node(node)
|
|
295
|
+
iq = basic_pubsub_query(:set,true)
|
|
296
|
+
iq.pubsub.add(REXML::Element.new('delete')).attributes['node'] = node
|
|
297
|
+
@stream.send_with_id(iq)
|
|
298
|
+
end
|
|
299
|
+
|
|
300
|
+
def set_affiliations(node, jid, role = 'publisher')
|
|
301
|
+
iq = basic_pubsub_query(:set, true)
|
|
302
|
+
affiliations = iq.pubsub.add(REXML::Element.new('affiliations'))
|
|
303
|
+
affiliations.attributes['node'] = node
|
|
304
|
+
affiliation = affiliations.add(REXML::Element.new('affiliation'))
|
|
305
|
+
affiliation.attributes['jid'] = jid.to_s
|
|
306
|
+
affiliation.attributes['affiliation'] = role.to_s
|
|
307
|
+
res = nil
|
|
308
|
+
@stream.send_with_id(iq) { |reply|
|
|
309
|
+
true
|
|
310
|
+
}
|
|
311
|
+
res
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
##
|
|
315
|
+
# shows the affiliations on a pubsub service
|
|
316
|
+
# node:: [String]
|
|
317
|
+
# return:: [Hash] of { node => symbol }
|
|
318
|
+
def get_affiliations(node = nil)
|
|
319
|
+
iq = basic_pubsub_query(:get)
|
|
320
|
+
affiliations = iq.pubsub.add(REXML::Element.new('affiliations'))
|
|
321
|
+
affiliations.attributes['node'] = node
|
|
322
|
+
res = nil
|
|
323
|
+
@stream.send_with_id(iq) { |reply|
|
|
324
|
+
if reply.pubsub.first_element('affiliations')
|
|
325
|
+
res = {}
|
|
326
|
+
reply.pubsub.first_element('affiliations').each_element('affiliation') do |affiliation|
|
|
327
|
+
# TODO: This should be handled by an affiliation element class
|
|
328
|
+
aff = case affiliation.attributes['affiliation']
|
|
329
|
+
when 'owner' then :owner
|
|
330
|
+
when 'publisher' then :publisher
|
|
331
|
+
when 'none' then :none
|
|
332
|
+
when 'outcast' then :outcast
|
|
333
|
+
else nil
|
|
334
|
+
end
|
|
335
|
+
res[affiliation.attributes['node']] = aff
|
|
336
|
+
end
|
|
337
|
+
end
|
|
338
|
+
true
|
|
339
|
+
}
|
|
340
|
+
res
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
##
|
|
344
|
+
# shows all subscriptions on the given node
|
|
345
|
+
# node:: [String]
|
|
346
|
+
# return:: [Array] of [Jabber::Pubsub::Subscription]
|
|
347
|
+
def get_subscriptions_from(node)
|
|
348
|
+
iq = basic_pubsub_query(:get)
|
|
349
|
+
entities = iq.pubsub.add(REXML::Element.new('subscriptions'))
|
|
350
|
+
entities.attributes['node'] = node
|
|
351
|
+
res = nil
|
|
352
|
+
@stream.send_with_id(iq) { |reply|
|
|
353
|
+
if reply.pubsub.first_element('subscriptions')
|
|
354
|
+
res = []
|
|
355
|
+
if reply.pubsub.first_element('subscriptions').attributes['node'] == node
|
|
356
|
+
reply.pubsub.first_element('subscriptions').each_element('subscription') { |subscription|
|
|
357
|
+
res << PubSub::Subscription.import(subscription)
|
|
358
|
+
}
|
|
359
|
+
end
|
|
360
|
+
end
|
|
361
|
+
true
|
|
362
|
+
}
|
|
363
|
+
res
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
##
|
|
367
|
+
# shows all jids of subscribers of a node
|
|
368
|
+
# node:: [String]
|
|
369
|
+
# return:: [Array] of [String]
|
|
370
|
+
def get_subscribers_from(node)
|
|
371
|
+
res = []
|
|
372
|
+
get_subscriptions_from(node).each { |sub|
|
|
373
|
+
res << sub.jid
|
|
374
|
+
}
|
|
375
|
+
res
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
##
|
|
380
|
+
# get options from a subscription
|
|
381
|
+
# node:: [String]
|
|
382
|
+
# jid:: [Jabber::JID] or [String]
|
|
383
|
+
# subid:: [String] or nil
|
|
384
|
+
# return:: [Jabber::PubSub::OwnerConfigure]
|
|
385
|
+
def get_options_from(node, jid, subid = nil)
|
|
386
|
+
iq = basic_pubsub_query(:get)
|
|
387
|
+
iq.pubsub.add(Jabber::PubSub::SubscriptionConfig.new(node, jid.kind_of?(String) ? Jabber::JID.new(jid).strip: jid.strip, subid))
|
|
388
|
+
ret = nil
|
|
389
|
+
@stream.send_with_id(iq) do |reply|
|
|
390
|
+
ret = reply.pubsub.first_element('options')
|
|
391
|
+
end
|
|
392
|
+
ret
|
|
393
|
+
end
|
|
394
|
+
|
|
395
|
+
##
|
|
396
|
+
# set options for a subscription
|
|
397
|
+
# node:: [String]
|
|
398
|
+
# jid:: [Jabber::JID] or [String]
|
|
399
|
+
# options:: [Jabber::PubSub::SubscriptionConfig} specifying configuration options
|
|
400
|
+
# subid:: [String] or nil
|
|
401
|
+
# return:: true
|
|
402
|
+
def set_options_for(node, jid, options, subid = nil)
|
|
403
|
+
iq = basic_pubsub_query(:set)
|
|
404
|
+
iq.pubsub.add(Jabber::PubSub::SubscriptionConfig.new(node, jid.kind_of?(String) ? Jabber::JID.new(jid).strip: jid.strip, options, subid))
|
|
405
|
+
ret = false
|
|
406
|
+
@stream.send_with_id(iq) do |reply|
|
|
407
|
+
ret = ( reply.type == :result )
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
ret
|
|
411
|
+
end
|
|
412
|
+
|
|
413
|
+
##
|
|
414
|
+
# String representation
|
|
415
|
+
# result:: [String] The PubSub service's JID
|
|
416
|
+
def to_s
|
|
417
|
+
@pubsubjid.to_s
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
##
|
|
421
|
+
# Register callbacks for incoming events
|
|
422
|
+
# (i.e. Message stanzas containing) PubSub notifications
|
|
423
|
+
def add_event_callback(prio = 200, ref = nil, &block)
|
|
424
|
+
@event_cbs.add(prio, ref, block)
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
private
|
|
428
|
+
|
|
429
|
+
##
|
|
430
|
+
# creates a basic pubsub iq
|
|
431
|
+
# basic_pubsub_query(type)
|
|
432
|
+
# type:: [Symbol]
|
|
433
|
+
def basic_pubsub_query(type,ownerusecase = false)
|
|
434
|
+
iq = Jabber::Iq.new(type,@pubsubjid)
|
|
435
|
+
if ownerusecase
|
|
436
|
+
iq.add(IqPubSubOwner.new)
|
|
437
|
+
else
|
|
438
|
+
iq.add(IqPubSub.new)
|
|
439
|
+
end
|
|
440
|
+
iq.from = @stream.jid #.strip
|
|
441
|
+
iq
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
##
|
|
445
|
+
# handling incoming events
|
|
446
|
+
# handle_message(message)
|
|
447
|
+
# message:: [Jabber::Message]
|
|
448
|
+
def handle_message(message)
|
|
449
|
+
if message.from == @pubsubjid and message.first_element('event').kind_of?(Jabber::PubSub::Event)
|
|
450
|
+
event = message.first_element('event')
|
|
451
|
+
@event_cbs.process(event)
|
|
452
|
+
end
|
|
453
|
+
end
|
|
454
|
+
end
|
|
455
|
+
end
|
|
456
|
+
end
|