xmpp4r 0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +340 -0
- data/ChangeLog +28 -0
- data/LICENSE +59 -0
- data/README +20 -0
- data/Rakefile +103 -0
- data/UPDATING +40 -0
- data/data/doc/xmpp4r/examples/advanced/adventure/README +57 -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 +425 -0
- data/data/doc/xmpp4r/examples/advanced/fileserve.conf +11 -0
- data/data/doc/xmpp4r/examples/advanced/fileserve.rb +344 -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 +89 -0
- data/data/doc/xmpp4r/examples/advanced/minimuc.rb +266 -0
- data/data/doc/xmpp4r/examples/advanced/recvfile.rb +83 -0
- data/data/doc/xmpp4r/examples/advanced/rosterdiscovery.rb +130 -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 +90 -0
- data/data/doc/xmpp4r/examples/advanced/xmpping.rb +134 -0
- data/data/doc/xmpp4r/examples/advanced/xmppingrc.sample +9 -0
- data/data/doc/xmpp4r/examples/basic/change_password.rb +41 -0
- data/data/doc/xmpp4r/examples/basic/client.rb +68 -0
- data/data/doc/xmpp4r/examples/basic/component.rb +11 -0
- data/data/doc/xmpp4r/examples/basic/echo_nonthreaded.rb +32 -0
- data/data/doc/xmpp4r/examples/basic/echo_threaded.rb +32 -0
- data/data/doc/xmpp4r/examples/basic/jabbersend.rb +41 -0
- data/data/doc/xmpp4r/examples/basic/mass_sender.rb +67 -0
- data/data/doc/xmpp4r/examples/basic/mucinfo.rb +39 -0
- data/data/doc/xmpp4r/examples/basic/mucsimplebot.rb +83 -0
- data/data/doc/xmpp4r/examples/basic/register.rb +25 -0
- data/data/doc/xmpp4r/examples/basic/remove_registration.rb +18 -0
- data/data/doc/xmpp4r/examples/basic/roster.rb +42 -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 +172 -0
- data/data/doc/xmpp4r/examples/basic/send_vcard.rb +68 -0
- data/data/doc/xmpp4r/examples/basic/versionbot.rb +75 -0
- data/data/doc/xmpp4r/examples/buggy/jabber2jabber/jabber2jabber.rb +18 -0
- data/data/doc/xmpp4r/examples/buggy/miniedgarr_cgi.rb +192 -0
- data/data/doc/xmpp4r/examples/buggy/miniedgarr_watch.rb +82 -0
- data/lib/callbacks.rb +122 -0
- data/lib/xmpp4r/authenticationfailure.rb +13 -0
- data/lib/xmpp4r/bytestreams/helper/filetransfer.rb +315 -0
- data/lib/xmpp4r/bytestreams/helper/ibb/base.rb +256 -0
- data/lib/xmpp4r/bytestreams/helper/ibb/initiator.rb +30 -0
- data/lib/xmpp4r/bytestreams/helper/ibb/target.rb +46 -0
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/base.rb +151 -0
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/initiator.rb +85 -0
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb +178 -0
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/socks5.rb +56 -0
- data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/target.rb +61 -0
- data/lib/xmpp4r/bytestreams/iq/bytestreams.rb +177 -0
- data/lib/xmpp4r/bytestreams/iq/si.rb +221 -0
- data/lib/xmpp4r/bytestreams.rb +11 -0
- data/lib/xmpp4r/client.rb +249 -0
- data/lib/xmpp4r/component.rb +103 -0
- data/lib/xmpp4r/connection.rb +166 -0
- data/lib/xmpp4r/dataforms/x/data.rb +248 -0
- data/lib/xmpp4r/dataforms.rb +1 -0
- data/lib/xmpp4r/debuglog.rb +34 -0
- data/lib/xmpp4r/delay/x/delay.rb +100 -0
- data/lib/xmpp4r/delay.rb +1 -0
- data/lib/xmpp4r/discovery/iq/discoinfo.rb +225 -0
- data/lib/xmpp4r/discovery/iq/discoitems.rb +162 -0
- data/lib/xmpp4r/discovery.rb +2 -0
- data/lib/xmpp4r/error.rb +230 -0
- data/lib/xmpp4r/errorexception.rb +32 -0
- data/lib/xmpp4r/feature_negotiation/iq/feature.rb +42 -0
- data/lib/xmpp4r/feature_negotiation.rb +1 -0
- data/lib/xmpp4r/idgenerator.rb +37 -0
- data/lib/xmpp4r/iq.rb +229 -0
- data/lib/xmpp4r/jid.rb +167 -0
- data/lib/xmpp4r/message.rb +171 -0
- data/lib/xmpp4r/muc/helper/mucbrowser.rb +107 -0
- data/lib/xmpp4r/muc/helper/mucclient.rb +382 -0
- data/lib/xmpp4r/muc/helper/simplemucclient.rb +222 -0
- data/lib/xmpp4r/muc/x/muc.rb +98 -0
- data/lib/xmpp4r/muc/x/mucuserinvite.rb +58 -0
- data/lib/xmpp4r/muc/x/mucuseritem.rb +148 -0
- data/lib/xmpp4r/muc.rb +6 -0
- data/lib/xmpp4r/presence.rb +255 -0
- data/lib/xmpp4r/query.rb +43 -0
- data/lib/xmpp4r/rexmladdons.rb +826 -0
- data/lib/xmpp4r/roster/helper/roster.rb +514 -0
- data/lib/xmpp4r/roster/iq/roster.rb +244 -0
- data/lib/xmpp4r/roster/x/roster.rb +155 -0
- data/lib/xmpp4r/roster.rb +4 -0
- data/lib/xmpp4r/sasl.rb +167 -0
- data/lib/xmpp4r/stream.rb +543 -0
- data/lib/xmpp4r/streamparser.rb +77 -0
- data/lib/xmpp4r/vcard/helper/vcard.rb +86 -0
- data/lib/xmpp4r/vcard/iq/vcard.rb +102 -0
- data/lib/xmpp4r/vcard.rb +3 -0
- data/lib/xmpp4r/version/helper/responder.rb +71 -0
- data/lib/xmpp4r/version/helper/simpleresponder.rb +44 -0
- data/lib/xmpp4r/version/iq/version.rb +118 -0
- data/lib/xmpp4r/version.rb +3 -0
- data/lib/xmpp4r/x.rb +43 -0
- data/lib/xmpp4r/xmlstanza.rb +174 -0
- data/lib/xmpp4r/xmpp4r.rb +16 -0
- data/lib/xmpp4r.rb +122 -0
- data/setup.rb +1360 -0
- data/test/bytestreams/tc_ibb.rb +186 -0
- data/test/bytestreams/tc_socks5bytestreams.rb +57 -0
- data/test/delay/tc_xdelay.rb +51 -0
- data/test/lib/clienttester.rb +110 -0
- data/test/muc/tc_muc_mucclient.rb +569 -0
- data/test/muc/tc_muc_simplemucclient.rb +72 -0
- data/test/roster/.tc_helper.rb.swp +0 -0
- data/test/roster/tc_helper.rb +389 -0
- data/test/roster/tc_iqqueryroster.rb +140 -0
- data/test/roster/tc_xroster.rb +70 -0
- data/test/tc_callbacks.rb +128 -0
- data/test/tc_class_names.rb +129 -0
- data/test/tc_client.rb +30 -0
- data/test/tc_error.rb +103 -0
- data/test/tc_idgenerator.rb +30 -0
- data/test/tc_iq.rb +109 -0
- data/test/tc_iqquery.rb +31 -0
- data/test/tc_jid.rb +202 -0
- data/test/tc_message.rb +114 -0
- data/test/tc_presence.rb +148 -0
- data/test/tc_stream.rb +182 -0
- data/test/tc_streamError.rb +87 -0
- data/test/tc_streamSend.rb +59 -0
- data/test/tc_streamThreaded.rb +168 -0
- data/test/tc_xmlstanza.rb +76 -0
- data/test/ts_xmpp4r.rb +34 -0
- data/test/vcard/tc_iqvcard.rb +52 -0
- data/test/version/tc_helper.rb +46 -0
- data/test/version/tc_iqqueryversion.rb +96 -0
- data/tools/doctoweb.bash +30 -0
- data/tools/gen_requires.bash +10 -0
- metadata +232 -0
@@ -0,0 +1,192 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
# cp /usr/local/share/psi/iconsets/roster/lightbulb/{away,online,offline,xa,chat,dnd}.png .
|
4
|
+
|
5
|
+
$:.unshift '../lib'
|
6
|
+
|
7
|
+
require 'GD'
|
8
|
+
require 'cgi'
|
9
|
+
require 'digest/md5'
|
10
|
+
|
11
|
+
require 'rexml/document'
|
12
|
+
|
13
|
+
require 'xmpp4r'
|
14
|
+
require 'xmpp4r/iqqueryroster'
|
15
|
+
|
16
|
+
# Handle CGI parameters
|
17
|
+
cgi = CGI.new
|
18
|
+
jid = Jabber::JID.new(cgi['jid']).strip
|
19
|
+
jidhash = cgi['hash']
|
20
|
+
transparency = (cgi['transparency'] == 'true')
|
21
|
+
|
22
|
+
# Create data
|
23
|
+
|
24
|
+
roster = Jabber::IqQueryRoster.new
|
25
|
+
presences = {}
|
26
|
+
|
27
|
+
# Load state
|
28
|
+
|
29
|
+
doc = REXML::Document.new(File.new('edgarrstate.xml'))
|
30
|
+
|
31
|
+
doc.root.each_element { |e|
|
32
|
+
if (e.name == 'query') && (e.namespace == 'jabber:iq:roster')
|
33
|
+
roster.import(e)
|
34
|
+
elsif e.name == 'presence'
|
35
|
+
pres = Jabber::Presence.new.import(e)
|
36
|
+
|
37
|
+
if (pres.from.strip == jid) || (Digest::MD5.new(pres.from.strip.to_s).to_s == jidhash)
|
38
|
+
if (jid == '') && !jidhash.nil?
|
39
|
+
jid = pres.from.strip
|
40
|
+
end
|
41
|
+
presences[pres.from] = pres
|
42
|
+
end
|
43
|
+
end
|
44
|
+
}
|
45
|
+
|
46
|
+
resources = (presences.size < 1) ? 1 : presences.size
|
47
|
+
|
48
|
+
|
49
|
+
class BannerTable
|
50
|
+
def initialize
|
51
|
+
@lines = []
|
52
|
+
end
|
53
|
+
|
54
|
+
def last
|
55
|
+
@lines[@lines.size - 1]
|
56
|
+
end
|
57
|
+
|
58
|
+
def add_line
|
59
|
+
@lines.push(BannerLine.new)
|
60
|
+
end
|
61
|
+
|
62
|
+
def paint
|
63
|
+
width = 0
|
64
|
+
height = 0
|
65
|
+
@lines.each do |line|
|
66
|
+
if width < line.w
|
67
|
+
width = line.w
|
68
|
+
end
|
69
|
+
height += line.h
|
70
|
+
end
|
71
|
+
|
72
|
+
gd = GD::Image.new(width + 6, height + 6)
|
73
|
+
white = gd.colorAllocate(255,255,255)
|
74
|
+
black = gd.colorAllocate(0,0,0)
|
75
|
+
|
76
|
+
gd.fill(0, 0, black)
|
77
|
+
gd.interlace = true
|
78
|
+
gd.rectangle(0,0,width + 5,height + 5,white)
|
79
|
+
y = 2
|
80
|
+
|
81
|
+
@lines.each do |line|
|
82
|
+
line.paint(gd, 3, y + (line.h / 2))
|
83
|
+
y += line.h
|
84
|
+
end
|
85
|
+
|
86
|
+
gd
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
class BannerLine
|
91
|
+
def initialize
|
92
|
+
@items = []
|
93
|
+
end
|
94
|
+
|
95
|
+
def add(type, text)
|
96
|
+
@items.push(BannerItem.new(type, text))
|
97
|
+
end
|
98
|
+
|
99
|
+
def w
|
100
|
+
w = 1
|
101
|
+
@items.each do |item|
|
102
|
+
w += item.w
|
103
|
+
end
|
104
|
+
w
|
105
|
+
end
|
106
|
+
|
107
|
+
def h
|
108
|
+
h = 0
|
109
|
+
@items.each do |item|
|
110
|
+
if h < item.h
|
111
|
+
h = item.h
|
112
|
+
end
|
113
|
+
end
|
114
|
+
h
|
115
|
+
end
|
116
|
+
|
117
|
+
def paint(gd, x_start, y_center)
|
118
|
+
x = x_start
|
119
|
+
@items.each do |item|
|
120
|
+
item.paint(gd, x, y_center - (item.h / 2))
|
121
|
+
x += item.w
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
class BannerItem
|
127
|
+
def initialize(type, text)
|
128
|
+
@type = type
|
129
|
+
@text = text
|
130
|
+
end
|
131
|
+
|
132
|
+
def w
|
133
|
+
if @type.kind_of?(GD::Font)
|
134
|
+
(@type.width * @text.size) + 2
|
135
|
+
elsif @type.kind_of?(GD::Image)
|
136
|
+
@type.width + 2
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def h
|
141
|
+
if @type.kind_of?(GD::Font) || @type.kind_of?(GD::Image)
|
142
|
+
@type.height + 2
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def paint(gd, x, y)
|
147
|
+
if @type.kind_of?(GD::Font) && (@text.size > 0)
|
148
|
+
gd.string(@type, x + 1, y + 1, @text, gd.colorAllocate(255,255,255))
|
149
|
+
elsif @type.kind_of?(GD::Image)
|
150
|
+
type = @type.to_paletteImage(false, 256)
|
151
|
+
type.copy(gd, x + 1, y + 1, 0, 0, type.height, type.height)
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
# Paint the image
|
157
|
+
|
158
|
+
table = BannerTable.new
|
159
|
+
table.add_line
|
160
|
+
|
161
|
+
# Put JID at top
|
162
|
+
if roster[jid.strip].nil?
|
163
|
+
iname = 'Unknown'
|
164
|
+
else
|
165
|
+
iname = roster[jid.strip].iname.to_s
|
166
|
+
end
|
167
|
+
table.last.add(GD::Font::MediumFont, iname == '' ? jid.to_s : iname)
|
168
|
+
|
169
|
+
if (presences.size < 1)
|
170
|
+
table.add_line
|
171
|
+
table.last.add(GD::Font::SmallFont, 'Unavailable')
|
172
|
+
else
|
173
|
+
presences.each { |jid,pres|
|
174
|
+
show = pres.show.to_s
|
175
|
+
if pres.type == :unavailable
|
176
|
+
show = 'offline'
|
177
|
+
elsif pres.show.nil?
|
178
|
+
show = 'online'
|
179
|
+
end
|
180
|
+
|
181
|
+
table.add_line
|
182
|
+
table.last.add(GD::Image.newFromPng(File.new("miniedgarr_bulbs/#{show}.png")), nil)
|
183
|
+
prio = pres.priority.nil? ? 0 : pres.priority
|
184
|
+
table.last.add(GD::Font::SmallFont, "#{pres.from.resource} (#{prio})")
|
185
|
+
table.add_line
|
186
|
+
table.last.add(GD::Font::TinyFont, pres.status.to_s.strip)
|
187
|
+
}
|
188
|
+
end
|
189
|
+
|
190
|
+
# Convert the image to PNG and print it on standard output
|
191
|
+
print "Content-type: image/png\r\n\r\n"
|
192
|
+
table.paint.png STDOUT
|
@@ -0,0 +1,82 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
$:.unshift '../lib'
|
4
|
+
|
5
|
+
require 'rexml/document'
|
6
|
+
|
7
|
+
require 'xmpp4r'
|
8
|
+
require 'xmpp4r/iqqueryroster'
|
9
|
+
|
10
|
+
# Command line argument checking
|
11
|
+
|
12
|
+
if ARGV.size != 3
|
13
|
+
puts("Usage: ./rosterwatch.rb <jid> <password> <statefile>")
|
14
|
+
exit
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
def write_state(statefile, roster, presences)
|
19
|
+
doc = REXML::Document.new
|
20
|
+
state = doc.add(REXML::Element.new('state'))
|
21
|
+
state.add(roster)
|
22
|
+
presences.each { |jid,pres| state.add(pres) }
|
23
|
+
|
24
|
+
file = File.new(statefile, "w")
|
25
|
+
doc.write(file, 0)
|
26
|
+
file.close
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
# Building up the connection
|
31
|
+
|
32
|
+
Jabber::debug = true
|
33
|
+
|
34
|
+
jid = Jabber::JID.new(ARGV[0])
|
35
|
+
|
36
|
+
cl = Jabber::Client.new(jid, false)
|
37
|
+
cl.connect
|
38
|
+
cl.auth(ARGV[1])
|
39
|
+
|
40
|
+
|
41
|
+
roster = Jabber::IqQueryRoster.new
|
42
|
+
presences = {}
|
43
|
+
|
44
|
+
cl.add_iq_callback { |iq|
|
45
|
+
if (iq.type == :result) && iq.query.kind_of?(Jabber::IqQueryRoster)
|
46
|
+
roster.import(iq.query)
|
47
|
+
write_state(ARGV[2], roster, presences)
|
48
|
+
end
|
49
|
+
}
|
50
|
+
|
51
|
+
# TODO: <presence><x xmlns='jabber:x:delay'>...</x></presence>
|
52
|
+
cl.add_presence_callback { |pres|
|
53
|
+
# Handle subscription request
|
54
|
+
if pres.type == :subscribe
|
55
|
+
# Accept subscription
|
56
|
+
cl.send(Jabber::Presence.new.set_to(pres.from).set_type(:subscribed))
|
57
|
+
# Subscribe to sender
|
58
|
+
cl.send(Jabber::Presence.new.set_to(pres.from).set_type(:subscribe))
|
59
|
+
# Add to roster
|
60
|
+
# TODO: Resolve Nickname from vCard
|
61
|
+
roster_set_iq = Jabber::Iq.new(:set)
|
62
|
+
roster_set_iq.add(Jabber::IqQueryRoster.new).add(Jabber::RosterItem.new(pres.from.strip))
|
63
|
+
cl.send(roster_set_iq)
|
64
|
+
end
|
65
|
+
|
66
|
+
presences[pres.from] = pres
|
67
|
+
write_state(ARGV[2], roster, presences)
|
68
|
+
}
|
69
|
+
|
70
|
+
# Send request for roster
|
71
|
+
cl.send(Jabber::Iq.new_rosterget)
|
72
|
+
# Send initial presence
|
73
|
+
# This is important as it ensures reception of
|
74
|
+
# further <presence/> stanzas
|
75
|
+
cl.send(Jabber::Presence.new.set_show(:dnd).set_status('Watching my roster change...'))
|
76
|
+
|
77
|
+
loop do
|
78
|
+
cl.process
|
79
|
+
sleep(1)
|
80
|
+
end
|
81
|
+
|
82
|
+
cl.close
|
data/lib/callbacks.rb
ADDED
@@ -0,0 +1,122 @@
|
|
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
|
+
##
|
6
|
+
# This class manages a list of callbacks.
|
7
|
+
#
|
8
|
+
# ==Callbacks management and priority
|
9
|
+
#
|
10
|
+
# Callbacks are managed by the class CallbackList. When they are added, a
|
11
|
+
# priority (just a number or anything Comparable with other priorities) is
|
12
|
+
# specified. The biggest the priority is, the earliest the callback will be
|
13
|
+
# considered.
|
14
|
+
#
|
15
|
+
# Callbacks are processed for a given set of objects as long as they return
|
16
|
+
# false. If you want to stop processing, you must return true. Example :
|
17
|
+
# cbl = CallbackList::new
|
18
|
+
# c1 = false
|
19
|
+
# c2 = false
|
20
|
+
# c3 = false
|
21
|
+
# cbl.add(10) { c1 = true; 1 }
|
22
|
+
# cbl.add(5) { c2 = true; true }
|
23
|
+
# cbl.add(0) { c3 = true }
|
24
|
+
# cbl.process('aa')
|
25
|
+
# puts "#{c1} #{c2} #{c3}"
|
26
|
+
# This example would display "true true false" as callbacks processing was
|
27
|
+
# stopped after the second callback returned true.
|
28
|
+
#
|
29
|
+
# In XMPP4R, callbacks' priorities are quite normalized since we want to be
|
30
|
+
# able to "cascade" callbacks in a clean way. Here are values your code should
|
31
|
+
# take into account :
|
32
|
+
#
|
33
|
+
# >= 200:: logging & debugging callbacks. Those callbacks should not consume
|
34
|
+
# elements.
|
35
|
+
# 100-199:: Where Helpers register their callbacks. The normal value is 100,
|
36
|
+
# and Helpers shouldn't register something else unless there's a
|
37
|
+
# very good reason to.
|
38
|
+
# < 100:: all those numbers are normally available for your application.
|
39
|
+
# That's enough, don't you think ?
|
40
|
+
class CallbackList
|
41
|
+
|
42
|
+
# Create a new list of callbacks
|
43
|
+
def initialize
|
44
|
+
@list = []
|
45
|
+
end
|
46
|
+
|
47
|
+
##
|
48
|
+
# Add a callback to the list
|
49
|
+
#
|
50
|
+
# List will be sorted afterwards
|
51
|
+
#
|
52
|
+
# prio:: [Integer] the callback's priority, the higher, the sooner.
|
53
|
+
# ref:: [String] the callback's reference
|
54
|
+
# block:: [Block] a block to execute
|
55
|
+
# return:: [Jabber::CallbackList] The list, for chaining
|
56
|
+
def add(prio = 0, ref = nil, proc = nil, &block)
|
57
|
+
block = proc if proc
|
58
|
+
@list.push(Callback::new(prio, ref, block))
|
59
|
+
@list.sort! { |a, b| b.priority <=> a.priority }
|
60
|
+
self
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# Delete a callback by reference
|
65
|
+
# ref:: [String] the reference of the callback to delete
|
66
|
+
# return:: [CallBackList] The list, for chaining
|
67
|
+
def delete(ref)
|
68
|
+
@list.delete_if { |item| item.ref == ref }
|
69
|
+
self
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
# Number of elements in the list
|
74
|
+
# return:: [Integer] The number of elements
|
75
|
+
def length
|
76
|
+
@list.length
|
77
|
+
end
|
78
|
+
|
79
|
+
##
|
80
|
+
# Process an element through all my callbacks. returns e.consumed?
|
81
|
+
# e:: [Object] The elements to pass to the callback. You can pass
|
82
|
+
# several, but of course, you block must know how to handle them.
|
83
|
+
# return:: [Boolean] true if the element has been consumed
|
84
|
+
def process(*e)
|
85
|
+
# If somebody adds a new callback the list will get modified
|
86
|
+
# and sorted(!) while still iterating through it. So we use a
|
87
|
+
# local copy of @list. Any freshly added callback will receive
|
88
|
+
# the next stanzas, not the current.
|
89
|
+
list = @list.dup
|
90
|
+
|
91
|
+
# process through callbacks
|
92
|
+
list.each do |item|
|
93
|
+
return true if item.block.call(*e) == true
|
94
|
+
end
|
95
|
+
false
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# This class is used to store callbacks inside CallbackList. See the
|
100
|
+
# CallbackList class for more detailed explanations.
|
101
|
+
class Callback
|
102
|
+
|
103
|
+
# The Callback's priority
|
104
|
+
attr_reader :priority
|
105
|
+
|
106
|
+
# The Callback's reference, using for deleting purposes
|
107
|
+
attr_reader :ref
|
108
|
+
|
109
|
+
# The Callback's block to execute
|
110
|
+
attr_reader :block
|
111
|
+
|
112
|
+
##
|
113
|
+
# Create a new callback
|
114
|
+
# priority:: [Integer] the callback's priority. The higher, the sooner it
|
115
|
+
# will be executed
|
116
|
+
# ref:: [String] The callback's reference
|
117
|
+
def initialize(priority = 0, ref = nil, block = Proc::new {})
|
118
|
+
@priority = priority
|
119
|
+
@ref = ref
|
120
|
+
@block = block
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,13 @@
|
|
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
|
+
module Jabber
|
6
|
+
##
|
7
|
+
# The AuthenticationFailure is an Exception to be raised
|
8
|
+
# when Client or Component authentication fails
|
9
|
+
#
|
10
|
+
# There are no special arguments
|
11
|
+
class AuthenticationFailure < RuntimeError
|
12
|
+
end
|
13
|
+
end
|