julien51-babylon 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +30 -3
- data/lib/babylon.rb +1 -0
- data/lib/babylon/base/controller.rb +9 -4
- data/lib/babylon/client_connection.rb +22 -20
- data/lib/babylon/xmpp_connection.rb +0 -108
- data/lib/babylon/xmpp_parser.rb +104 -0
- metadata +3 -2
data/Rakefile
CHANGED
@@ -11,7 +11,7 @@ begin
|
|
11
11
|
gem.authors = ["julien Genestoux"]
|
12
12
|
gem.requirements = ["eventmachine", "yaml", "fileutils", "log4r", "nokogiri"]
|
13
13
|
gem.executables = "babylon"
|
14
|
-
gem.files = ["bin/babylon", "lib/babylon.rb", "lib/babylon/base/controller.rb", "lib/babylon/base/view.rb", "lib/babylon/client_connection.rb", "lib/babylon/component_connection.rb", "lib/babylon/router/dsl.rb", "lib/babylon/router.rb", "lib/babylon/runner.rb", "lib/babylon/xmpp_connection.rb", "lib/babylon/xpath_helper.rb", "LICENSE", "Rakefile", "README.rdoc", "templates/babylon/app/controllers/README.rdoc", "templates/babylon/app/models/README.rdoc", "templates/babylon/app/views/README.rdoc", "templates/babylon/config/boot.rb", "templates/babylon/config/config.yaml", "templates/babylon/config/dependencies.rb", "templates/babylon/config/routes.rb", "templates/babylon/config/initializers/README.rdoc"]
|
14
|
+
gem.files = ["bin/babylon", "lib/babylon.rb", "lib/babylon/base/controller.rb", "lib/babylon/base/view.rb", "lib/babylon/client_connection.rb", "lib/babylon/component_connection.rb", "lib/babylon/router/dsl.rb", "lib/babylon/router.rb", "lib/babylon/runner.rb", "lib/babylon/xmpp_connection.rb", "lib/babylon/xmpp_parser.rb", "lib/babylon/xpath_helper.rb", "LICENSE", "Rakefile", "README.rdoc", "templates/babylon/app/controllers/README.rdoc", "templates/babylon/app/models/README.rdoc", "templates/babylon/app/views/README.rdoc", "templates/babylon/config/boot.rb", "templates/babylon/config/config.yaml", "templates/babylon/config/dependencies.rb", "templates/babylon/config/routes.rb", "templates/babylon/config/initializers/README.rdoc"]
|
15
15
|
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
16
16
|
end
|
17
17
|
rescue LoadError
|
@@ -34,11 +34,37 @@ Rake::TestTask.new(:test) do |test|
|
|
34
34
|
test.verbose = false
|
35
35
|
end
|
36
36
|
|
37
|
+
# begin
|
38
|
+
# require 'rcov/rcovtask'
|
39
|
+
# Rcov::RcovTask.new do |test|
|
40
|
+
# test.libs << 'test'
|
41
|
+
# test.pattern = 'test/**/*_test.rb'
|
42
|
+
# test.verbose = true
|
43
|
+
# end
|
44
|
+
# rescue LoadError
|
45
|
+
# task :rcov do
|
46
|
+
# abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
47
|
+
# end
|
48
|
+
# end
|
49
|
+
|
50
|
+
begin
|
51
|
+
require 'spec/rake/spectask'
|
52
|
+
desc "Run all Spec"
|
53
|
+
Spec::Rake::SpecTask.new('spec') do |spec|
|
54
|
+
spec.spec_files = FileList['spec/**/*.rb']
|
55
|
+
spec.verbose = true
|
56
|
+
end
|
57
|
+
rescue LoadError
|
58
|
+
task :rcov do
|
59
|
+
abort "Rspec is not available. In order to run rspec, you must: sudo gem install rspec"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
37
63
|
begin
|
38
64
|
require 'rcov/rcovtask'
|
39
65
|
Rcov::RcovTask.new do |test|
|
40
|
-
test.libs << '
|
41
|
-
test.pattern = '
|
66
|
+
test.libs << 'spec'
|
67
|
+
test.pattern = 'spec/**/*_spec.rb'
|
42
68
|
test.verbose = true
|
43
69
|
end
|
44
70
|
rescue LoadError
|
@@ -47,6 +73,7 @@ rescue LoadError
|
|
47
73
|
end
|
48
74
|
end
|
49
75
|
|
76
|
+
|
50
77
|
task :install => :build
|
51
78
|
|
52
79
|
task :default => :test
|
data/lib/babylon.rb
CHANGED
@@ -35,11 +35,16 @@ module Babylon
|
|
35
35
|
return if @rendered # Avoid double rendering
|
36
36
|
|
37
37
|
if options.nil? # default rendering
|
38
|
-
|
38
|
+
render(:file => default_template_name)
|
39
39
|
elsif options[:file]
|
40
|
-
|
40
|
+
file = options[:file]
|
41
|
+
if file.include?('/')
|
42
|
+
render_for_file("app/views/#{file}.xml.builder")
|
43
|
+
else
|
44
|
+
render_for_file(view_path(file))
|
45
|
+
end
|
41
46
|
elsif action_name = options[:action]
|
42
|
-
|
47
|
+
render(:file => default_template_name(action_name.to_s))
|
43
48
|
end
|
44
49
|
|
45
50
|
# And finally, we set up rendered to be true
|
@@ -73,4 +78,4 @@ module Babylon
|
|
73
78
|
end
|
74
79
|
end
|
75
80
|
end
|
76
|
-
end
|
81
|
+
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
module Babylon
|
2
|
-
|
2
|
+
|
3
3
|
##
|
4
4
|
# ClientConnection is in charge of the XMPP connection for a Regular XMPP Client.
|
5
5
|
# So far, SASL Plain authenticationonly is supported
|
@@ -8,7 +8,7 @@ module Babylon
|
|
8
8
|
require 'digest/sha1'
|
9
9
|
require 'base64'
|
10
10
|
require 'resolv'
|
11
|
-
|
11
|
+
|
12
12
|
|
13
13
|
attr_reader :binding_iq_id, :session_iq_id
|
14
14
|
|
@@ -18,13 +18,13 @@ module Babylon
|
|
18
18
|
super(params)
|
19
19
|
@state = :wait_for_stream
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
##
|
23
23
|
# Connects the ClientConnection based on SRV records for the jid's domain, if no host or port has been specified.
|
24
24
|
# In any case, we give priority to the specified host and port.
|
25
25
|
def self.connect(params, &block)
|
26
26
|
return super(params, &block) if params["host"] && params["port"]
|
27
|
-
|
27
|
+
|
28
28
|
begin
|
29
29
|
begin
|
30
30
|
srv = []
|
@@ -79,18 +79,18 @@ module Babylon
|
|
79
79
|
case @state
|
80
80
|
when :connected
|
81
81
|
super # Can be dispatched
|
82
|
-
|
82
|
+
|
83
83
|
when :wait_for_stream
|
84
84
|
if stanza.name == "stream:stream" && stanza.attributes['id']
|
85
85
|
@state = :wait_for_auth_mechanisms unless @success
|
86
86
|
@state = :wait_for_bind if @success
|
87
87
|
end
|
88
|
-
|
88
|
+
|
89
89
|
when :wait_for_auth_mechanisms
|
90
90
|
if stanza.name == "stream:features"
|
91
91
|
if stanza.at("starttls") # we shall start tls
|
92
92
|
starttls = Nokogiri::XML::Node.new("starttls", @outstream)
|
93
|
-
starttls["xmlns"] =
|
93
|
+
starttls["xmlns"] = "urn:ietf:params:xml:ns:xmpp-tls"
|
94
94
|
send(starttls)
|
95
95
|
@state = :wait_for_proceed
|
96
96
|
elsif stanza.at("mechanisms") # tls is ok
|
@@ -98,14 +98,14 @@ module Babylon
|
|
98
98
|
# auth_text = "#{jid.strip}\x00#{jid.node}\x00#{password}"
|
99
99
|
auth = Nokogiri::XML::Node.new("auth", @outstream)
|
100
100
|
auth['mechanism'] = "PLAIN"
|
101
|
-
auth['xmlns'] =
|
101
|
+
auth['xmlns'] = "urn:ietf:params:xml:ns:xmpp-sasl"
|
102
102
|
auth.content = Base64::encode64([jid, jid.split("@").first, @password].join("\000")).gsub(/\s/, '')
|
103
103
|
send(auth)
|
104
104
|
@state = :wait_for_success
|
105
105
|
end
|
106
106
|
end
|
107
107
|
end
|
108
|
-
|
108
|
+
|
109
109
|
when :wait_for_success
|
110
110
|
if stanza.name == "success" # Yay! Success
|
111
111
|
@success = true
|
@@ -120,7 +120,7 @@ module Babylon
|
|
120
120
|
else
|
121
121
|
# Hum Failure...
|
122
122
|
end
|
123
|
-
|
123
|
+
|
124
124
|
when :wait_for_bind
|
125
125
|
if stanza.name == "stream:features"
|
126
126
|
if stanza.at("bind")
|
@@ -142,7 +142,7 @@ module Babylon
|
|
142
142
|
@state = :wait_for_confirmed_binding
|
143
143
|
end
|
144
144
|
end
|
145
|
-
|
145
|
+
|
146
146
|
when :wait_for_confirmed_binding
|
147
147
|
if stanza.name == "iq" && stanza["type"] == "result" && Integer(stanza["id"]) == @binding_iq_id
|
148
148
|
if stanza.at("jid")
|
@@ -159,7 +159,7 @@ module Babylon
|
|
159
159
|
iq = @outstream.add_child(builder.doc.root)
|
160
160
|
send(iq)
|
161
161
|
@state = :wait_for_confirmed_session
|
162
|
-
|
162
|
+
|
163
163
|
when :wait_for_confirmed_session
|
164
164
|
if stanza.name == "iq" && stanza["type"] == "result" && Integer(stanza["id"]) == @session_iq_id && stanza.at("session")
|
165
165
|
# And now, send a presence!
|
@@ -168,21 +168,23 @@ module Babylon
|
|
168
168
|
@connection_callback.call(self) if @connection_callback
|
169
169
|
@state = :connected
|
170
170
|
end
|
171
|
-
|
171
|
+
|
172
172
|
when :wait_for_proceed
|
173
173
|
start_tls() # starting TLS
|
174
174
|
@state = :wait_for_stream
|
175
175
|
@parser.reset
|
176
176
|
send @outstream.root.to_xml.split('<paste_content_here/>').first
|
177
177
|
end
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
##
|
182
|
-
# Namespace of the client
|
183
|
-
def stream_namespace
|
184
|
-
"jabber:client"
|
178
|
+
rescue
|
179
|
+
Babylon.logger.error("#{$!}:\n#{$!.backtrace.join("\n")}")
|
185
180
|
end
|
181
|
+
end
|
186
182
|
|
183
|
+
##
|
184
|
+
# Namespace of the client
|
185
|
+
def stream_namespace
|
186
|
+
"jabber:client"
|
187
187
|
end
|
188
|
+
|
189
|
+
end
|
188
190
|
end
|
@@ -8,7 +8,6 @@ module Babylon
|
|
8
8
|
# xml-not-well-formed Exception
|
9
9
|
class XmlNotWellFormed < Exception; end
|
10
10
|
|
11
|
-
|
12
11
|
##
|
13
12
|
# This class is in charge of handling the network connection to the XMPP server.
|
14
13
|
class XmppConnection < EventMachine::Connection
|
@@ -113,111 +112,4 @@ module Babylon
|
|
113
112
|
end
|
114
113
|
end
|
115
114
|
|
116
|
-
##
|
117
|
-
# This is the XML SAX Parser that accepts "pushed" content
|
118
|
-
class XmppParser < Nokogiri::XML::SAX::Document
|
119
|
-
|
120
|
-
attr_accessor :elem, :doc
|
121
|
-
|
122
|
-
##
|
123
|
-
# Initialize the parser and adds the callback that will be called upon stanza completion
|
124
|
-
def initialize(&callback)
|
125
|
-
@callback = callback
|
126
|
-
super()
|
127
|
-
reset
|
128
|
-
end
|
129
|
-
|
130
|
-
##
|
131
|
-
# Resets the Pushed SAX Parser.
|
132
|
-
def reset
|
133
|
-
@parser = Nokogiri::XML::SAX::PushParser.new(self)
|
134
|
-
@doc = Nokogiri::XML::Document.new
|
135
|
-
@elem = nil
|
136
|
-
end
|
137
|
-
|
138
|
-
##
|
139
|
-
# Pushes the received data to the parser. The parser will then callback the document's methods (start_tag, end_tag... etc)
|
140
|
-
def push(data)
|
141
|
-
@parser << data
|
142
|
-
end
|
143
|
-
|
144
|
-
##
|
145
|
-
# Called when the document contains a CData block
|
146
|
-
def cdata_block(string)
|
147
|
-
cdata = Nokogiri::XML::CDATA.new(@doc, string)
|
148
|
-
@elem.add_child(cdata)
|
149
|
-
end
|
150
|
-
|
151
|
-
##
|
152
|
-
# Called when the document received in the stream is started
|
153
|
-
def start_document
|
154
|
-
@doc = Nokogiri::XML::Document.new
|
155
|
-
end
|
156
|
-
|
157
|
-
##
|
158
|
-
# Adds characters to the current element (being parsed)
|
159
|
-
def characters(string)
|
160
|
-
@last_text_elem ||= @elem
|
161
|
-
@last_text = @last_text ? @last_text + string : string
|
162
|
-
end
|
163
|
-
|
164
|
-
##
|
165
|
-
# Instantiate a new current Element, adds the corresponding attributes and namespaces
|
166
|
-
# The new element is eventually added to a parent element (if present).
|
167
|
-
# If this element is the first element (the root of the document), then instead of adding it to a parent, we add it to the document itself. In this case, the current element will not be terminated, so we activate the callback immediately.
|
168
|
-
def start_element(qname, attributes = [])
|
169
|
-
e = Nokogiri::XML::Element.new(qname, @doc)
|
170
|
-
add_namespaces_and_attributes_to_node(attributes, e)
|
171
|
-
|
172
|
-
# Adding the newly created element to the @elem that is being parsed, or, if no element is being parsed, then we set the @root and the @elem to be this newly created element.
|
173
|
-
@elem = @elem ? @elem.add_child(e) : (@root = e)
|
174
|
-
|
175
|
-
if @elem.name == "stream:stream"
|
176
|
-
# Should be called only for stream:stream.
|
177
|
-
# We re-initialize the document and set its root to be the doc.
|
178
|
-
# Also, we activate the callback since this element will never end.
|
179
|
-
@doc = Nokogiri::XML::Document.new
|
180
|
-
@doc.root = @root = @elem
|
181
|
-
@callback.call(@elem)
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
##
|
186
|
-
# Terminates the current element and calls the callback
|
187
|
-
def end_element(name)
|
188
|
-
if @last_text_elem
|
189
|
-
@elem.add_child(Nokogiri::XML::Text.new(@last_text, @doc))
|
190
|
-
@last_text_elem = nil
|
191
|
-
@last_text = nil
|
192
|
-
end
|
193
|
-
if @elem
|
194
|
-
if @elem.parent == @root
|
195
|
-
@callback.call(@elem)
|
196
|
-
# And we also need to remove @elem from its tree
|
197
|
-
@elem.unlink
|
198
|
-
# And the current elem is the next sibling or the root
|
199
|
-
@elem = @root
|
200
|
-
else
|
201
|
-
@elem = @elem.parent
|
202
|
-
end
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
private
|
207
|
-
|
208
|
-
##
|
209
|
-
# Adds namespaces and attributes. Nokogiri passes them as a array of [name, value, name, value]...
|
210
|
-
def add_namespaces_and_attributes_to_node(attrs, node)
|
211
|
-
(attrs.size / 2).times do |i|
|
212
|
-
name, value = attrs[2 * i], attrs[2 * i + 1]
|
213
|
-
if name =~ /xmlns/
|
214
|
-
node.add_namespace(name, value)
|
215
|
-
else
|
216
|
-
node.set_attribute name, value
|
217
|
-
end
|
218
|
-
end
|
219
|
-
end
|
220
|
-
|
221
|
-
end
|
222
|
-
|
223
115
|
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module Babylon
|
2
|
+
|
3
|
+
##
|
4
|
+
# This is the XML SAX Parser that accepts "pushed" content
|
5
|
+
class XmppParser < Nokogiri::XML::SAX::Document
|
6
|
+
|
7
|
+
attr_accessor :elem, :doc, :parser, :top
|
8
|
+
|
9
|
+
##
|
10
|
+
# Initialize the parser and adds the callback that will be called upon stanza completion
|
11
|
+
def initialize(&callback)
|
12
|
+
@callback = callback
|
13
|
+
super()
|
14
|
+
reset
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# Resets the Pushed SAX Parser.
|
19
|
+
def reset
|
20
|
+
@parser = Nokogiri::XML::SAX::PushParser.new(self)
|
21
|
+
start_document
|
22
|
+
@elem = nil
|
23
|
+
end
|
24
|
+
|
25
|
+
##
|
26
|
+
# Pushes the received data to the parser. The parser will then callback the document's methods (start_tag, end_tag... etc)
|
27
|
+
def push(data)
|
28
|
+
@parser << data
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# Called when the document contains a CData block
|
33
|
+
def cdata_block(string)
|
34
|
+
@elem.add_child(Nokogiri::XML::CDATA.new(@doc, string))
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# Called when the document received in the stream is started
|
39
|
+
def start_document
|
40
|
+
@doc = Nokogiri::XML::Document.new
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Adds characters to the current element (being parsed)
|
45
|
+
def characters(string)
|
46
|
+
@elem.add_child(Nokogiri::XML::Text.new(string, @doc)) if @elem
|
47
|
+
end
|
48
|
+
|
49
|
+
##
|
50
|
+
# Instantiate a new current Element, adds the corresponding attributes and namespaces
|
51
|
+
# The new element is eventually added to a parent element (if present).
|
52
|
+
# If this element is the first element (the root of the document), then instead of adding it to a parent, we add it to the document itself. In this case, the current element will not be terminated, so we activate the callback immediately.
|
53
|
+
def start_element(qname, attributes = [])
|
54
|
+
e = Nokogiri::XML::Element.new(qname, @doc)
|
55
|
+
add_namespaces_and_attributes_to_node(attributes, e)
|
56
|
+
|
57
|
+
if e.name == "stream:stream"
|
58
|
+
# Should be called only for stream:stream.
|
59
|
+
# We re-initialize the document and set its root to be the newly created element.
|
60
|
+
start_document
|
61
|
+
@doc.root = e
|
62
|
+
# Also, we activate the callback since this element will never end.
|
63
|
+
@callback.call(e)
|
64
|
+
else
|
65
|
+
# Adding the newly created element to the @elem that is being parsed, or, if no element is being parsed, then we set the @top and the @elem to be this newly created element.
|
66
|
+
# Room is the "highest" element to (it's parent is the <stream> element)
|
67
|
+
@elem = @elem ? @elem.add_child(e) : (@top = e)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
##
|
72
|
+
# Terminates the current element and calls the callback
|
73
|
+
def end_element(name)
|
74
|
+
if @elem
|
75
|
+
if @elem == @top
|
76
|
+
@callback.call(@elem)
|
77
|
+
# And the current elem is the next sibling or the root
|
78
|
+
@elem = @top = nil
|
79
|
+
else
|
80
|
+
@elem = @elem.parent
|
81
|
+
end
|
82
|
+
else
|
83
|
+
# Not sure what to do since it seems we're not processing any element at this time, so how can one end?
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
##
|
90
|
+
# Adds namespaces and attributes. Nokogiri passes them as a array of [name, value, name, value]...
|
91
|
+
def add_namespaces_and_attributes_to_node(attrs, node)
|
92
|
+
(attrs.size / 2).times do |i|
|
93
|
+
name, value = attrs[2 * i], attrs[2 * i + 1]
|
94
|
+
if name =~ /xmlns/
|
95
|
+
node.add_namespace(name, value)
|
96
|
+
else
|
97
|
+
node.set_attribute name, value
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: julien51-babylon
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- julien Genestoux
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-03-
|
12
|
+
date: 2009-03-23 00:00:00 -07:00
|
13
13
|
default_executable: babylon
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -33,6 +33,7 @@ files:
|
|
33
33
|
- lib/babylon/router.rb
|
34
34
|
- lib/babylon/runner.rb
|
35
35
|
- lib/babylon/xmpp_connection.rb
|
36
|
+
- lib/babylon/xmpp_parser.rb
|
36
37
|
- lib/babylon/xpath_helper.rb
|
37
38
|
- LICENSE
|
38
39
|
- Rakefile
|