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.
Files changed (142) hide show
  1. data/COPYING +340 -0
  2. data/ChangeLog +28 -0
  3. data/LICENSE +59 -0
  4. data/README +20 -0
  5. data/Rakefile +103 -0
  6. data/UPDATING +40 -0
  7. data/data/doc/xmpp4r/examples/advanced/adventure/README +57 -0
  8. data/data/doc/xmpp4r/examples/advanced/adventure/adventure.rb +23 -0
  9. data/data/doc/xmpp4r/examples/advanced/adventure/adventuremuc.rb +136 -0
  10. data/data/doc/xmpp4r/examples/advanced/adventure/cube.xml +15 -0
  11. data/data/doc/xmpp4r/examples/advanced/adventure/tower.xml +69 -0
  12. data/data/doc/xmpp4r/examples/advanced/adventure/world.rb +425 -0
  13. data/data/doc/xmpp4r/examples/advanced/fileserve.conf +11 -0
  14. data/data/doc/xmpp4r/examples/advanced/fileserve.rb +344 -0
  15. data/data/doc/xmpp4r/examples/advanced/getonline.rb +56 -0
  16. data/data/doc/xmpp4r/examples/advanced/gtkmucclient.rb +315 -0
  17. data/data/doc/xmpp4r/examples/advanced/migrate.rb +89 -0
  18. data/data/doc/xmpp4r/examples/advanced/minimuc.rb +266 -0
  19. data/data/doc/xmpp4r/examples/advanced/recvfile.rb +83 -0
  20. data/data/doc/xmpp4r/examples/advanced/rosterdiscovery.rb +130 -0
  21. data/data/doc/xmpp4r/examples/advanced/sendfile.conf +10 -0
  22. data/data/doc/xmpp4r/examples/advanced/sendfile.rb +72 -0
  23. data/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr.rb +51 -0
  24. data/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr_jabber.rb +43 -0
  25. data/data/doc/xmpp4r/examples/advanced/shellmgr/shellmgr_test.rb +10 -0
  26. data/data/doc/xmpp4r/examples/advanced/versionpoll.rb +90 -0
  27. data/data/doc/xmpp4r/examples/advanced/xmpping.rb +134 -0
  28. data/data/doc/xmpp4r/examples/advanced/xmppingrc.sample +9 -0
  29. data/data/doc/xmpp4r/examples/basic/change_password.rb +41 -0
  30. data/data/doc/xmpp4r/examples/basic/client.rb +68 -0
  31. data/data/doc/xmpp4r/examples/basic/component.rb +11 -0
  32. data/data/doc/xmpp4r/examples/basic/echo_nonthreaded.rb +32 -0
  33. data/data/doc/xmpp4r/examples/basic/echo_threaded.rb +32 -0
  34. data/data/doc/xmpp4r/examples/basic/jabbersend.rb +41 -0
  35. data/data/doc/xmpp4r/examples/basic/mass_sender.rb +67 -0
  36. data/data/doc/xmpp4r/examples/basic/mucinfo.rb +39 -0
  37. data/data/doc/xmpp4r/examples/basic/mucsimplebot.rb +83 -0
  38. data/data/doc/xmpp4r/examples/basic/register.rb +25 -0
  39. data/data/doc/xmpp4r/examples/basic/remove_registration.rb +18 -0
  40. data/data/doc/xmpp4r/examples/basic/roster.rb +42 -0
  41. data/data/doc/xmpp4r/examples/basic/rosterprint.rb +50 -0
  42. data/data/doc/xmpp4r/examples/basic/rosterrename.rb +34 -0
  43. data/data/doc/xmpp4r/examples/basic/rosterwatch.rb +172 -0
  44. data/data/doc/xmpp4r/examples/basic/send_vcard.rb +68 -0
  45. data/data/doc/xmpp4r/examples/basic/versionbot.rb +75 -0
  46. data/data/doc/xmpp4r/examples/buggy/jabber2jabber/jabber2jabber.rb +18 -0
  47. data/data/doc/xmpp4r/examples/buggy/miniedgarr_cgi.rb +192 -0
  48. data/data/doc/xmpp4r/examples/buggy/miniedgarr_watch.rb +82 -0
  49. data/lib/callbacks.rb +122 -0
  50. data/lib/xmpp4r/authenticationfailure.rb +13 -0
  51. data/lib/xmpp4r/bytestreams/helper/filetransfer.rb +315 -0
  52. data/lib/xmpp4r/bytestreams/helper/ibb/base.rb +256 -0
  53. data/lib/xmpp4r/bytestreams/helper/ibb/initiator.rb +30 -0
  54. data/lib/xmpp4r/bytestreams/helper/ibb/target.rb +46 -0
  55. data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/base.rb +151 -0
  56. data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/initiator.rb +85 -0
  57. data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/server.rb +178 -0
  58. data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/socks5.rb +56 -0
  59. data/lib/xmpp4r/bytestreams/helper/socks5bytestreams/target.rb +61 -0
  60. data/lib/xmpp4r/bytestreams/iq/bytestreams.rb +177 -0
  61. data/lib/xmpp4r/bytestreams/iq/si.rb +221 -0
  62. data/lib/xmpp4r/bytestreams.rb +11 -0
  63. data/lib/xmpp4r/client.rb +249 -0
  64. data/lib/xmpp4r/component.rb +103 -0
  65. data/lib/xmpp4r/connection.rb +166 -0
  66. data/lib/xmpp4r/dataforms/x/data.rb +248 -0
  67. data/lib/xmpp4r/dataforms.rb +1 -0
  68. data/lib/xmpp4r/debuglog.rb +34 -0
  69. data/lib/xmpp4r/delay/x/delay.rb +100 -0
  70. data/lib/xmpp4r/delay.rb +1 -0
  71. data/lib/xmpp4r/discovery/iq/discoinfo.rb +225 -0
  72. data/lib/xmpp4r/discovery/iq/discoitems.rb +162 -0
  73. data/lib/xmpp4r/discovery.rb +2 -0
  74. data/lib/xmpp4r/error.rb +230 -0
  75. data/lib/xmpp4r/errorexception.rb +32 -0
  76. data/lib/xmpp4r/feature_negotiation/iq/feature.rb +42 -0
  77. data/lib/xmpp4r/feature_negotiation.rb +1 -0
  78. data/lib/xmpp4r/idgenerator.rb +37 -0
  79. data/lib/xmpp4r/iq.rb +229 -0
  80. data/lib/xmpp4r/jid.rb +167 -0
  81. data/lib/xmpp4r/message.rb +171 -0
  82. data/lib/xmpp4r/muc/helper/mucbrowser.rb +107 -0
  83. data/lib/xmpp4r/muc/helper/mucclient.rb +382 -0
  84. data/lib/xmpp4r/muc/helper/simplemucclient.rb +222 -0
  85. data/lib/xmpp4r/muc/x/muc.rb +98 -0
  86. data/lib/xmpp4r/muc/x/mucuserinvite.rb +58 -0
  87. data/lib/xmpp4r/muc/x/mucuseritem.rb +148 -0
  88. data/lib/xmpp4r/muc.rb +6 -0
  89. data/lib/xmpp4r/presence.rb +255 -0
  90. data/lib/xmpp4r/query.rb +43 -0
  91. data/lib/xmpp4r/rexmladdons.rb +826 -0
  92. data/lib/xmpp4r/roster/helper/roster.rb +514 -0
  93. data/lib/xmpp4r/roster/iq/roster.rb +244 -0
  94. data/lib/xmpp4r/roster/x/roster.rb +155 -0
  95. data/lib/xmpp4r/roster.rb +4 -0
  96. data/lib/xmpp4r/sasl.rb +167 -0
  97. data/lib/xmpp4r/stream.rb +543 -0
  98. data/lib/xmpp4r/streamparser.rb +77 -0
  99. data/lib/xmpp4r/vcard/helper/vcard.rb +86 -0
  100. data/lib/xmpp4r/vcard/iq/vcard.rb +102 -0
  101. data/lib/xmpp4r/vcard.rb +3 -0
  102. data/lib/xmpp4r/version/helper/responder.rb +71 -0
  103. data/lib/xmpp4r/version/helper/simpleresponder.rb +44 -0
  104. data/lib/xmpp4r/version/iq/version.rb +118 -0
  105. data/lib/xmpp4r/version.rb +3 -0
  106. data/lib/xmpp4r/x.rb +43 -0
  107. data/lib/xmpp4r/xmlstanza.rb +174 -0
  108. data/lib/xmpp4r/xmpp4r.rb +16 -0
  109. data/lib/xmpp4r.rb +122 -0
  110. data/setup.rb +1360 -0
  111. data/test/bytestreams/tc_ibb.rb +186 -0
  112. data/test/bytestreams/tc_socks5bytestreams.rb +57 -0
  113. data/test/delay/tc_xdelay.rb +51 -0
  114. data/test/lib/clienttester.rb +110 -0
  115. data/test/muc/tc_muc_mucclient.rb +569 -0
  116. data/test/muc/tc_muc_simplemucclient.rb +72 -0
  117. data/test/roster/.tc_helper.rb.swp +0 -0
  118. data/test/roster/tc_helper.rb +389 -0
  119. data/test/roster/tc_iqqueryroster.rb +140 -0
  120. data/test/roster/tc_xroster.rb +70 -0
  121. data/test/tc_callbacks.rb +128 -0
  122. data/test/tc_class_names.rb +129 -0
  123. data/test/tc_client.rb +30 -0
  124. data/test/tc_error.rb +103 -0
  125. data/test/tc_idgenerator.rb +30 -0
  126. data/test/tc_iq.rb +109 -0
  127. data/test/tc_iqquery.rb +31 -0
  128. data/test/tc_jid.rb +202 -0
  129. data/test/tc_message.rb +114 -0
  130. data/test/tc_presence.rb +148 -0
  131. data/test/tc_stream.rb +182 -0
  132. data/test/tc_streamError.rb +87 -0
  133. data/test/tc_streamSend.rb +59 -0
  134. data/test/tc_streamThreaded.rb +168 -0
  135. data/test/tc_xmlstanza.rb +76 -0
  136. data/test/ts_xmpp4r.rb +34 -0
  137. data/test/vcard/tc_iqvcard.rb +52 -0
  138. data/test/version/tc_helper.rb +46 -0
  139. data/test/version/tc_iqqueryversion.rb +96 -0
  140. data/tools/doctoweb.bash +30 -0
  141. data/tools/gen_requires.bash +10 -0
  142. 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
@@ -0,0 +1 @@
1
+ require 'xmpp4r/delay/x/delay.rb'