xmpp4r 0.3
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/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,102 @@
|
|
|
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/iq'
|
|
6
|
+
|
|
7
|
+
module Jabber
|
|
8
|
+
module Vcard
|
|
9
|
+
##
|
|
10
|
+
# vCard container for User Information
|
|
11
|
+
# (can be specified by users themselves, mostly kept on servers)
|
|
12
|
+
# (JEP 0054)
|
|
13
|
+
class IqVcard < REXML::Element
|
|
14
|
+
##
|
|
15
|
+
# Initialize a <vCard/> element
|
|
16
|
+
# fields:: [Hash] Initialize with keys as XPath element names and values for element texts
|
|
17
|
+
def initialize(fields=nil)
|
|
18
|
+
super("vCard")
|
|
19
|
+
add_namespace('vcard-temp')
|
|
20
|
+
|
|
21
|
+
unless fields.nil?
|
|
22
|
+
fields.each { |name,value|
|
|
23
|
+
self[name] = value
|
|
24
|
+
}
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
##
|
|
29
|
+
# element:: [REXML::Element] to import
|
|
30
|
+
# result:: [IqVcard] with all attributes and children copied from element
|
|
31
|
+
def IqVcard.import(element)
|
|
32
|
+
IqVcard::new.import(element)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
##
|
|
36
|
+
# Get an elements/fields text
|
|
37
|
+
#
|
|
38
|
+
# vCards have too much possible children, so ask for them here
|
|
39
|
+
# and extract the result with iqvcard.element('...').text
|
|
40
|
+
# name:: [String] XPath
|
|
41
|
+
def [](name)
|
|
42
|
+
text = nil
|
|
43
|
+
each_element(name) { |child| text = child.text }
|
|
44
|
+
text
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
##
|
|
48
|
+
# Set an elements/fields text
|
|
49
|
+
# name:: [String] XPath
|
|
50
|
+
# text:: [String] Value
|
|
51
|
+
def []=(name, text)
|
|
52
|
+
xe = self
|
|
53
|
+
name.split(/\//).each do |elementname|
|
|
54
|
+
# Does the children already exist?
|
|
55
|
+
newxe = nil
|
|
56
|
+
xe.each_element(elementname) { |child| newxe = child }
|
|
57
|
+
|
|
58
|
+
if newxe.nil?
|
|
59
|
+
# Create a new
|
|
60
|
+
xe = xe.add_element(elementname)
|
|
61
|
+
else
|
|
62
|
+
# Or take existing
|
|
63
|
+
xe = newxe
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
xe.text = text
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
##
|
|
70
|
+
# Get vCard field names
|
|
71
|
+
#
|
|
72
|
+
# Example:
|
|
73
|
+
# ["NICKNAME", "BDAY", "ORG/ORGUNIT", "PHOTO/TYPE", "PHOTO/BINVAL"]
|
|
74
|
+
#
|
|
75
|
+
# result:: [Array] of [String]
|
|
76
|
+
def fields
|
|
77
|
+
element_names(self).uniq
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
##
|
|
81
|
+
# Recursive helper function,
|
|
82
|
+
# returns all element names in an array, concatenated
|
|
83
|
+
# to their parent's name with a slash
|
|
84
|
+
def element_names(xe, prefix='') # :nodoc:
|
|
85
|
+
res = []
|
|
86
|
+
xe.each_element { |child|
|
|
87
|
+
if child.kind_of?(REXML::Element)
|
|
88
|
+
children = element_names(child, "#{prefix}#{child.name}/")
|
|
89
|
+
if children == []
|
|
90
|
+
res.push("#{prefix}#{child.name}")
|
|
91
|
+
else
|
|
92
|
+
res += children
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
}
|
|
96
|
+
res
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
Iq.add_elementclass('vCard', IqVcard)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
data/lib/xmpp4r/vcard.rb
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
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 'callbacks'
|
|
6
|
+
require 'xmpp4r/version/iq/version'
|
|
7
|
+
|
|
8
|
+
module Jabber
|
|
9
|
+
module Version
|
|
10
|
+
##
|
|
11
|
+
# A class to answer version requests using IqQueryVersion
|
|
12
|
+
#
|
|
13
|
+
# If you don't need the flexibility of dynamic responses with
|
|
14
|
+
# the callback you can register with add_version_callback,
|
|
15
|
+
# take a look at SimpleResponder
|
|
16
|
+
class Responder
|
|
17
|
+
##
|
|
18
|
+
# Initialize a new version responder
|
|
19
|
+
#
|
|
20
|
+
# Registers it's callback (prio = 180, ref = self)
|
|
21
|
+
# stream:: [Stream] Where to register callback handlers
|
|
22
|
+
def initialize(stream)
|
|
23
|
+
@stream = stream
|
|
24
|
+
@versioncbs = CallbackList.new
|
|
25
|
+
|
|
26
|
+
stream.add_iq_callback(180, self) { |iq|
|
|
27
|
+
iq_callback(iq)
|
|
28
|
+
}
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
##
|
|
32
|
+
# Add a callback for Iq stanzas with IqQueryVersion
|
|
33
|
+
#
|
|
34
|
+
# First argument passed to block is the Iq stanza,
|
|
35
|
+
# second argument is a block, which can be called with
|
|
36
|
+
# software name, version and os
|
|
37
|
+
#
|
|
38
|
+
# Example:
|
|
39
|
+
# my_version_helper.add_version_callback { |iq,block|
|
|
40
|
+
# block.call('Cool client', '6.0', 'Cool OS')
|
|
41
|
+
# }
|
|
42
|
+
def add_version_callback(priority = 0, ref = nil, &block)
|
|
43
|
+
@versioncbs.add(priority, ref, block)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
##
|
|
47
|
+
# <iq/> callback handler to answer Software Version queries
|
|
48
|
+
# (registered by constructor and used internally only)
|
|
49
|
+
#
|
|
50
|
+
# Used internally
|
|
51
|
+
def iq_callback(iq)
|
|
52
|
+
if iq.type == :get
|
|
53
|
+
if iq.query.kind_of?(IqQueryVersion)
|
|
54
|
+
replyblock = lambda { |name,version,os|
|
|
55
|
+
answer = iq.answer
|
|
56
|
+
answer.type = :result
|
|
57
|
+
answer.query.set_iname(name).set_version(version).set_os(os)
|
|
58
|
+
|
|
59
|
+
@stream.send(answer)
|
|
60
|
+
}
|
|
61
|
+
@versioncbs.process(iq, replyblock)
|
|
62
|
+
else
|
|
63
|
+
false
|
|
64
|
+
end
|
|
65
|
+
else
|
|
66
|
+
false
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
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/iq'
|
|
6
|
+
require 'xmpp4r/version/helper/responder'
|
|
7
|
+
|
|
8
|
+
module Jabber
|
|
9
|
+
module Version
|
|
10
|
+
##
|
|
11
|
+
# A class to answer version requests using IqQueryVersion
|
|
12
|
+
#
|
|
13
|
+
# This is simplification as one doesn't need dynamic
|
|
14
|
+
# version answering normally.
|
|
15
|
+
#
|
|
16
|
+
# Example usage:
|
|
17
|
+
# Jabber::Version::SimpleResponder.new(my_client, "My cool XMPP4R script", "1.0", "Younicks")
|
|
18
|
+
class SimpleResponder < Responder
|
|
19
|
+
attr_accessor :name
|
|
20
|
+
attr_accessor :version
|
|
21
|
+
attr_accessor :os
|
|
22
|
+
|
|
23
|
+
##
|
|
24
|
+
# Initialize a new version responder
|
|
25
|
+
#
|
|
26
|
+
# Registers it's callback (prio = 180, ref = self)
|
|
27
|
+
# stream:: [Stream] Where to register callback handlers
|
|
28
|
+
# name:: [String] Software name for answers
|
|
29
|
+
# version:: [String] Software versio for answers
|
|
30
|
+
# os:: [String] Optional operating system name for answers
|
|
31
|
+
def initialize(stream, name, version, os=nil)
|
|
32
|
+
super stream
|
|
33
|
+
|
|
34
|
+
@name = name
|
|
35
|
+
@version = version
|
|
36
|
+
@os = os
|
|
37
|
+
|
|
38
|
+
add_version_callback(180, self) { |iq,block|
|
|
39
|
+
block.call(@name, @version, @os)
|
|
40
|
+
}
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,118 @@
|
|
|
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/query'
|
|
6
|
+
|
|
7
|
+
module Jabber
|
|
8
|
+
module Version
|
|
9
|
+
##
|
|
10
|
+
# Class for handling queries for 'Software Version'
|
|
11
|
+
# (JEP 0092)
|
|
12
|
+
#
|
|
13
|
+
# Notice that according to JEP 0092 only the <os/> element can be omitted,
|
|
14
|
+
# <name/> (iname) and <version/> must be present
|
|
15
|
+
class IqQueryVersion < IqQuery
|
|
16
|
+
##
|
|
17
|
+
# Create a new <query xmlns='jabber:iq:version'/> element
|
|
18
|
+
def initialize(iname='', version='', os=nil)
|
|
19
|
+
super()
|
|
20
|
+
add_namespace('jabber:iq:version')
|
|
21
|
+
set_iname(iname)
|
|
22
|
+
set_version(version)
|
|
23
|
+
set_os(os)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
##
|
|
27
|
+
# Import an element,
|
|
28
|
+
# deletes <name/>, <version/> and <os/> elements first
|
|
29
|
+
# xe:: [REXML::Element]
|
|
30
|
+
def import(xe)
|
|
31
|
+
delete_element('name')
|
|
32
|
+
delete_element('version')
|
|
33
|
+
delete_element('os')
|
|
34
|
+
super
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
##
|
|
38
|
+
# Get the name of the software
|
|
39
|
+
#
|
|
40
|
+
# This has been renamed to 'iname' here to keep
|
|
41
|
+
# REXML::Element#name accessible
|
|
42
|
+
def iname
|
|
43
|
+
first_element_text('name')
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
##
|
|
47
|
+
# Set the name of the software
|
|
48
|
+
#
|
|
49
|
+
# The element won't be deleted if text is nil as
|
|
50
|
+
# it must occur in a version query, but its text will
|
|
51
|
+
# be empty.
|
|
52
|
+
def iname=(text)
|
|
53
|
+
replace_element_text('name', text.nil? ? '' : text)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
##
|
|
57
|
+
# Set the name of the software (chaining-friendly)
|
|
58
|
+
# result:: [String] or nil
|
|
59
|
+
def set_iname(text)
|
|
60
|
+
self.iname = text
|
|
61
|
+
self
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
##
|
|
65
|
+
# Get the version of the software
|
|
66
|
+
# result:: [String] or nil
|
|
67
|
+
def version
|
|
68
|
+
first_element_text('version')
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
##
|
|
72
|
+
# Set the version of the software
|
|
73
|
+
#
|
|
74
|
+
# The element won't be deleted if text is nil as
|
|
75
|
+
# it must occur in a version query
|
|
76
|
+
def version=(text)
|
|
77
|
+
replace_element_text('version', text.nil? ? '' : text)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
##
|
|
81
|
+
# Set the version of the software (chaining-friendly)
|
|
82
|
+
# text:: [String]
|
|
83
|
+
def set_version(text)
|
|
84
|
+
self.version = text
|
|
85
|
+
self
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
##
|
|
89
|
+
# Get the operating system or nil
|
|
90
|
+
# (os is not mandatory for Version Query)
|
|
91
|
+
def os
|
|
92
|
+
first_element_text('os')
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
##
|
|
96
|
+
# Set the os of the software
|
|
97
|
+
# text:: [String] or nil
|
|
98
|
+
def os=(text)
|
|
99
|
+
if text
|
|
100
|
+
replace_element_text('os', text)
|
|
101
|
+
else
|
|
102
|
+
delete_elements('os')
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
##
|
|
107
|
+
# Set the os of the software (chaining-friendly)
|
|
108
|
+
# text:: [String] or nil
|
|
109
|
+
def set_os(text)
|
|
110
|
+
self.os = text
|
|
111
|
+
self
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
IqQuery.add_namespaceclass('jabber:iq:version', IqQueryVersion)
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
data/lib/xmpp4r/x.rb
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
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/rexmladdons'
|
|
6
|
+
|
|
7
|
+
module Jabber
|
|
8
|
+
##
|
|
9
|
+
# A class used to build/parse <x/> elements
|
|
10
|
+
#
|
|
11
|
+
# These elements may occur as "attachments"
|
|
12
|
+
# in [Message] and [Presence] stanzas
|
|
13
|
+
class X < REXML::Element
|
|
14
|
+
@@namespace_classes = {}
|
|
15
|
+
|
|
16
|
+
##
|
|
17
|
+
# Initialize a <x/> element
|
|
18
|
+
#
|
|
19
|
+
# Does nothing more than setting the element's name to 'x'
|
|
20
|
+
def initialize
|
|
21
|
+
super("x")
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
##
|
|
25
|
+
# Create a new [X] from an XML-Element
|
|
26
|
+
# element:: [REXML::Element] to import, will be automatically converted if namespace appropriate
|
|
27
|
+
def X.import(element)
|
|
28
|
+
if @@namespace_classes.has_key?(element.namespace)
|
|
29
|
+
@@namespace_classes[element.namespace]::new.import(element)
|
|
30
|
+
else
|
|
31
|
+
X::new.import(element)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
##
|
|
36
|
+
# Add a class by namespace for automatic X conversion (see X.import)
|
|
37
|
+
# ns:: [String] Namespace (e.g. 'jabber:x:delay')
|
|
38
|
+
# xclass:: [X] x class derived from X
|
|
39
|
+
def X.add_namespaceclass(ns, xclass)
|
|
40
|
+
@@namespace_classes[ns] = xclass
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -0,0 +1,174 @@
|
|
|
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/jid'
|
|
6
|
+
require 'xmpp4r/error'
|
|
7
|
+
|
|
8
|
+
module Jabber
|
|
9
|
+
##
|
|
10
|
+
# root class of all Jabber XML elements
|
|
11
|
+
class XMLStanza < REXML::Element
|
|
12
|
+
##
|
|
13
|
+
# Compose a response by doing the following:
|
|
14
|
+
# * Create a new XMLStanza of the same subclass
|
|
15
|
+
# with the same element-name
|
|
16
|
+
# * Import xmlstanza if import is true
|
|
17
|
+
# * Swap 'to' and 'from'
|
|
18
|
+
# * Copy 'id'
|
|
19
|
+
# * Does not take care about the type
|
|
20
|
+
#
|
|
21
|
+
# *Attention*: Be careful when answering to stanzas with
|
|
22
|
+
# <tt>type == :error</tt> - answering to an error may generate
|
|
23
|
+
# another error on the other side, which could be leading to a
|
|
24
|
+
# ping-pong effect quickly!
|
|
25
|
+
#
|
|
26
|
+
# xmlstanza:: [XMLStanza] source
|
|
27
|
+
# import:: [true or false] Copy attributes and children of source
|
|
28
|
+
# result:: [XMLStanza] answer stanza
|
|
29
|
+
def XMLStanza.answer(xmlstanza, import=true)
|
|
30
|
+
x = xmlstanza.class::new
|
|
31
|
+
if import
|
|
32
|
+
x.import(xmlstanza)
|
|
33
|
+
end
|
|
34
|
+
x.from = xmlstanza.to
|
|
35
|
+
x.to = xmlstanza.from
|
|
36
|
+
x.id = xmlstanza.id
|
|
37
|
+
x
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
##
|
|
41
|
+
# Add a sub-element
|
|
42
|
+
#
|
|
43
|
+
# Will be converted to [Error] if named "error"
|
|
44
|
+
# element:: [REXML::Element] to add
|
|
45
|
+
def typed_add(element)
|
|
46
|
+
if element.kind_of?(REXML::Element) && (element.name == 'error')
|
|
47
|
+
super(Error::import(element))
|
|
48
|
+
else
|
|
49
|
+
super(element)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
##
|
|
54
|
+
# Return the first <tt><error/></tt> child
|
|
55
|
+
def error
|
|
56
|
+
first_element('error')
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
##
|
|
60
|
+
# Compose a response of this XMLStanza
|
|
61
|
+
# (see XMLStanza.answer)
|
|
62
|
+
# result:: [XMLStanza] New constructed stanza
|
|
63
|
+
def answer(import=true)
|
|
64
|
+
XMLStanza.answer(self, import)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
##
|
|
68
|
+
# Makes some changes to the structure of an XML element to help
|
|
69
|
+
# it respect the specification. For example, in a message, we should
|
|
70
|
+
# have <subject/> < <body/> < { rest of tags }
|
|
71
|
+
def normalize
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
##
|
|
75
|
+
# get the to attribute
|
|
76
|
+
#
|
|
77
|
+
# return:: [String] the element's to attribute
|
|
78
|
+
def to
|
|
79
|
+
(a = attribute('to')).nil? ? a : JID::new(a.value)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
##
|
|
83
|
+
# set the to attribute
|
|
84
|
+
#
|
|
85
|
+
# v:: [String] the value to set
|
|
86
|
+
def to= (v)
|
|
87
|
+
add_attribute('to', v ? v.to_s : nil)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
##
|
|
91
|
+
# set the to attribute (chaining-friendly)
|
|
92
|
+
#
|
|
93
|
+
# v:: [String] the value to set
|
|
94
|
+
def set_to(v)
|
|
95
|
+
self.to = v
|
|
96
|
+
self
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
##
|
|
100
|
+
# get the from attribute
|
|
101
|
+
#
|
|
102
|
+
# return:: [String] the element's from attribute
|
|
103
|
+
def from
|
|
104
|
+
(a = attribute('from')).nil? ? a : JID::new(a.value)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
##
|
|
108
|
+
# set the from attribute
|
|
109
|
+
#
|
|
110
|
+
# v:: [String] the value from set
|
|
111
|
+
def from= (v)
|
|
112
|
+
add_attribute('from', v ? v.to_s : nil)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
##
|
|
116
|
+
# set the from attribute (chaining-friendly)
|
|
117
|
+
#
|
|
118
|
+
# v:: [String] the value from set
|
|
119
|
+
def set_from(v)
|
|
120
|
+
add_attribute('from', v ? v.to_s : nil)
|
|
121
|
+
self
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
##
|
|
125
|
+
# get the id attribute
|
|
126
|
+
#
|
|
127
|
+
# return:: [String] the element's id attribute
|
|
128
|
+
def id
|
|
129
|
+
(a = attribute('id')).nil? ? a : a.value
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
##
|
|
133
|
+
# set the id attribute
|
|
134
|
+
#
|
|
135
|
+
# v:: [String] the value id set
|
|
136
|
+
def id= (v)
|
|
137
|
+
add_attribute('id', v)
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
##
|
|
141
|
+
# set the id attribute (chaining-friendly)
|
|
142
|
+
#
|
|
143
|
+
# v:: [String] the value id set
|
|
144
|
+
def set_id(v)
|
|
145
|
+
add_attribute('id', v)
|
|
146
|
+
self
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
##
|
|
150
|
+
# get the type attribute
|
|
151
|
+
#
|
|
152
|
+
# return:: [String] the element's type attribute
|
|
153
|
+
def type
|
|
154
|
+
(a = attribute('type')).nil? ? a : a.value
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
##
|
|
158
|
+
# set the type attribute
|
|
159
|
+
#
|
|
160
|
+
# v:: [String] the value type set
|
|
161
|
+
def type= (v)
|
|
162
|
+
add_attribute('type', v)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
##
|
|
166
|
+
# set the type attribute (chaining-friendly)
|
|
167
|
+
#
|
|
168
|
+
# v:: [String] the value type set
|
|
169
|
+
def set_type(v)
|
|
170
|
+
add_attribute('type', v)
|
|
171
|
+
self
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
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
|
+
# The Jabber module is the root namespace of the library. You might want
|
|
7
|
+
# to Include it in your script to ease your coding. It provides
|
|
8
|
+
# a simple debug logging support.
|
|
9
|
+
module Jabber
|
|
10
|
+
# XMPP4R Version number
|
|
11
|
+
XMPP4R_VERSION = '0.3'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
require 'xmpp4r/client'
|
|
15
|
+
require 'xmpp4r/component'
|
|
16
|
+
require 'xmpp4r/debuglog'
|
data/lib/xmpp4r.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
|
+
# ==Introduction
|
|
6
|
+
#
|
|
7
|
+
# XMPP4R is a XMPP/Jabber library for Ruby. It can be used to build scripts
|
|
8
|
+
# using Jabber, full-featured Jabber clients, and components. It is written
|
|
9
|
+
# with extensibility in mind.
|
|
10
|
+
#
|
|
11
|
+
# ==XML management
|
|
12
|
+
#
|
|
13
|
+
# All the XML parsing is REXML's, and XML stanzas like <message/> (class
|
|
14
|
+
# <tt>Jabber::Message</tt>) or <iq/> (class <tt>Jabber::Iq</tt>) are indirect
|
|
15
|
+
# derivatives from REXML's Element class. This provide a maximum flexibity:
|
|
16
|
+
# the user can access attributes and childs using either the XMPP4R's helpers
|
|
17
|
+
# or directly using REXML's methods.
|
|
18
|
+
#
|
|
19
|
+
# ===Automatic element casting
|
|
20
|
+
#
|
|
21
|
+
# Because there are special classes derived from REXML::Element to ease
|
|
22
|
+
# development on the protocol level, Elements must be cast to them. This is
|
|
23
|
+
# done via REXML::Element.import. This method is also used in import class
|
|
24
|
+
# methods of some Element classes.
|
|
25
|
+
#
|
|
26
|
+
# The first occurance of this feature is in Jabber::Stream::receive:
|
|
27
|
+
# * <tt><message/></tt> stanzas are cast to Jabber::Message class
|
|
28
|
+
# * <tt><presence/></tt> stanzas are cast to Jabber::Presence class
|
|
29
|
+
# * <tt><iq/></tt> stanzas are cast to Jabber::Iq class
|
|
30
|
+
#
|
|
31
|
+
# This is not only useful for stanzas but all other XML processing, too:
|
|
32
|
+
# * <tt><x/></tt> children elements of <tt><message/></tt> and <tt><presence/></tt> are converted to Jabber::X
|
|
33
|
+
# * <tt><error/></tt> children elements of all three stanzas are converted to Jabber::Error
|
|
34
|
+
# * <tt><query/></tt> children elements of <tt><iq/></tt> are converted to Jabber::IqQuery
|
|
35
|
+
# * <tt><vCard/></tt> children elements of <tt><iq/></tt> are converted to Jabber::IqVcard
|
|
36
|
+
#
|
|
37
|
+
# The following conversion facilities are only executed if the respective
|
|
38
|
+
# library parts are loaded. See below for more details on Non-basic features.
|
|
39
|
+
# * Jabber::IqQuery elements are converted to Jabber::Roster::IqQueryRoster if their
|
|
40
|
+
# namespace is 'jabber:iq:roster'
|
|
41
|
+
# * Jabber::IqQuery elements are converted to Jabber::Version::IqQueryVersion if their
|
|
42
|
+
# namespace is 'jabber:iq:version'
|
|
43
|
+
# * Jabber::IqQuery elements are converted to Jabber::Discovery::IqQueryDiscoInfo if their
|
|
44
|
+
# namespace is 'http://jabber.org/protocol/disco#info'
|
|
45
|
+
# * Jabber::IqQuery elements are converted to Jabber::Discovery::IqQueryDiscoItems if their
|
|
46
|
+
# namespace is 'http://jabber.org/protocol/disco#items'
|
|
47
|
+
# * <tt><item/></tt> children elements of Jabber::Roster::IqQueryRoster are converted
|
|
48
|
+
# to Jabber::Roster::RosterItem
|
|
49
|
+
# * <tt><identity/></tt> children elements of Jabber::IqQueryDiscoInfo are converted
|
|
50
|
+
# to Jabber::Discovery::DiscoIdentity
|
|
51
|
+
# * <tt><feature/></tt> children elements of Jabber::IqQueryDiscoInfo are converted
|
|
52
|
+
# to Jabber::Discovery::DiscoFeature
|
|
53
|
+
# * <tt><item/></tt> children elements of Jabber::IqQueryDiscoItems are converted
|
|
54
|
+
# to Jabber::Discovery::DiscoItem
|
|
55
|
+
#
|
|
56
|
+
# To use this, don't check for:
|
|
57
|
+
# <tt>iq.queryns == 'http://jabber.org/protocol/disco#info'</tt>
|
|
58
|
+
#
|
|
59
|
+
# But instead check for the query's class:
|
|
60
|
+
# <tt>iq.query.kind_of?(Jabber::IqQueryDiscoInfo)</tt>
|
|
61
|
+
#
|
|
62
|
+
# ==Threaded and non-threaded modes
|
|
63
|
+
#
|
|
64
|
+
# From the user's point of view, the library can be used either in threaded mode,
|
|
65
|
+
# or in non-threaded mode, using a call to <tt>Jabber::Stream#process</tt> to
|
|
66
|
+
# receive pending messages.
|
|
67
|
+
#
|
|
68
|
+
# ==Where to begin?
|
|
69
|
+
#
|
|
70
|
+
# Because it is built in an extensible way, it might be hard for newcomers to
|
|
71
|
+
# understand where to look at documentation for a specific method. For example,
|
|
72
|
+
# Client heritates from Connection, which itself heritates from Stream.
|
|
73
|
+
#
|
|
74
|
+
# A newcomer should have a look at the <tt>Jabber::Client</tt> and
|
|
75
|
+
# <tt>Jabber::Component</tt> classes, and their parent classes
|
|
76
|
+
# <tt>Jabber::Connection</tt> and <tt>Jabber::Stream</tt>. The best way to
|
|
77
|
+
# understand how to use them is probably to look at the examples in the
|
|
78
|
+
# <tt>examples/</tt> dir.
|
|
79
|
+
#
|
|
80
|
+
# ==Non-basic features
|
|
81
|
+
#
|
|
82
|
+
# <tt>require 'xmpp4r'</tt> does only include basic functionality as
|
|
83
|
+
# Connections, Authentication, Stream processing, Callbacks, Stanza handling
|
|
84
|
+
# and Debugging to keep the library's footprint small.
|
|
85
|
+
#
|
|
86
|
+
# There is code for features that aren't required by a *basic* client. These
|
|
87
|
+
# must be additionally included to use them.
|
|
88
|
+
#
|
|
89
|
+
# ===Protocol-level features
|
|
90
|
+
#
|
|
91
|
+
# You're highly advised to read the according RFCs and JEPs if you intend to
|
|
92
|
+
# use them. The benefit will be that you'll understand the protocols and be
|
|
93
|
+
# going to be more efficient when programming with them.
|
|
94
|
+
#
|
|
95
|
+
# * Jabber::Bytestreams, Jabber::FileTransfer: <tt>require 'xmpp4r/bytestreams'</tt>
|
|
96
|
+
# * Jabber::Dataforms: <tt>require 'xmpp4r/dataforms'</tt>
|
|
97
|
+
# * Jabber::Delay: <tt>require 'xmpp4r/delay'</tt>
|
|
98
|
+
# * Jabber::Discovery: <tt>require 'xmpp4r/discovery'</tt>
|
|
99
|
+
# * Jabber::FeatureNegotiation: <tt>require 'xmpp4r/feature_negotiation'</tt>
|
|
100
|
+
# * Jabber::MUC: <tt>require 'xmpp4r/muc'</tt>
|
|
101
|
+
# * Jabber::Roster: <tt>require 'xmpp4r/roster'</tt>
|
|
102
|
+
# * Jabber::Vcard: <tt>require 'xmpp4r/vcard'</tt>
|
|
103
|
+
# * Jabber::Version: <tt>require 'xmpp4r/version'</tt>
|
|
104
|
+
#
|
|
105
|
+
# ===Helpers
|
|
106
|
+
#
|
|
107
|
+
# Helpers are intended to give more simplistic interfaces to various tasks
|
|
108
|
+
# of Jabber clients at the cost of flexibility. But you won't need that
|
|
109
|
+
# order of flexibility for the most things.
|
|
110
|
+
#
|
|
111
|
+
# * Jabber::Roster::Helper: <tt>require 'xmpp4r/roster'</tt>
|
|
112
|
+
# * Jabber::MUC::MUCBrowser, Jabber::MUC::MUCClient, Jabber::MUC::SimpleMUCClient: <tt>require 'xmpp4r/muc'</tt>
|
|
113
|
+
# * Jabber::Version::SimpleResponder, Jabber::Version::Responder: <tt>require 'xmpp4r/version'</tt>
|
|
114
|
+
# * Jabber::Vcard::Helper: <tt>require 'xmpp4r/vcard'</tt>
|
|
115
|
+
# * Jabber::FileTransfer::Helper, Jabber::Bytestreams::SOCKS5BytestreamsServer: <tt>require 'xmpp4r/bytestreams'</tt>
|
|
116
|
+
#
|
|
117
|
+
# ==Debugging
|
|
118
|
+
#
|
|
119
|
+
# Dumping your Jabber stream can be enabled this way:
|
|
120
|
+
# Jabber::debug = true
|
|
121
|
+
|
|
122
|
+
require 'xmpp4r/xmpp4r'
|