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,166 @@
|
|
|
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 'openssl'
|
|
6
|
+
require 'xmpp4r/stream'
|
|
7
|
+
require 'xmpp4r/errorexception'
|
|
8
|
+
|
|
9
|
+
module Jabber
|
|
10
|
+
##
|
|
11
|
+
# The connection class manages the TCP connection to the Jabber server
|
|
12
|
+
#
|
|
13
|
+
class Connection < Stream
|
|
14
|
+
attr_reader :host, :port
|
|
15
|
+
|
|
16
|
+
# Allow TLS negotiation? Defaults to true
|
|
17
|
+
attr_accessor :allow_tls
|
|
18
|
+
|
|
19
|
+
# How many seconds to wait for <stream:features/>
|
|
20
|
+
# before proceeding
|
|
21
|
+
attr_accessor :features_timeout
|
|
22
|
+
|
|
23
|
+
# Optional CA-Path for TLS-handshake
|
|
24
|
+
attr_accessor :ssl_capath
|
|
25
|
+
|
|
26
|
+
# Optional callback for verification of SSL peer
|
|
27
|
+
attr_accessor :ssl_verifycb
|
|
28
|
+
|
|
29
|
+
##
|
|
30
|
+
# Create a new connection to the given host and port, using threaded mode
|
|
31
|
+
# or not.
|
|
32
|
+
def initialize(threaded = true)
|
|
33
|
+
super(threaded)
|
|
34
|
+
@host = nil
|
|
35
|
+
@port = nil
|
|
36
|
+
@allow_tls = true
|
|
37
|
+
@tls = false
|
|
38
|
+
@ssl_capath = nil
|
|
39
|
+
@ssl_verifycb = nil
|
|
40
|
+
@features_timeout = 10
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
##
|
|
44
|
+
# Connects to the Jabber server through a TCP Socket and
|
|
45
|
+
# starts the Jabber parser.
|
|
46
|
+
def connect(host, port)
|
|
47
|
+
@host = host
|
|
48
|
+
@port = port
|
|
49
|
+
# Reset is_tls?, so that it works when reconnecting
|
|
50
|
+
@tls = false
|
|
51
|
+
|
|
52
|
+
Jabber::debuglog("CONNECTING:\n#{@host}:#{@port}")
|
|
53
|
+
@socket = TCPSocket.new(@host, @port)
|
|
54
|
+
start
|
|
55
|
+
|
|
56
|
+
accept_features
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def accept_features
|
|
60
|
+
begin
|
|
61
|
+
Timeout::timeout(@features_timeout) {
|
|
62
|
+
Jabber::debuglog("FEATURES: waiting...")
|
|
63
|
+
@features_lock.lock
|
|
64
|
+
@features_lock.unlock
|
|
65
|
+
Jabber::debuglog("FEATURES: waiting finished")
|
|
66
|
+
}
|
|
67
|
+
rescue Timeout::Error
|
|
68
|
+
Jabber::debuglog("FEATURES: timed out when waiting, stream peer seems not XMPP compliant")
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
if @allow_tls and not is_tls? and @stream_features['starttls'] == 'urn:ietf:params:xml:ns:xmpp-tls'
|
|
72
|
+
begin
|
|
73
|
+
starttls
|
|
74
|
+
rescue
|
|
75
|
+
Jabber::debuglog("STARTTLS:\nFailure: #{$!}")
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
##
|
|
81
|
+
# Start the parser on the previously connected socket
|
|
82
|
+
def start
|
|
83
|
+
@features_lock.lock
|
|
84
|
+
|
|
85
|
+
super(@socket)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
##
|
|
89
|
+
# Do a <starttls/>
|
|
90
|
+
# (will be automatically done by connect if stream peer supports this)
|
|
91
|
+
def starttls
|
|
92
|
+
stls = REXML::Element.new('starttls')
|
|
93
|
+
stls.add_namespace('urn:ietf:params:xml:ns:xmpp-tls')
|
|
94
|
+
|
|
95
|
+
reply = nil
|
|
96
|
+
send(stls) { |r|
|
|
97
|
+
reply = r
|
|
98
|
+
true
|
|
99
|
+
}
|
|
100
|
+
if reply.name != 'proceed'
|
|
101
|
+
raise ErrorException(reply.first_element('error'))
|
|
102
|
+
end
|
|
103
|
+
# Don't be interrupted
|
|
104
|
+
stop
|
|
105
|
+
|
|
106
|
+
begin
|
|
107
|
+
error = nil
|
|
108
|
+
|
|
109
|
+
# Context/user set-able stuff
|
|
110
|
+
ctx = OpenSSL::SSL::SSLContext.new('TLSv1')
|
|
111
|
+
if @ssl_capath
|
|
112
|
+
ctx.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
|
113
|
+
ctx.ca_path = @ssl_capath
|
|
114
|
+
else
|
|
115
|
+
ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
|
116
|
+
end
|
|
117
|
+
ctx.verify_callback = @ssl_verifycb
|
|
118
|
+
|
|
119
|
+
# SSL connection establishing
|
|
120
|
+
sslsocket = OpenSSL::SSL::SSLSocket.new(@socket, ctx)
|
|
121
|
+
sslsocket.sync_close = true
|
|
122
|
+
Jabber::debuglog("TLSv1: OpenSSL handshake in progress")
|
|
123
|
+
sslsocket.connect
|
|
124
|
+
|
|
125
|
+
# Make REXML believe it's a real socket
|
|
126
|
+
class << sslsocket
|
|
127
|
+
def kind_of?(o)
|
|
128
|
+
o == IO ? true : super
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# We're done and will use it
|
|
133
|
+
@tls = true
|
|
134
|
+
@socket = sslsocket
|
|
135
|
+
rescue
|
|
136
|
+
error = $!
|
|
137
|
+
ensure
|
|
138
|
+
Jabber::debuglog("TLSv1: restarting parser")
|
|
139
|
+
start
|
|
140
|
+
accept_features
|
|
141
|
+
raise error if error
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
##
|
|
146
|
+
# Have we gone to TLS mode?
|
|
147
|
+
# result:: [true] or [false]
|
|
148
|
+
def is_tls?
|
|
149
|
+
@tls
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
def generate_stream_start(to=nil, from=nil, id=nil, xml_lang="en", xmlns="jabber:client", version="1.0")
|
|
153
|
+
stream_start_string = "<stream:stream xmlns:stream='http://etherx.jabber.org/streams' "
|
|
154
|
+
stream_start_string += "xmlns='#{xmlns}' " unless xmlns.nil?
|
|
155
|
+
stream_start_string += "to='#{to}' " unless to.nil?
|
|
156
|
+
stream_start_string += "from='#{from}' " unless from.nil?
|
|
157
|
+
stream_start_string += "id='#{id}' " unless id.nil?
|
|
158
|
+
stream_start_string += "xml:lang='#{xml_lang}' " unless xml_lang.nil?
|
|
159
|
+
stream_start_string += "version='#{version}' " unless version.nil?
|
|
160
|
+
stream_start_string += ">"
|
|
161
|
+
stream_start_string
|
|
162
|
+
end
|
|
163
|
+
private :generate_stream_start
|
|
164
|
+
|
|
165
|
+
end
|
|
166
|
+
end
|
|
@@ -0,0 +1,248 @@
|
|
|
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/x'
|
|
6
|
+
require 'xmpp4r/jid'
|
|
7
|
+
|
|
8
|
+
module Jabber
|
|
9
|
+
module Dataforms
|
|
10
|
+
##
|
|
11
|
+
# Data Forms (JEP-0004) implementation
|
|
12
|
+
class XData < X
|
|
13
|
+
def initialize(type=nil)
|
|
14
|
+
super()
|
|
15
|
+
add_namespace('jabber:x:data')
|
|
16
|
+
self.type = type
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def typed_add(xe)
|
|
20
|
+
if xe.kind_of?(REXML::Element)
|
|
21
|
+
case xe.name
|
|
22
|
+
when 'instructions' then super XDataInstructions.new.import(xe)
|
|
23
|
+
when 'title' then super XDataTitle.new.import(xe)
|
|
24
|
+
when 'field' then super XDataField.new.import(xe)
|
|
25
|
+
when 'reported' then super XDataReported.new.import(xe)
|
|
26
|
+
#when 'item' then super XDataItem.new.import(xe)
|
|
27
|
+
else super xe
|
|
28
|
+
end
|
|
29
|
+
else
|
|
30
|
+
super xe
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
##
|
|
35
|
+
# Search a field by it's var-name
|
|
36
|
+
# var:: [String]
|
|
37
|
+
# result:: [XDataField] or [nil]
|
|
38
|
+
def field(var)
|
|
39
|
+
each_element { |xe|
|
|
40
|
+
return xe if xe.kind_of?(XDataField) and xe.var == var
|
|
41
|
+
}
|
|
42
|
+
nil
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
##
|
|
46
|
+
# Type of this Data Form
|
|
47
|
+
# result:: * :cancel
|
|
48
|
+
# * :form
|
|
49
|
+
# * :result
|
|
50
|
+
# * :submit
|
|
51
|
+
# * nil
|
|
52
|
+
def type
|
|
53
|
+
case attributes['type']
|
|
54
|
+
when 'cancel' then :cancel
|
|
55
|
+
when 'form' then :form
|
|
56
|
+
when 'result' then :result
|
|
57
|
+
when 'submit' then :submit
|
|
58
|
+
else nil
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
##
|
|
63
|
+
# Set the type (see type)
|
|
64
|
+
def type=(t)
|
|
65
|
+
case t
|
|
66
|
+
when :cancel then attributes['type'] = 'cancel'
|
|
67
|
+
when :form then attributes['type'] = 'form'
|
|
68
|
+
when :result then attributes['type'] = 'result'
|
|
69
|
+
when :submit then attributes['type'] = 'submit'
|
|
70
|
+
else attributes['type'] = nil
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
X.add_namespaceclass('jabber:x:data', XData)
|
|
76
|
+
|
|
77
|
+
##
|
|
78
|
+
# Child of XData, contains the title of this Data Form
|
|
79
|
+
class XDataTitle < REXML::Element
|
|
80
|
+
def initialize
|
|
81
|
+
super('title')
|
|
82
|
+
end
|
|
83
|
+
def to_s
|
|
84
|
+
text.to_s
|
|
85
|
+
end
|
|
86
|
+
def title
|
|
87
|
+
text
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
##
|
|
92
|
+
# Child of XData, contains the instructions of this Data Form
|
|
93
|
+
class XDataInstructions < REXML::Element
|
|
94
|
+
def initialize
|
|
95
|
+
super('instructions')
|
|
96
|
+
end
|
|
97
|
+
def to_s
|
|
98
|
+
text.to_s
|
|
99
|
+
end
|
|
100
|
+
def instructions
|
|
101
|
+
text
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
##
|
|
106
|
+
# Child of XData, contains configurable/configured options of this Data Form
|
|
107
|
+
class XDataField < REXML::Element
|
|
108
|
+
def initialize(var=nil, type=nil)
|
|
109
|
+
super('field')
|
|
110
|
+
self.var = var
|
|
111
|
+
self.type = type
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def label
|
|
115
|
+
attributes['label']
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def label=(s)
|
|
119
|
+
attributes['label'] = s
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def var
|
|
123
|
+
attributes['var']
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def var=(s)
|
|
127
|
+
attributes['var'] = s
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
##
|
|
131
|
+
# Type of this field
|
|
132
|
+
# result::
|
|
133
|
+
# * :boolean
|
|
134
|
+
# * :fixed
|
|
135
|
+
# * :hidden
|
|
136
|
+
# * :jid_multi
|
|
137
|
+
# * :jid_single
|
|
138
|
+
# * :list_multi
|
|
139
|
+
# * :list_single
|
|
140
|
+
# * :text_multi
|
|
141
|
+
# * :text_private
|
|
142
|
+
# * :text_single
|
|
143
|
+
# * nil
|
|
144
|
+
def type
|
|
145
|
+
case attributes['type']
|
|
146
|
+
when 'boolean' then :boolean
|
|
147
|
+
when 'fixed' then :fixed
|
|
148
|
+
when 'hidden' then :hidden
|
|
149
|
+
when 'jid-multi' then :jid_multi
|
|
150
|
+
when 'jid-single' then :jid_single
|
|
151
|
+
when 'list-multi' then :list_multi
|
|
152
|
+
when 'list-single' then :list_single
|
|
153
|
+
when 'text-multi' then :text_multi
|
|
154
|
+
when 'text-private' then :text_private
|
|
155
|
+
when 'text-single' then :text_single
|
|
156
|
+
else nil
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
##
|
|
161
|
+
# Set the type of this field (see type)
|
|
162
|
+
def type=(t)
|
|
163
|
+
case t
|
|
164
|
+
when :boolean then attributes['type'] = 'boolean'
|
|
165
|
+
when :fixed then attributes['type'] = 'fixed'
|
|
166
|
+
when :hidden then attributes['type'] = 'hidden'
|
|
167
|
+
when :jid_multi then attributes['type'] = 'jid-multi'
|
|
168
|
+
when :jid_single then attributes['type'] = 'jid-single'
|
|
169
|
+
when :list_multi then attributes['type'] = 'list-multi'
|
|
170
|
+
when :list_single then attributes['type'] = 'list-single'
|
|
171
|
+
when :text_multi then attributes['type'] = 'text-multi'
|
|
172
|
+
when :text_private then attributes['type'] = 'text-private'
|
|
173
|
+
when :text_single then attributes['type'] = 'text-single'
|
|
174
|
+
else attributes['type'] = nil
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
##
|
|
179
|
+
# Is this field required (has the <required/> child)?
|
|
180
|
+
def required?
|
|
181
|
+
res = false
|
|
182
|
+
each_element('required') { res = true }
|
|
183
|
+
res
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
##
|
|
187
|
+
# Set if this field is required
|
|
188
|
+
# r:: [true] or [false]
|
|
189
|
+
def required=(r)
|
|
190
|
+
delete_elements('required')
|
|
191
|
+
if r
|
|
192
|
+
add REXML::Element.new('required')
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
##
|
|
197
|
+
# Get the values (in a Data Form with type='submit')
|
|
198
|
+
def values
|
|
199
|
+
res = []
|
|
200
|
+
each_element('value') { |e|
|
|
201
|
+
res << e.text
|
|
202
|
+
}
|
|
203
|
+
res
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
##
|
|
207
|
+
# Set the values
|
|
208
|
+
def values=(ary)
|
|
209
|
+
delete_elements('value')
|
|
210
|
+
ary.each { |v|
|
|
211
|
+
add(REXML::Element.new('value')).text = v
|
|
212
|
+
}
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
##
|
|
216
|
+
# Get the options (in a Data Form with type='form')
|
|
217
|
+
def options
|
|
218
|
+
res = {}
|
|
219
|
+
each_element('option') { |e|
|
|
220
|
+
value = nil
|
|
221
|
+
e.each_element('value') { |ve| value = ve.text }
|
|
222
|
+
res[value] = e.attributes['label']
|
|
223
|
+
}
|
|
224
|
+
res
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
##
|
|
228
|
+
# Set the options
|
|
229
|
+
def options=(hsh)
|
|
230
|
+
delete_elements('option')
|
|
231
|
+
hsh.each { |value,label|
|
|
232
|
+
o = add(REXML::Element.new('option'))
|
|
233
|
+
o.attributes['label'] = label
|
|
234
|
+
o.add(REXML::Element.new('value')).text = value
|
|
235
|
+
}
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
##
|
|
240
|
+
# The <reported/> element, can contain XDataField elements
|
|
241
|
+
class XDataReported < REXML::Element
|
|
242
|
+
def initialize
|
|
243
|
+
super('reported')
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require 'xmpp4r/dataforms/x/data.rb'
|
|
@@ -0,0 +1,34 @@
|
|
|
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
|
+
# Is debugging mode enabled ?
|
|
7
|
+
@@debug = false
|
|
8
|
+
|
|
9
|
+
# Enable/disable debugging mode. When debug mode is enabled, information
|
|
10
|
+
# can be logged using Jabber::debuglog. When debug mode is disabled, calls
|
|
11
|
+
# to Jabber::debuglog are just ignored.
|
|
12
|
+
def Jabber::debug=(debug)
|
|
13
|
+
@@debug = debug
|
|
14
|
+
if @@debug
|
|
15
|
+
debuglog('Debugging mode enabled.')
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# returns true if debugging mode is enabled. If you just want to log
|
|
20
|
+
# something if debugging is enabled, use Jabber::debuglog instead.
|
|
21
|
+
def Jabber::debug
|
|
22
|
+
@@debug
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Outputs a string only if debugging mode is enabled. If the string includes
|
|
26
|
+
# several lines, 4 spaces are added at the begginning of each line but the
|
|
27
|
+
# first one. Time is prepended to the string.
|
|
28
|
+
def Jabber::debuglog(string)
|
|
29
|
+
return if not @@debug
|
|
30
|
+
s = string.chomp.gsub("\n", "\n ")
|
|
31
|
+
t = Time::new.strftime('%H:%M:%S')
|
|
32
|
+
puts "#{t} #{s}"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
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/x'
|
|
6
|
+
require 'xmpp4r/jid'
|
|
7
|
+
require 'time'
|
|
8
|
+
|
|
9
|
+
module Jabber
|
|
10
|
+
module Delay
|
|
11
|
+
##
|
|
12
|
+
# Implementation of JEP 0091
|
|
13
|
+
# for <x xmlns='jabber:x:delay' stamp='...' .../>
|
|
14
|
+
# applied on <message/> and <presence/> stanzas
|
|
15
|
+
#
|
|
16
|
+
# One may also use XDelay#text for a descriptive reason
|
|
17
|
+
# for the delay.
|
|
18
|
+
#
|
|
19
|
+
# Please note that you must require 'xmpp4r/xdelay' to use
|
|
20
|
+
# this class as it's not required by a basic XMPP implementation.
|
|
21
|
+
# <x/> elements with the specific namespace will then be
|
|
22
|
+
# converted to XDelay automatically.
|
|
23
|
+
class XDelay < X
|
|
24
|
+
##
|
|
25
|
+
# Initialize a new XDelay element
|
|
26
|
+
#
|
|
27
|
+
# insertnow:: [Boolean] Set the stamp to [Time::now]
|
|
28
|
+
def initialize(insertnow=true)
|
|
29
|
+
super()
|
|
30
|
+
add_namespace('jabber:x:delay')
|
|
31
|
+
|
|
32
|
+
if insertnow
|
|
33
|
+
set_stamp(Time.now)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
##
|
|
38
|
+
# Get the timestamp
|
|
39
|
+
# result:: [Time] or nil
|
|
40
|
+
def stamp
|
|
41
|
+
if attributes['stamp']
|
|
42
|
+
begin
|
|
43
|
+
# Actually this should be Time.xmlschema,
|
|
44
|
+
# but "unfortunately, the 'jabber:x:delay' namespace predates" JEP 0082
|
|
45
|
+
Time.parse(attributes['stamp'])
|
|
46
|
+
rescue ArgumentError
|
|
47
|
+
nil
|
|
48
|
+
end
|
|
49
|
+
else
|
|
50
|
+
nil
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
##
|
|
55
|
+
# Set the timestamp
|
|
56
|
+
# t:: [Time] or nil
|
|
57
|
+
def stamp=(t)
|
|
58
|
+
if t.nil?
|
|
59
|
+
attributes['stamp'] = nil
|
|
60
|
+
else
|
|
61
|
+
attributes['stamp'] = t.strftime("%Y%m%dT%H:%M:%S")
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
##
|
|
66
|
+
# Set the timestamp (chaining-friendly)
|
|
67
|
+
def set_stamp(t)
|
|
68
|
+
self.stamp = t
|
|
69
|
+
self
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
##
|
|
73
|
+
# Get the timestamp's origin
|
|
74
|
+
# result:: [JID]
|
|
75
|
+
def from
|
|
76
|
+
if attributes['from']
|
|
77
|
+
JID::new(attributes['from'])
|
|
78
|
+
else
|
|
79
|
+
nil
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
##
|
|
84
|
+
# Set the timestamp's origin
|
|
85
|
+
# jid:: [JID]
|
|
86
|
+
def from=(jid)
|
|
87
|
+
attributes['from'] = jid.nil? ? nil : jid.to_s
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
##
|
|
91
|
+
# Set the timestamp's origin (chaining-friendly)
|
|
92
|
+
def set_from(jid)
|
|
93
|
+
self.from = jid
|
|
94
|
+
self
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
X.add_namespaceclass('jabber:x:delay', XDelay)
|
|
99
|
+
end
|
|
100
|
+
end
|
data/lib/xmpp4r/delay.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require 'xmpp4r/delay/x/delay.rb'
|