xmpp4r 0.3

Sign up to get free protection for your applications and to get access to all the features.
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'