julien51-babylon 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc ADDED
@@ -0,0 +1,89 @@
1
+ = babylon
2
+
3
+ == DESCRIPTION:
4
+
5
+ Babylon is a framework to EventMachine based XMPP External Components in Ruby.
6
+
7
+ == FEATURES/PROBLEMS:
8
+
9
+ * This hasn't been tested.
10
+ * Problems with quotes and double-quotes in text that are not handled correctly... I spent too many hours on this! Please help!
11
+
12
+ == ROADMAP :
13
+
14
+ - Instead of passing the stanzas as Nokogiri:XML:Node elements we should find a way to pass an "agnostic" datastructure, so that app developers don't have to learn/know/understand Nokogiri
15
+ - Adding the ability to send several messages all at once (like render :collection in Rails)
16
+
17
+ == SYNOPSIS:
18
+
19
+ 1. Install the gem
20
+ 2. The app contains a generator that will "build" a scaffold for your application.
21
+
22
+ $> babylon myapp
23
+
24
+ 3. Write your own "controllers"
25
+
26
+ /app/controllers/message_controller.rb
27
+
28
+ class MessageController < Babylon::Base::Controller
29
+ # Each controller is initiated with the stanza.(similar to params in rails actions)
30
+
31
+ def echo
32
+ # We do stuff here
33
+ @to = @stanza.attributes["from"].text
34
+ @from = @stanza.attributes["from"].text
35
+ @response = @stanza.elements["//body"].text
36
+ # By default, this would "render" the echo.xml.builder
37
+ end
38
+ end
39
+
40
+ 4. Add 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 :
41
+ Compared to Rails, we are using accessors (and not @variables assigned in the controller).
42
+
43
+ /app/views/message/echo.xml.builder
44
+
45
+ self.message(:to => to, :from => from, :type => :chat) do
46
+ self.body(response)
47
+ end
48
+
49
+ 5. And finally start the component :
50
+
51
+ script/component
52
+
53
+ == ADDITIONAL INFORMATION
54
+
55
+ This code hasn't been tested at all! It's just a proof of concept. Feel free to pull, branch, improve {code|specs|tests|docs} and we will merge it!
56
+
57
+ == REQUIREMENTS:
58
+
59
+ Our goal is to limit the number of dependencies. Nokogiri seems to be only XML Library on Ruby that has a Push SAX Parser, that is why we are using it. It also seems pretty 'fast'.
60
+ Gems : Eventmachine, nokogiri
61
+
62
+ == INSTALL:
63
+
64
+ - sudo gem install babylon
65
+
66
+ == LICENSE:
67
+
68
+ (The MIT License)
69
+
70
+ Copyright (c) 2009 Julien Genestoux http://notifixio.us
71
+
72
+ Permission is hereby granted, free of charge, to any person obtaining
73
+ a copy of this software and associated documentation files (the
74
+ 'Software'), to deal in the Software without restriction, including
75
+ without limitation the rights to use, copy, modify, merge, publish,
76
+ distribute, sublicense, and/or sell copies of the Software, and to
77
+ permit persons to whom the Software is furnished to do so, subject to
78
+ the following conditions:
79
+
80
+ The above copyright notice and this permission notice shall be
81
+ included in all copies or substantial portions of the Software.
82
+
83
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
84
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
85
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
86
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
87
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
88
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
89
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/bin/babylon ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Generates the stubs for a new Babylon Application
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
+ if ARGV[0]
8
+ puts "Creating app '#{ARGV[0]}' in #{Dir.pwd}..."
9
+ FileUtils.cp_r "#{File.dirname(__FILE__)}/../templates/babylon", "#{Dir.pwd}/#{ARGV[0]}"
10
+ else
11
+ puts "Syntax : $> babylon app_name "
12
+ end
data/lib/babylon.rb ADDED
@@ -0,0 +1,24 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require 'eventmachine'
5
+ require 'nokogiri'
6
+
7
+ require 'babylon/xmpp_connection'
8
+ require 'babylon/component_connection'
9
+ require 'babylon/router'
10
+ require 'babylon/runner'
11
+ require 'babylon/base/controller'
12
+ require 'babylon/base/view'
13
+
14
+ # Babylon is a XMPP Component Framework based on EventMachine. It uses the Nokogiri GEM, which is a Ruby wrapper for Libxml2.
15
+ # It implements the MVC paradigm.
16
+ # You can create your own application by running :
17
+ # $> babylon app_name
18
+ # This will generate some folders and files for your application. Please see README for further instructions
19
+
20
+ module Babylon
21
+ # 0.0.3 : Not suited for production, use at your own risks
22
+ VERSION = '0.0.3'
23
+ end
24
+
@@ -0,0 +1,62 @@
1
+ module Babylon
2
+ module Base
3
+
4
+ # Your application's controller should be descendant of this class.
5
+
6
+ class Controller
7
+
8
+ attr_accessor :stanza # Stanza received by the controller (Nokogiri::XML::Node)
9
+
10
+ # Creates a new controller (you should not override this class) and assigns the stanza
11
+ def initialize(params = {})
12
+ @stanza = params[:stanza]
13
+ @rendered = false
14
+ end
15
+
16
+ # Performs the action and calls back the optional block argument : you should not override this function
17
+ def perform(action, &block)
18
+ @action_name = action
19
+ @block = block
20
+ self.send(@action_name)
21
+ self.render
22
+ end
23
+
24
+ # Called by default after each action to "build" a XMPP stanza. By default, it will use the /controller_name/action.xml.builder
25
+ def render(options = nil)
26
+ return if @rendered # Avoid double rendering
27
+
28
+ if options.nil? # default rendering
29
+ return render(:file => default_template_name)
30
+ elsif action_name = options[:action]
31
+ return render(:file => default_template_name(action_name.to_s))
32
+ end
33
+ render_for_file(options[:file])
34
+
35
+ # And finally, we set up rendered to be true
36
+ @rendered = true
37
+ end
38
+
39
+ protected
40
+
41
+ # Used to transfer the assigned variables from the controller to the views
42
+ def hashed_variables
43
+ vars = Hash.new
44
+ instance_variables.each do |var|
45
+ vars[var[1..-1]] = instance_variable_get(var)
46
+ end
47
+ return vars
48
+ end
49
+
50
+ # Default template name used to build stanzas
51
+ def default_template_name(action_name = nil)
52
+ "app/views/#{self.class.name.gsub("Controller","").downcase}/#{action_name || @action_name}.xml.builder"
53
+ end
54
+
55
+ # Creates the view and "evaluates" it to build the XML for the stanza
56
+ def render_for_file(file)
57
+ view = Babylon::Base::View.new(file, hashed_variables)
58
+ @block.call(view.evaluate)
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,50 @@
1
+ module Babylon
2
+ module Base
3
+
4
+ ##
5
+ # Your application's views (stanzas) should be descendant of this class.
6
+ class View
7
+ attr_reader :output
8
+
9
+ ##
10
+ # Instantiate a new view with the various varibales passed in assigns and the path of the template to render.
11
+ def initialize(path, assigns)
12
+ @assigns = assigns
13
+ @output = ""
14
+ @view_template = path
15
+ end
16
+
17
+ ##
18
+ # "Loads" the view file, and uses the Nokogiri Builder to build the XML stanzas that will be sent.
19
+ def evaluate
20
+ evaluate_assigns
21
+ view_content = File.read(@view_template)
22
+ xml = Nokogiri::XML::Builder.new do
23
+ instance_eval(view_content)
24
+ end
25
+ return xml.doc.root.to_xml #we return the doc's root (to avoid the instruct)
26
+ end
27
+
28
+ ##
29
+ # Evaluate the local assigns and pushes them to the view.
30
+ def evaluate_assigns
31
+ unless @assigns_added
32
+ assign_variables_from_controller
33
+ @assigns_added = true
34
+ end
35
+ end
36
+
37
+ ##
38
+ # Assigns instance variables from the controller to the view.
39
+ def assign_variables_from_controller
40
+ @assigns.each do |key, value|
41
+ instance_variable_set("@#{key}", value)
42
+ self.class.send(:define_method, key) do # Defining accessors
43
+ value
44
+ end
45
+ end
46
+ end
47
+
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,61 @@
1
+ module Babylon
2
+ ##
3
+ # ComponentConnection is in charge of the XMPP connection itself.
4
+ # Upon stanza reception, and depending on the status (connected... etc), this component will handle or forward the stanzas.
5
+ class ComponentConnection < XmppConnection
6
+ require 'digest/sha1'
7
+
8
+ ##
9
+ # Creates a new ComponentConnection and waits for data in the stream
10
+ def initialize(*a)
11
+ super
12
+ @state = :wait_for_stream
13
+ end
14
+
15
+ ##
16
+ # XMPP Component handshake as defined in XEP-0114:
17
+ # http://xmpp.org/extensions/xep-0114.html
18
+ def receive_stanza(stanza)
19
+ case @state
20
+
21
+ when :wait_for_stream
22
+ if stanza.name == "stream:stream" && stanza.attributes['id']
23
+ # This means the XMPP session started!
24
+ # We must send the handshake now.
25
+ hash = Digest::SHA1::hexdigest(stanza.attributes['id'].content + @config['password'])
26
+ handshake = Nokogiri::XML::Node.new("handshake", stanza.document)
27
+ handshake.content = hash
28
+ send(handshake)
29
+ @state = :wait_for_handshake
30
+ else
31
+ raise
32
+ end
33
+
34
+ when :wait_for_handshake
35
+ if stanza.name == "handshake"
36
+ # Awesome, we're now connected and authentified, let's
37
+ # callback the controllers to tell them we're connected!
38
+ # TODO
39
+ @state = :connected
40
+ else
41
+ raise
42
+ end
43
+
44
+ when :connected
45
+ super # Can be dispatched
46
+ end
47
+ end
48
+
49
+ ##
50
+ # Namespace of the component
51
+ def stream_namespace
52
+ 'jabber:component:accept'
53
+ end
54
+
55
+ ##
56
+ # Jid of the component
57
+ def stream_to
58
+ @config['jid']
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,79 @@
1
+ module Babylon
2
+
3
+ ##
4
+ # The router is in charge of sending the right stanzas to the right controllers based on user defined Routes.
5
+ module Router
6
+
7
+ ##
8
+ # Add several routes to the router
9
+ # Routes should be of form {name => params}
10
+ def add_routes(routes)
11
+ routes.each do |name, params|
12
+ add_route(Route.new(name, params))
13
+ end
14
+ end
15
+
16
+ ##
17
+ # Insert a route and makes sure that the routes are sorted
18
+ def add_route(route)
19
+ @routes ||= []
20
+ @routes << route
21
+ @routes.sort! { |r1,r2|
22
+ r2.priority <=> r1.priority
23
+ }
24
+ end
25
+
26
+ # Look for the first martching route and calls the correspondong action for the corresponding controller.
27
+ # Sends the response on the XMPP stream/
28
+ def route(connection, stanza)
29
+ @routes ||= []
30
+ @routes.each { |route|
31
+ if route.accepts?(connection, stanza)
32
+ # Here should happen the magic : call the controller
33
+ controller = route.controller.new({:stanza => stanza})
34
+ controller.perform(route.action) do |response|
35
+ connection.send(response)
36
+ end
37
+ return true
38
+ end
39
+ }
40
+ false
41
+ end
42
+
43
+ # Throw away all added routes from this router. Helpful for
44
+ # testing.
45
+ def purge_routes!
46
+ @routes = []
47
+ end
48
+ end
49
+
50
+ ##
51
+ # Main router where all dispatchers shall register.
52
+ module CentralRouter
53
+ extend Router
54
+ end
55
+
56
+ ##
57
+ # Route class which associate an XPATH match and a priority to a controller and an action
58
+ class Route
59
+
60
+ attr_reader :priority, :controller, :action
61
+
62
+ ##
63
+ # Creates a new route
64
+ def initialize(name, params)
65
+ @priority = params["priority"]
66
+ @xpath = params["xpath"]
67
+ @controller = Kernel.const_get("#{params["controller"].capitalize}Controller")
68
+ @action = params["action"]
69
+ end
70
+
71
+ ##
72
+ # Checks that the route matches the stanzas and calls the the action on the controller
73
+ def accepts?(connection, stanza)
74
+ stanza.xpath(@xpath, stanza.namespaces).first ? self : false
75
+ end
76
+
77
+ end
78
+
79
+ end
@@ -0,0 +1,31 @@
1
+ module Babylon
2
+
3
+ ##
4
+ # Runner is in charge of running the application.
5
+ class Runner
6
+
7
+ ##
8
+ # When run is called, it loads the configuration, the routes and add them into the router
9
+ # It then loads the models.
10
+ # Finally it starts the EventMachine and connect the ComponentConnection
11
+ def self.run(env = "development")
12
+ config = YAML::load(File.new('config/config.yaml'))[env]
13
+ routes = YAML::load(File.new('config/routes.yaml')) || []
14
+
15
+ # Adding Routes
16
+ CentralRouter.add_routes(routes)
17
+
18
+ # Requiring all models
19
+ Dir.glob('app/models/*.rb').each do |f|
20
+ require f
21
+ end
22
+
23
+ # Starting the EventMachine
24
+ EventMachine.epoll
25
+ EventMachine::run do
26
+ Babylon::ComponentConnection.connect(config)
27
+ end
28
+ end
29
+
30
+ end
31
+ end
@@ -0,0 +1,161 @@
1
+ module Babylon
2
+
3
+ ##
4
+ # Connection Exception
5
+ class NotConnected < Exception; end
6
+
7
+ ##
8
+ # This class is in charge of handling the network connection to the XMPP server.
9
+ class XmppConnection < EventMachine::Connection
10
+
11
+ attr_reader :config
12
+
13
+ ##
14
+ # Connects the XmppConnection to the right host with the right port.
15
+ # It passes itself (as handler) and the configuration
16
+ def self.connect(config)
17
+ EventMachine::connect config['host'], config['port'], self, config
18
+ end
19
+
20
+ ##
21
+ # Called when the connection is terminated and stops the event loop
22
+ def unbind()
23
+ EventMachine::stop_event_loop
24
+ end
25
+
26
+ ##
27
+ # Instantiate the Handler (called internally by EventMachine) and attaches a new XmppParser
28
+ def initialize(config)
29
+ @config = config
30
+ super()
31
+ @parser = XmppParser.new(&method(:receive_stanza))
32
+ end
33
+
34
+ ##
35
+ # Called when a full stanza has been received and returns it to the central router to be sent to the corresponding controller. Eventually it displays this data for debugging purposes
36
+ def receive_stanza(stanza)
37
+ puts "<< #{stanza}\n" if debug? # Low level Logging
38
+ # If not handled by subclass (for authentication)
39
+ CentralRouter.route self, stanza
40
+ end
41
+
42
+ ##
43
+ # Connection_completed is called when the connection (socket) has been established and is in charge of "building" the XML stream to establish the XMPP connection itself
44
+ # We use a "tweak" here to send only the starting tag of stream:stream
45
+ def connection_completed
46
+ super
47
+ builder = Nokogiri::XML::Builder.new {
48
+ self.send('stream:stream', 'xmlns' => "jabber:component:accept", 'xmlns:stream' => 'http://etherx.jabber.org/streams', 'to' => @context.config['jid']) {
49
+ paste_content_here # The stream:stream element should be cut here ;)
50
+ }
51
+ }
52
+ @start_stream, @stop_stream = builder.to_xml.split('<paste_content_here/>')
53
+ send_data(@start_stream)
54
+ end
55
+
56
+ ##
57
+ # Sends data (string) on the stream. Eventually it displays this data for debugging purposes
58
+ def send(xml)
59
+ puts ">> #{xml}\n" if debug? # Very low level Logging
60
+ send_data xml.to_s
61
+ end
62
+
63
+ private
64
+
65
+ ##
66
+ # receive_data is called when data is received. It is then passed to the parser.
67
+ def receive_data(data)
68
+ @parser.parse data
69
+ end
70
+
71
+ ##
72
+ # Pretty self-explanatory ;)
73
+ def debug?
74
+ @config["debug"]
75
+ end
76
+ end
77
+
78
+ ##
79
+ # This is the XML SAX Parser that accepts "pushed" content
80
+ class XmppParser < Nokogiri::XML::SAX::Document
81
+
82
+ ##
83
+ # Initialize the parser and adds the callback that will be called upen stanza completion
84
+ def initialize(&callback)
85
+ @callback = callback
86
+ super()
87
+ @parser = Nokogiri::XML::SAX::Parser.new(self)
88
+ @doc = nil
89
+ @elem = nil
90
+ end
91
+
92
+ ##
93
+ # Parses the received data
94
+ def parse(data)
95
+ @parser.parse data
96
+ end
97
+
98
+ ##
99
+ # Called when the document received in the stream is started
100
+ def start_document
101
+ @doc = Nokogiri::XML::Document.new
102
+ end
103
+
104
+ ##
105
+ # Adds characters to the current element (being parsed)
106
+ def characters(string)
107
+ @elem.add_child(Nokogiri::XML::Text.new(string, @doc))
108
+ end
109
+
110
+ ##
111
+ # Instantiate a new current Element, adds the corresponding attributes and namespaces
112
+ # The new element is eventually added to a parent element (if present).
113
+ # 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.
114
+ def start_element(qname, attributes = [])
115
+ e = Nokogiri::XML::Element.new(qname, @doc)
116
+ add_namespaces_and_attributes_to_node(attributes, e)
117
+
118
+ # If we don't have any elem yet, we are at the root
119
+ @elem = @elem ? @elem.add_child(e) : (@root = e)
120
+
121
+ if @elem.parent.nil?
122
+ # Should be called only for stream:stream
123
+ @doc.root = @elem
124
+ @callback.call(@elem)
125
+ end
126
+ end
127
+
128
+ ##
129
+ # Terminates the current element and calls the callback
130
+ def end_element(name)
131
+ if @elem
132
+ if @elem.parent == @root
133
+ @callback.call(@elem)
134
+ # And we also need to remove @elem from its tree
135
+ @elem.unlink
136
+ # And the current elem is the root
137
+ @elem = @root
138
+ else
139
+ @elem = @elem.parent
140
+ end
141
+ end
142
+ end
143
+
144
+ private
145
+
146
+ ##
147
+ # Adds namespaces and attributes. Nokogiri passes them as a array of [name, value, name, value]...
148
+ def add_namespaces_and_attributes_to_node(attrs, node)
149
+ (attrs.size / 2).times do |i|
150
+ name, value = attrs[2 * i], attrs[2 * i + 1]
151
+ if name =~ /xmlns/
152
+ node.add_namespace(name, value)
153
+ else
154
+ node.set_attribute name, value
155
+ end
156
+ end
157
+ end
158
+
159
+ end
160
+
161
+ end
@@ -0,0 +1,13 @@
1
+ = Babylon::Base::Controller
2
+
3
+ == Usage :
4
+
5
+ Please see Babylon rdoc.
6
+
7
+ == Example
8
+
9
+ class MyController < Babylon::Base::Controller
10
+ def my_action
11
+ // Do something great!
12
+ end
13
+ end
@@ -0,0 +1 @@
1
+ You can define you class models here. It is totally ok to reuse your ActiveRecord from another application!
@@ -0,0 +1,12 @@
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
@@ -0,0 +1,8 @@
1
+ require "rubygems"
2
+ require "babylon"
3
+
4
+ # Load the controllers
5
+ Dir.glob(File.join(File.dirname(__FILE__), '../app/controllers/*_controller.rb')).each {|f| require f }
6
+
7
+ # And start the App
8
+ Babylon::Runner::run()
@@ -0,0 +1,28 @@
1
+ # This contains the global configuration of your component.
2
+ # env:
3
+ # jid: your.component.jid
4
+ # password: your.component.password
5
+ # host: host on which the XMPP server is running
6
+ # port: port to which your component should connect
7
+ # debug: outputs the xmpp stanzas
8
+
9
+ development:
10
+ jid: component.server.com
11
+ password: password
12
+ host: localhost
13
+ port: 5278
14
+ debug: true
15
+
16
+ test:
17
+ jid: component.server.com
18
+ password: password
19
+ host: localhost
20
+ port: 5278
21
+ debug: false
22
+
23
+ production:
24
+ jid: component.server.com
25
+ password: password
26
+ host: localhost
27
+ port: 5278
28
+ debug: false
@@ -0,0 +1,15 @@
1
+ # This determines the routing for your controllers
2
+ # The macthing is based on XPATH
3
+
4
+ # route_name:
5
+ # priority: if a stanza matches several XPath conditions, the one with the greater priority will be executed. If they have the same priority, one will be chose randomly, so choose your priority very carefully! It is a good practice to attribute a different priority to each of your routes, so that there is no conflict
6
+ # controller: name of the controller that should handle the stanza
7
+ # action: action to be called to handle the stanza
8
+ # xpath: used to macth the stanza
9
+
10
+ # my_route_1:
11
+ # priority: 1
12
+ # controller: main
13
+ # xpath: "//message"
14
+ # action: echo
15
+
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env ruby
2
+ require File.dirname(__FILE__) + '/../config/boot'
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ ##
4
+ # This is a generator that will build scaffold controller and add the corresponding routes
5
+ #
6
+ # == Usage
7
+ #
8
+ # $> scripts/generate controller_name [action_name:priority;Xpath, ...]
9
+ #
10
+ # == Example
11
+ #
12
+ # $> scripts/generate message echo:10:"//message/body" reverse:0:"//message"
13
+ #
14
+ # This will generate a an echo controller with 2 actions : echo and reverse. Echo will be called for stanza of type message witch a body than contains "echo", while reverse will be called for any other stanza of type message.
15
+
16
+
17
+ # Create the views subdirectory
18
+ Dir.mkdir "app/views/#{ARGV[0]}" if !File.exists?("app/views/#{ARGV[0]}")
19
+ # CReate the controller file and write the first lines
20
+ controller_file = File.open("app/controllers/#{ARGV[0]}_controller.rb", "w+")
21
+ route_file = File.open("config/routes.yaml", "a")
22
+ controller_file.puts "class #{ARGV[0].capitalize}Controller < Babylon::Base::Controller"
23
+ controller_file.puts ""
24
+ ARGV[1..-1].each do |action|
25
+ action_name, priority, xpath = action.split(":")
26
+ # Add the action to the controller
27
+ controller_file.puts ""
28
+ controller_file.puts " def #{action_name}"
29
+ controller_file.puts " # Called when the stanza matches #{xpath}. Priority #{priority}"
30
+ controller_file.puts " "
31
+ controller_file.puts " end"
32
+ # Create the file views
33
+ view_file = File.open("app/views/#{ARGV[0]}/#{action_name}.xml.builder", "w+")
34
+ view_file.puts "self.message(:to => to, :from => from, :type => :chat) do"
35
+ view_file.puts " self.body(content) # Same as self.send(:body, body) "
36
+ view_file.puts "end"
37
+ view_file.close
38
+ # And now add the route (we must be careful and not delete other routes)
39
+ route_file.puts ""
40
+ route_file.puts "#{ARGV[0]}_#{action_name}_route:"
41
+ route_file.puts " priority: #{priority}"
42
+ route_file.puts " controller: #{ARGV[0]}"
43
+ route_file.puts " xpath: #{xpath}"
44
+ route_file.puts " action: #{action_name}"
45
+ end
46
+ controller_file.puts "end"
47
+
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: julien51-babylon
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
+ platform: ruby
6
+ authors:
7
+ - Julien Genestoux
8
+ - Astro
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2009-02-13 00:00:00 -08:00
14
+ default_executable:
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: nokogiri
18
+ type: :runtime
19
+ version_requirement:
20
+ version_requirements: !ruby/object:Gem::Requirement
21
+ requirements:
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: "0"
25
+ version:
26
+ - !ruby/object:Gem::Dependency
27
+ name: eventmachine
28
+ type: :runtime
29
+ version_requirement:
30
+ version_requirements: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ version:
36
+ description: Babylon is a framework to create EventMachine based XMPP External Components in Ruby.
37
+ email: babylon@notifixio.us
38
+ executables:
39
+ - babylon
40
+ extensions: []
41
+
42
+ extra_rdoc_files: []
43
+
44
+ files:
45
+ - README.rdoc
46
+ - lib/babylon.rb
47
+ - lib/babylon/base/controller.rb
48
+ - lib/babylon/base/view.rb
49
+ - lib/babylon/component_connection.rb
50
+ - lib/babylon/router.rb
51
+ - lib/babylon/runner.rb
52
+ - lib/babylon/xmpp_connection.rb
53
+ - bin/babylon
54
+ - spec
55
+ - templates
56
+ - templates/babylon
57
+ - templates/babylon/app
58
+ - templates/babylon/app/controllers/README.rdoc
59
+ - templates/babylon/app/models/README.rdoc
60
+ - templates/babylon/app/views/README.rdoc
61
+ - templates/babylon/config
62
+ - templates/babylon/config/routes.yaml
63
+ - templates/babylon/config/config.yaml
64
+ - templates/babylon/config/boot.rb
65
+ - templates/babylon/scripts
66
+ - templates/babylon/scripts/component
67
+ - templates/babylon/scripts/generate
68
+ has_rdoc: true
69
+ homepage: http://github.com/julien51/babylon/
70
+ post_install_message:
71
+ rdoc_options: []
72
+
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: "0"
80
+ version:
81
+ required_rubygems_version: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ version: "0"
86
+ version:
87
+ requirements: []
88
+
89
+ rubyforge_project:
90
+ rubygems_version: 1.2.0
91
+ signing_key:
92
+ specification_version: 2
93
+ summary: Babylon is a framework to create EventMachine based XMPP External Components in Ruby.
94
+ test_files: []
95
+