julien51-babylon 0.0.11 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +44 -62
- data/Rakefile +30 -6
- data/bin/babylon +4 -12
- data/lib/babylon.rb +4 -1
- data/lib/babylon/base/controller.rb +1 -1
- data/lib/babylon/base/stanza.rb +27 -0
- data/lib/babylon/generator.rb +132 -0
- data/lib/babylon/router.rb +12 -2
- data/lib/babylon/runner.rb +3 -0
- data/templates/babylon/app/controllers/controller.rb +7 -0
- data/templates/babylon/app/stanzas/stanza.rb +6 -0
- data/templates/babylon/app/views/view.rb +6 -0
- data/templates/babylon/config/boot.rb +1 -1
- data/templates/babylon/config/routes.rb +6 -8
- data/templates/babylon/script/component +2 -0
- metadata +9 -6
- data/templates/babylon/app/controllers/README.rdoc +0 -13
- data/templates/babylon/app/models/README.rdoc +0 -1
- data/templates/babylon/app/views/README.rdoc +0 -12
- data/templates/babylon/config/initializers/README.rdoc +0 -1
data/README.rdoc
CHANGED
@@ -1,86 +1,73 @@
|
|
1
|
-
=
|
1
|
+
= Babylon
|
2
2
|
|
3
3
|
== DESCRIPTION:
|
4
4
|
|
5
5
|
Babylon is a framework to build XMPP Applications in Ruby. The framework uses EventMachine to handle network connections.
|
6
6
|
|
7
|
-
This framework can use both an XMPP Component (XEP-0114) and an XMPP Client. However, we strongly discourage any production application using a regular client.
|
7
|
+
This framework can use both an XMPP Component (XEP-0114) and an XMPP Client (and XMPP Servers should come soone). However, we strongly discourage any production application using a regular client.
|
8
8
|
|
9
9
|
== FEATURES/PROBLEMS:
|
10
10
|
|
11
|
+
Please report/request them at the Lighthouse : http://babylon.lighthouseapp.com/projects/27641-babylon/overview
|
12
|
+
|
13
|
+
The current version is a good candidate for version 0.1. We will probably not add any important features before that release, but we need some help with the tests and documentation.
|
14
|
+
|
11
15
|
== ROADMAP :
|
12
16
|
|
13
|
-
- Instead of passing the stanzas as Nokogiri:XML:Node elements we should find a way to pass an "agnostic" ruby data-structure, so that app developers don't have to learn/know/understand Nokogiri
|
14
17
|
- Improve the Client Connection to support other authentication than PLAIN SASL
|
18
|
+
- Implement the ServerConnection for S2S
|
19
|
+
- Implement "auto-responding" features for disco-info... etc
|
20
|
+
- Use a better generator (the next version of Nokogiri should fix that)
|
21
|
+
- Implement "background" running when in production (and adjust log level)
|
22
|
+
- Delete route priorities? And rely on the order only? (As Rails does)
|
23
|
+
- Review doc
|
24
|
+
- Write more spec
|
25
|
+
- Write tests
|
26
|
+
- Evangelize!
|
27
|
+
|
28
|
+
You can help with at least one of these points, don't turn your back on Babylon!
|
29
|
+
|
30
|
+
== DOCUMENTATION :
|
31
|
+
|
32
|
+
You can find it on our Rubyforge page : http://babylon.rubyforge.org/
|
33
|
+
Please note that the documentation is probably incomplete... so if you have any problems with something that is not clear enough to you, feel free to send us questions and do not hesitate to fork the project to add your own documentation. We will be more than happy to help you help us!
|
15
34
|
|
16
|
-
== SYNOPSIS:
|
35
|
+
== SYNOPSIS :
|
17
36
|
|
18
37
|
You can build applications directly with Babylon, or you can use the Babylon::ClientConnection and Babylon::ComponentConnection to create simple apps, but you will then have to handle stanza routing and creation yourself. You can also use these classes in external gems.
|
19
38
|
|
20
|
-
To create an Application with Babylon:
|
39
|
+
=== To create an Application with Babylon:
|
21
40
|
|
22
41
|
1. Install the gem
|
23
42
|
2. The app contains a generator that will "build" a scaffold for your application.
|
24
43
|
|
25
|
-
$> babylon myapp
|
44
|
+
$> babylon application <myapp>
|
26
45
|
|
27
46
|
3. Use the generator or write your own controllers :
|
28
47
|
|
29
|
-
$>
|
30
|
-
|
31
|
-
This will generate a "MessageController" class with 2 methods : echo and subscribed. "echo" will be called when the component receives message stanzas of type 'chat', while "subscribed" will be called for presence stanzas of type 'subscribe'. 10 and 0 are the priority : useful when a stanza matches 2 XPath. Also, try to put high priorities to the "most frequent" stanzas to improve your component's performance. This will also generate 2 'views' used to build your stanzas. And finally, this will write 2 routes in the config/routes.rb
|
32
|
-
|
33
|
-
4. Write your application's code and views :
|
34
|
-
|
35
|
-
/app/controllers/message_controller.rb
|
36
|
-
|
37
|
-
class MessageController < Babylon::Base::Controller
|
38
|
-
|
39
|
-
def echo
|
40
|
-
extract_to_and_from
|
41
|
-
body = @stanza.xpath("//message/body").first
|
42
|
-
@resp = body.text.reverse
|
43
|
-
end
|
48
|
+
$> babylon controller messages echo:10://message[@type='chat']/body,subscribed:0://presence[@type='subscribe']
|
44
49
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
50
|
+
This will generate a "MessagesController" class with 2 methods : echo and subscribed.
|
51
|
+
- "echo" will be called when the component receives message stanzas of type 'chat',
|
52
|
+
- "subscribed" will be called for presence stanzas of type 'subscribe'.
|
53
|
+
10 and 0 are the priority : useful when a stanza matches 2 XPath.
|
49
54
|
|
50
|
-
|
55
|
+
Each of these actions will be called with stanza objects. You have to define your own objects in stanzas/echo.rb and stanzas/subscribed.rb
|
56
|
+
By defining them, you can choose which elements and attributes you want to have access to. These attributes will be populated upon instantiation of the Stanza objects.
|
51
57
|
|
52
|
-
|
53
|
-
@from = @stanza.attributes["to"].text
|
54
|
-
@to = @stanza.attributes["from"].text
|
55
|
-
end
|
58
|
+
This will also generate 2 'views' used to build your responses stanzas.
|
56
59
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
5. Implement the corresponding views (used to generate the messages). Babylon uses the same file conventions as Rails : a subdirectory for each controller, and one file per action :
|
61
|
-
Compared to Rails, we are using accessors (and not @variables assigned in the controller).
|
62
|
-
|
63
|
-
/app/views/message/echo.xml.builder
|
64
|
-
|
65
|
-
self.message(:to => to, :from => from, :type => :chat) do
|
66
|
-
self.body(resp)
|
67
|
-
end
|
68
|
-
|
69
|
-
/app/views/message/subscribed.xml.builder
|
60
|
+
And finally, this will write 2 routes in the config/routes.rb
|
70
61
|
|
71
|
-
|
72
|
-
self.body(ack) # Same as self.send(:body, body)
|
73
|
-
end
|
62
|
+
4. Customize your controllers, stanzas and views!
|
74
63
|
|
75
|
-
|
64
|
+
5. Make sure that the XMPP settings are correct in config/config.yaml. !!! You need to have a Jabber Component, regular clients will NOT work!!!
|
76
65
|
|
77
|
-
|
78
|
-
7. And finally start the component :
|
66
|
+
6. And finally start the component :
|
79
67
|
|
80
68
|
script/component
|
81
69
|
|
82
|
-
|
83
|
-
If you just want to make use of the connection classes (Client or Component), you can just call the following :
|
70
|
+
=== To use the Connection Classes only (Client or Component), you can just call the following :
|
84
71
|
|
85
72
|
Babylon::ClientConnection.connect(params, handler)
|
86
73
|
or,
|
@@ -88,22 +75,17 @@ Babylon::ComponentConnection.connect(params, handler)
|
|
88
75
|
|
89
76
|
where params is a hash for all the necessary information to connect, and handler is an object that will receive the callbacks. Right now 3 callbacks are supported:
|
90
77
|
|
91
|
-
on_connected, on_disconnected and on_stanza
|
92
|
-
|
93
|
-
|
94
|
-
== ADDITIONAL INFORMATION
|
95
|
-
|
96
|
-
This code hasn't been 100% tested. Feel free to pull, branch, improve {code|specs|tests|docs} and we will merge it!
|
78
|
+
on_connected(connection), on_disconnected and on_stanza(stanza)
|
97
79
|
|
98
|
-
==
|
80
|
+
== ADDITIONAL INFORMATION :
|
99
81
|
|
100
|
-
|
82
|
+
Feel free to pull, branch, improve and commit the {code|specs|tests|docs} : we will merge it if it's a step ahead!
|
101
83
|
|
102
|
-
|
84
|
+
Babylon's edge versions are located at Github : http://github.com/julien51/babylon/tree/master
|
103
85
|
|
104
|
-
==
|
86
|
+
== REQUIREMENTS :
|
105
87
|
|
106
|
-
|
88
|
+
Gems : Eventmachine, nokogiri, YAML, log4r, sax-machine
|
107
89
|
|
108
90
|
== LICENSE:
|
109
91
|
|
data/Rakefile
CHANGED
@@ -9,11 +9,35 @@ begin
|
|
9
9
|
gem.email = "julien.genestoux@gmail.com"
|
10
10
|
gem.homepage = "http://github.com/julien51/babylon"
|
11
11
|
gem.authors = ["julien Genestoux"]
|
12
|
-
gem.requirements = ["eventmachine", "yaml", "fileutils", "log4r", "nokogiri"]
|
12
|
+
gem.requirements = ["eventmachine", "yaml", "fileutils", "log4r", "nokogiri", "sax-machine"]
|
13
13
|
gem.executables = "babylon"
|
14
|
-
gem.files = ["bin/babylon",
|
15
|
-
|
16
|
-
|
14
|
+
gem.files = [ "bin/babylon",
|
15
|
+
"lib/babylon.rb",
|
16
|
+
"lib/babylon/base/controller.rb",
|
17
|
+
"lib/babylon/base/view.rb",
|
18
|
+
"lib/babylon/base/stanza.rb",
|
19
|
+
"lib/babylon/client_connection.rb",
|
20
|
+
"lib/babylon/component_connection.rb",
|
21
|
+
"lib/babylon/router/dsl.rb",
|
22
|
+
"lib/babylon/router.rb",
|
23
|
+
"lib/babylon/runner.rb",
|
24
|
+
"lib/babylon/generator.rb",
|
25
|
+
"lib/babylon/xmpp_connection.rb",
|
26
|
+
"lib/babylon/xmpp_parser.rb",
|
27
|
+
"lib/babylon/xpath_helper.rb",
|
28
|
+
"LICENSE",
|
29
|
+
"Rakefile",
|
30
|
+
"README.rdoc",
|
31
|
+
"templates/babylon/app/controllers/controller.rb",
|
32
|
+
"templates/babylon/app/views/view.rb",
|
33
|
+
"templates/babylon/app/stanzas/stanza.rb",
|
34
|
+
"templates/babylon/config/boot.rb",
|
35
|
+
"templates/babylon/config/config.yaml",
|
36
|
+
"templates/babylon/config/dependencies.rb",
|
37
|
+
"templates/babylon/config/routes.rb",
|
38
|
+
"templates/babylon/script/component"
|
39
|
+
]
|
40
|
+
gem.rubyforge_project = 'babylon'
|
17
41
|
end
|
18
42
|
rescue LoadError
|
19
43
|
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
@@ -22,10 +46,10 @@ end
|
|
22
46
|
require 'rake/rdoctask'
|
23
47
|
Rake::RDocTask.new do |rdoc|
|
24
48
|
rdoc.rdoc_dir = 'rdoc'
|
25
|
-
rdoc.title = '
|
26
|
-
rdoc.options << '--line-numbers' << '--inline-source'
|
49
|
+
rdoc.title = 'Babylon : a framework to create EventMachine based XMPP External Components in Ruby.'
|
27
50
|
rdoc.rdoc_files.include('README*')
|
28
51
|
rdoc.rdoc_files.include('lib/**/*.rb')
|
52
|
+
rdoc.options << '--line-numbers'
|
29
53
|
end
|
30
54
|
|
31
55
|
require 'rake/testtask'
|
data/bin/babylon
CHANGED
@@ -1,14 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'babylon'
|
2
5
|
|
3
|
-
|
4
|
-
# This will generate the right hierarchy for a Babylon App
|
5
|
-
# First, let's create the app directoryn based in ARGV[0]
|
6
|
-
|
7
|
-
require 'fileutils'
|
8
|
-
|
9
|
-
if ARGV[0]
|
10
|
-
puts "Creating app '#{ARGV[0]}' in #{Dir.pwd}..."
|
11
|
-
FileUtils.cp_r "#{File.dirname(__FILE__)}/../templates/babylon", "#{Dir.pwd}/#{ARGV[0]}"
|
12
|
-
else
|
13
|
-
puts "Usage: #{$0} <app_name>"
|
14
|
-
end
|
6
|
+
Babylon::Generator.run_cli(Dir.pwd, 'babylon_app', "0.1", ARGV)
|
data/lib/babylon.rb
CHANGED
@@ -6,6 +6,7 @@ require 'log4r'
|
|
6
6
|
require 'nokogiri'
|
7
7
|
require 'yaml'
|
8
8
|
require 'fileutils'
|
9
|
+
require 'sax-machine'
|
9
10
|
|
10
11
|
require 'babylon/xmpp_connection'
|
11
12
|
require 'babylon/xmpp_parser'
|
@@ -13,15 +14,17 @@ require 'babylon/component_connection'
|
|
13
14
|
require 'babylon/client_connection'
|
14
15
|
require 'babylon/router'
|
15
16
|
require 'babylon/runner'
|
17
|
+
require 'babylon/generator'
|
16
18
|
require "babylon/xpath_helper"
|
17
19
|
require 'babylon/base/controller'
|
18
20
|
require 'babylon/base/view'
|
21
|
+
require 'babylon/base/stanza'
|
19
22
|
|
20
23
|
# Babylon is a XMPP Component Framework based on EventMachine. It uses the Nokogiri GEM, which is a Ruby wrapper for Libxml2.
|
21
24
|
# It implements the MVC paradigm.
|
22
25
|
# You can create your own application by running :
|
23
26
|
# $> babylon app_name
|
24
|
-
# This will generate some folders and files for your application. Please see README for further instructions
|
27
|
+
# This will generate some folders and files for your application. Please see README.rdoc for further instructions
|
25
28
|
|
26
29
|
module Babylon
|
27
30
|
|
@@ -73,8 +73,8 @@ module Babylon
|
|
73
73
|
|
74
74
|
# Creates the view and "evaluates" it to build the XML for the stanza
|
75
75
|
def render_for_file(file)
|
76
|
-
Babylon.logger.info("RENDERING : #{file}")
|
77
76
|
@block.call(Babylon::Base::View.new(file, hashed_variables).evaluate) if @block
|
77
|
+
Babylon.logger.info("RENDERED : #{file}")
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "sax-machine"
|
2
|
+
|
3
|
+
module Babylon
|
4
|
+
module Base
|
5
|
+
##
|
6
|
+
# Class used to Parse a Stanza on the XMPP stream.
|
7
|
+
# You should have a Stanza subsclass for each of your controller actions, as they allow you to define which stanzas and which information is passed to yoru controllers.
|
8
|
+
#
|
9
|
+
# You can define your own macthing pretty easily with the element and elements methods, as explained in the SaxMachine Documentation: http://github.com/pauldix/sax-machine/tree/master
|
10
|
+
# if your stanza is a message stanza, you can match the following for example:
|
11
|
+
# element :message, :value => :to, :as => :to
|
12
|
+
# element :message, :value => :from, :as => :from
|
13
|
+
# element :message, :value => :id, :as => :stanza_id
|
14
|
+
# element :message, :value => :type, :as => :stanza_type
|
15
|
+
# element :message, :value => :"xml:lang", :as => :lang
|
16
|
+
|
17
|
+
class Stanza
|
18
|
+
|
19
|
+
include SAXMachine
|
20
|
+
|
21
|
+
def initialize(xml = nil)
|
22
|
+
@xml = xml
|
23
|
+
parse("#{xml}")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require "templater"
|
2
|
+
|
3
|
+
module Babylon
|
4
|
+
module Generator
|
5
|
+
extend Templater::Manifold
|
6
|
+
|
7
|
+
desc <<-DESC
|
8
|
+
Babylon is a framework to generate XMPP Applications in Ruby."
|
9
|
+
DESC
|
10
|
+
|
11
|
+
##
|
12
|
+
# Generates a Babylon Application
|
13
|
+
class ApplicationGenerator < Templater::Generator
|
14
|
+
desc <<-DESC
|
15
|
+
Generates the file architecture for a Babylon Application. To run, you MUST provide an application name"
|
16
|
+
DESC
|
17
|
+
|
18
|
+
first_argument :application_name, :required => true, :desc => "Your application name."
|
19
|
+
|
20
|
+
def self.source_root
|
21
|
+
File.join(File.dirname(__FILE__), '../../templates/babylon')
|
22
|
+
end
|
23
|
+
|
24
|
+
# Create all subsdirectories
|
25
|
+
empty_directory :app_directory do |d|
|
26
|
+
d.destination = "#{application_name}/app"
|
27
|
+
end
|
28
|
+
empty_directory :controllers_directory do |d|
|
29
|
+
d.destination = "#{application_name}/app/controllers"
|
30
|
+
end
|
31
|
+
empty_directory :views_directory do |d|
|
32
|
+
d.destination = "#{application_name}/app/views"
|
33
|
+
end
|
34
|
+
empty_directory :views_directory do |d|
|
35
|
+
d.destination = "#{application_name}/app/stanzas"
|
36
|
+
end
|
37
|
+
empty_directory :models_directory do |d|
|
38
|
+
d.destination = "#{application_name}/app/models"
|
39
|
+
end
|
40
|
+
empty_directory :initializers_directory do |d|
|
41
|
+
d.destination = "#{application_name}/config/initializers"
|
42
|
+
end
|
43
|
+
|
44
|
+
# And now add the critical files
|
45
|
+
file :boot_file do |f|
|
46
|
+
f.source = "#{source_root}/config/boot.rb"
|
47
|
+
f.destination = "#{application_name}/config/boot.rb"
|
48
|
+
end
|
49
|
+
file :config_file do |f|
|
50
|
+
f.source = "#{source_root}/config/config.yaml"
|
51
|
+
f.destination = "#{application_name}/config/config.yaml"
|
52
|
+
end
|
53
|
+
file :dependencies_file do |f|
|
54
|
+
f.source = "#{source_root}/config/dependencies.rb"
|
55
|
+
f.destination = "#{application_name}/config/dependencies.rb"
|
56
|
+
end
|
57
|
+
file :dependencies_file do |f|
|
58
|
+
f.source = "#{source_root}/config/routes.rb"
|
59
|
+
f.destination = "#{application_name}/config/routes.rb"
|
60
|
+
end
|
61
|
+
file :component_file do |f|
|
62
|
+
f.source = "#{source_root}/script/component"
|
63
|
+
f.destination = "#{application_name}/script/component"
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Generates a new controller, with the corresponding stanzas and routes.
|
70
|
+
class ControllerGenerator < Templater::Generator
|
71
|
+
desc <<-DESC
|
72
|
+
Generates a new controller for the current Application. It also adds the corresponding routes and actions, based on a Xpath and priority. \nSyntax: babylon controller <controller_name> [<action_name>:<priority>:<xpath>],[...]"
|
73
|
+
DESC
|
74
|
+
|
75
|
+
first_argument :controller_name, :required => true, :desc => "Name of the Controller."
|
76
|
+
second_argument :actions_arg, :required => true, :as => :array, :default => [], :desc => "Actions implemented by this controller. Use the following syntax : name:priority:xpath"
|
77
|
+
|
78
|
+
def self.source_root
|
79
|
+
File.join(File.dirname(__FILE__), '../../templates/babylon/app/controllers')
|
80
|
+
end
|
81
|
+
|
82
|
+
def controller_actions
|
83
|
+
@controller_actions ||= actions_arg.map { |a| a.split(":") }
|
84
|
+
end
|
85
|
+
|
86
|
+
def controller_class_name
|
87
|
+
"#{controller_name.capitalize}Controller"
|
88
|
+
end
|
89
|
+
|
90
|
+
##
|
91
|
+
# This is a hack since Templater doesn't offer any simple way to edit files right now...
|
92
|
+
def add_route_for_actions_in_controller(actions, controller)
|
93
|
+
sentinel = "Babylon::CentralRouter.draw do"
|
94
|
+
router_path = "config/routes.rb"
|
95
|
+
actions.each do |action|
|
96
|
+
to_inject = "xpath(\"#{action[2]}\").to(:controller => \"#{controller}\", :action => \"#{action[0]}\").priority(#{action[1]})"
|
97
|
+
if File.exist?(router_path)
|
98
|
+
content = File.read(router_path).gsub(/(#{Regexp.escape(sentinel)})/mi){|match| "#{match}\n\t#{to_inject}"}
|
99
|
+
File.open(router_path, 'wb') { |file| file.write(content) }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
template :controller do |t|
|
105
|
+
t.source = "#{source_root}/controller.rb"
|
106
|
+
t.destination = "app/controllers/#{controller_name}_controller.rb"
|
107
|
+
self.add_route_for_actions_in_controller(controller_actions, controller_name)
|
108
|
+
# This is a hack since Templater doesn't offer any simple way to write several files from one...
|
109
|
+
FileUtils.mkdir("app/views/#{controller_name}") unless File.exists?("app/views/#{controller_name}")
|
110
|
+
controller_actions.each do |action|
|
111
|
+
FileUtils.cp("#{source_root}/../views/view.rb", "app/views/#{controller_name}/#{action[0]}.xml.builder")
|
112
|
+
end
|
113
|
+
|
114
|
+
# And now, let's create the stanza files
|
115
|
+
controller_actions.each do |action|
|
116
|
+
FileUtils.cp("#{source_root}/../stanzas/stanza.rb", "app/stanzas/#{action[0]}.rb")
|
117
|
+
# We need to replace
|
118
|
+
# "class Stanza < Babylon::Base::Stanza" with "class #{action[0]} < Babylon::Base::Stanza"
|
119
|
+
content = File.read("app/stanzas/#{action[0]}.rb").gsub("class Stanza < Babylon::Base::Stanza", "class #{action[0].capitalize} < Babylon::Base::Stanza")
|
120
|
+
File.open("app/stanzas/#{action[0]}.rb", 'wb') { |file| file.write(content) }
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# The generators are added to the manifold, and assigned the names 'wiki' and 'blog'.
|
126
|
+
# So you can call them <script name> blog merb-blog-in-10-minutes and
|
127
|
+
# <script name> blog merb-wiki-in-10-minutes, respectively
|
128
|
+
add :application, ApplicationGenerator
|
129
|
+
add :controller, ControllerGenerator
|
130
|
+
|
131
|
+
end
|
132
|
+
end
|
data/lib/babylon/router.rb
CHANGED
@@ -2,6 +2,11 @@ require File.dirname(__FILE__)+"/router/dsl"
|
|
2
2
|
|
3
3
|
module Babylon
|
4
4
|
|
5
|
+
|
6
|
+
##
|
7
|
+
# Undefined stanza
|
8
|
+
class UndefinedStanza < Exception; end
|
9
|
+
|
5
10
|
##
|
6
11
|
# The router is in charge of sending the right stanzas to the right controllers based on user defined Routes.
|
7
12
|
module Router
|
@@ -46,7 +51,12 @@ module Babylon
|
|
46
51
|
if route.accepts?(stanza)
|
47
52
|
# Here should happen the magic : call the controller
|
48
53
|
Babylon.logger.info("ROUTING TO #{route.controller}::#{route.action}")
|
49
|
-
|
54
|
+
# Parsing the stanza
|
55
|
+
begin
|
56
|
+
controller = route.controller.new({:stanza => Kernel.const_get(route.action.capitalize).new(stanza)})
|
57
|
+
rescue NameError
|
58
|
+
raise UndefinedStanza
|
59
|
+
end
|
50
60
|
controller.perform(route.action) do |response|
|
51
61
|
# Response should be a Nokogiri::Nodeset
|
52
62
|
@@connection.send(response)
|
@@ -84,7 +94,7 @@ module Babylon
|
|
84
94
|
end
|
85
95
|
|
86
96
|
##
|
87
|
-
# Main router
|
97
|
+
# Main router for a Babylon Application.
|
88
98
|
module CentralRouter
|
89
99
|
extend Router
|
90
100
|
end
|
data/lib/babylon/runner.rb
CHANGED
@@ -20,6 +20,9 @@ module Babylon
|
|
20
20
|
# Requiring all models
|
21
21
|
Dir.glob('app/models/*.rb').each { |f| require f }
|
22
22
|
|
23
|
+
# Requiring all stanzas
|
24
|
+
Dir.glob('app/stanzas/*.rb').each { |f| require f }
|
25
|
+
|
23
26
|
# Load the controllers
|
24
27
|
Dir.glob('app/controllers/*_controller.rb').each {|f| require f }
|
25
28
|
|
@@ -0,0 +1,6 @@
|
|
1
|
+
class Stanza < Babylon::Base::Stanza
|
2
|
+
# element :message, :as => :to, :value => :to (will add a .to method for your <message> stanza, based on the "to" attribute)
|
3
|
+
# element :pubsub (will match to the content of <pubsub> and define a .pubsub method)
|
4
|
+
# element :publish, :as => :node, :value => :node (will match to the content of the "node" attribute of <publish> and defined a .node method)
|
5
|
+
# elements :entry, :as => :entries, :class => AtomEntry (will match <entry> elements to a subclass AtomEntry (that you must define, using SaxMachine) and create a .entries.methods that returns an Array of AtomEntry.
|
6
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
# Please see Babylon Rdoc. Put all the views related to controller MyController into app/views/my/...
|
2
|
+
# This file are Xml Builder Files (see Nokogiri Documentation for any doubt : http://nokogiri.rubyforge.org/nokogiri/Nokogiri/XML/Builder.html ).
|
3
|
+
|
4
|
+
# xml.message(:to => @to, :from => @from, :type => :chat) do
|
5
|
+
# xml.body(@body) # Same as self.send(:body, body)
|
6
|
+
# end
|
@@ -1,18 +1,14 @@
|
|
1
1
|
# Routes require an xpath against which to match, and a controller/action pair to which to map.
|
2
2
|
#
|
3
|
-
# xpath("//message[@type = 'chat']"
|
4
|
-
# ).to(:controller => "message", :action => "receive")
|
3
|
+
# xpath("//message[@type = 'chat']").to(:controller => "message", :action => "receive")
|
5
4
|
#
|
6
5
|
# Routes can be assigned priorities. The highest priority executes first, and the default priority is 0.
|
7
6
|
#
|
8
|
-
# xpath("//message[@type = 'chat']"
|
9
|
-
# ).to(:controller => "message", :action => "priority"
|
10
|
-
# ).priority(5000000)
|
7
|
+
# xpath("//message[@type = 'chat']").to(:controller => "message", :action => "priority").priority(5000000)
|
11
8
|
#
|
12
9
|
# It is not possible to easily check for namespace URI equivalence in xpath, but the following helper function was added.
|
13
10
|
#
|
14
|
-
# xpath("//iq[@type='get']/*[namespace(., 'query', 'http://jabber.org/protocol/disco#info')]"
|
15
|
-
# ).to(:controller => "discovery", :action => "services")
|
11
|
+
# xpath("//iq[@type='get']/*[namespace(., 'query', 'http://jabber.org/protocol/disco#info')]").to(:controller => "discovery", :action => "services")
|
16
12
|
#
|
17
13
|
# That syntax is ugly out of necessity. But, relax, you're using Ruby.
|
18
14
|
#
|
@@ -21,4 +17,6 @@
|
|
21
17
|
# disco_info.to(:controller => "discovery", :action => "services")
|
22
18
|
#
|
23
19
|
# See lib/babylon/router/dsl.rb for more helpers.
|
24
|
-
|
20
|
+
Babylon::CentralRouter.draw do
|
21
|
+
|
22
|
+
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.12
|
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-31 00:00:00 -07:00
|
13
13
|
default_executable: babylon
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -27,25 +27,27 @@ files:
|
|
27
27
|
- lib/babylon.rb
|
28
28
|
- lib/babylon/base/controller.rb
|
29
29
|
- lib/babylon/base/view.rb
|
30
|
+
- lib/babylon/base/stanza.rb
|
30
31
|
- lib/babylon/client_connection.rb
|
31
32
|
- lib/babylon/component_connection.rb
|
32
33
|
- lib/babylon/router/dsl.rb
|
33
34
|
- lib/babylon/router.rb
|
34
35
|
- lib/babylon/runner.rb
|
36
|
+
- lib/babylon/generator.rb
|
35
37
|
- lib/babylon/xmpp_connection.rb
|
36
38
|
- lib/babylon/xmpp_parser.rb
|
37
39
|
- lib/babylon/xpath_helper.rb
|
38
40
|
- LICENSE
|
39
41
|
- Rakefile
|
40
42
|
- README.rdoc
|
41
|
-
- templates/babylon/app/controllers/
|
42
|
-
- templates/babylon/app/
|
43
|
-
- templates/babylon/app/
|
43
|
+
- templates/babylon/app/controllers/controller.rb
|
44
|
+
- templates/babylon/app/views/view.rb
|
45
|
+
- templates/babylon/app/stanzas/stanza.rb
|
44
46
|
- templates/babylon/config/boot.rb
|
45
47
|
- templates/babylon/config/config.yaml
|
46
48
|
- templates/babylon/config/dependencies.rb
|
47
49
|
- templates/babylon/config/routes.rb
|
48
|
-
- templates/babylon/
|
50
|
+
- templates/babylon/script/component
|
49
51
|
has_rdoc: true
|
50
52
|
homepage: http://github.com/julien51/babylon
|
51
53
|
post_install_message:
|
@@ -72,6 +74,7 @@ requirements:
|
|
72
74
|
- fileutils
|
73
75
|
- log4r
|
74
76
|
- nokogiri
|
77
|
+
- sax-machine
|
75
78
|
rubyforge_project: babylon
|
76
79
|
rubygems_version: 1.2.0
|
77
80
|
signing_key:
|
@@ -1 +0,0 @@
|
|
1
|
-
You can define you class models here. It is totally ok to reuse your ActiveRecord from another application!
|
@@ -1,12 +0,0 @@
|
|
1
|
-
= Babylon::Base::View
|
2
|
-
|
3
|
-
== Usage
|
4
|
-
|
5
|
-
Please see Babylon Rdoc. Put all the views related to controller MyController into app/views/my/...
|
6
|
-
This file are Xml Builder Files (see Nokogiri Documentation for any doubt).
|
7
|
-
|
8
|
-
== Example
|
9
|
-
|
10
|
-
self.message(:to => to, :from => from, :type => :chat) do
|
11
|
-
self.body(body) // Same as self.send(:body, body) (
|
12
|
-
end
|
@@ -1 +0,0 @@
|
|
1
|
-
Place any application-specific code that needs to be run during initialization in this directory.
|