julien51-babylon 0.0.8 → 0.0.9
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/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
|