radamanthus-skates 0.3.5
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.rdoc +113 -0
- data/Rakefile +142 -0
- data/bin/skates +8 -0
- data/lib/skates.rb +154 -0
- data/lib/skates/base/controller.rb +116 -0
- data/lib/skates/base/stanza.rb +44 -0
- data/lib/skates/base/view.rb +59 -0
- data/lib/skates/client_connection.rb +234 -0
- data/lib/skates/component_connection.rb +114 -0
- data/lib/skates/ext/array.rb +21 -0
- data/lib/skates/generator.rb +142 -0
- data/lib/skates/router.rb +123 -0
- data/lib/skates/router/dsl.rb +48 -0
- data/lib/skates/runner.rb +164 -0
- data/lib/skates/xmpp_connection.rb +216 -0
- data/lib/skates/xmpp_parser.rb +112 -0
- data/spec/bin/skates_spec.rb +0 -0
- data/spec/em_mock.rb +42 -0
- data/spec/lib/skates/base/controller_spec.rb +205 -0
- data/spec/lib/skates/base/stanza_spec.rb +120 -0
- data/spec/lib/skates/base/view_spec.rb +105 -0
- data/spec/lib/skates/client_connection_spec.rb +309 -0
- data/spec/lib/skates/component_connection_spec.rb +144 -0
- data/spec/lib/skates/generator_spec.rb +10 -0
- data/spec/lib/skates/router/dsl_spec.rb +46 -0
- data/spec/lib/skates/router_spec.rb +252 -0
- data/spec/lib/skates/runner_spec.rb +233 -0
- data/spec/lib/skates/xmpp_connection_spec.rb +222 -0
- data/spec/lib/skates/xmpp_parser_spec.rb +283 -0
- data/spec/spec.opts +2 -0
- data/spec/spec_helper.rb +37 -0
- data/test/skates_test.rb +7 -0
- data/test/test_helper.rb +10 -0
- metadata +125 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 julien
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
= Skates
|
2
|
+
|
3
|
+
== DESCRIPTION:
|
4
|
+
|
5
|
+
Skates is a framework to build XMPP Applications in Ruby. The framework uses EventMachine to handle network connections.
|
6
|
+
|
7
|
+
This framework can use both an XMPP Component (XEP-0114) and an XMPP Client (and XMPP Servers should come soon). However, we strongly discourage any production application using a regular client.
|
8
|
+
|
9
|
+
== FEATURES/PROBLEMS:
|
10
|
+
|
11
|
+
Please link "report/request here.":http://github.com/julien51/skates/issues
|
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
|
+
|
15
|
+
== ROADMAP :
|
16
|
+
|
17
|
+
- Implement the ServerConnection for S2S
|
18
|
+
- Implement templates for disco-info... and common XEPs
|
19
|
+
- Delete route priorities? And rely on the order only? (As Rails does)
|
20
|
+
- Review doc
|
21
|
+
- Write tests
|
22
|
+
- Evangelize!
|
23
|
+
|
24
|
+
You can help with at least one of these points, don't turn your back on Skates!
|
25
|
+
|
26
|
+
== DOCUMENTATION :
|
27
|
+
|
28
|
+
You can find it on our "Rubyforge page":http://skates.rubyforge.org/
|
29
|
+
Feel free to fork the "github":http://github.com/julien51/skates/tree/master repo and add some documentation if you think anything is missing.
|
30
|
+
|
31
|
+
__You can't be a bad coder, a bad tester and a bad documenter at the same time ;)__
|
32
|
+
|
33
|
+
== SYNOPSIS :
|
34
|
+
|
35
|
+
You can build applications directly with Skates, or you can use the Skates::ClientConnection and Skates::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.
|
36
|
+
|
37
|
+
=== To create an Application with Skates:
|
38
|
+
|
39
|
+
1. Install the gem
|
40
|
+
2. The app contains a generator that will "build" a scaffold for your application.
|
41
|
+
|
42
|
+
$> skates application __myapp__
|
43
|
+
|
44
|
+
3. Use the generator or write your own controllers :
|
45
|
+
|
46
|
+
$> skates controller __messages__ __echo__:__10__:__//stream:message[@type='chat']/body__,__subscribed__:__0__:__//stream:presence[@type='subscribe']__
|
47
|
+
|
48
|
+
This will generate a __MessagesController__ class with 2 methods : __echo__ and __subscribed__.
|
49
|
+
- "echo" will be called when the component receives message stanzas of type 'chat',
|
50
|
+
- "subscribed" will be called for presence stanzas of type 'subscribe'.
|
51
|
+
10 and 0 are the priority : useful when a stanza matches 2 XPath.
|
52
|
+
|
53
|
+
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__
|
54
|
+
By implementing 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.
|
55
|
+
|
56
|
+
This will also generate 2 'views' used to build your responses stanzas.
|
57
|
+
|
58
|
+
And finally, this will write 2 routes in the config/routes.rb
|
59
|
+
|
60
|
+
4. Customize your controllers, stanzas and views!
|
61
|
+
|
62
|
+
5. Make sure that the XMPP settings are correct in config/config.yaml.
|
63
|
+
|
64
|
+
6. And finally start the component :
|
65
|
+
|
66
|
+
script/component
|
67
|
+
|
68
|
+
7. We running in production, you may run the script/component too, but with something like runit to deamonize the process.
|
69
|
+
|
70
|
+
=== To use the Connection Classes only (Client or Component), you can just call the following :
|
71
|
+
|
72
|
+
Skates::ClientConnection.connect(params, handler)
|
73
|
+
or,
|
74
|
+
Skates::ComponentConnection.connect(params, handler)
|
75
|
+
|
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:
|
77
|
+
|
78
|
+
on_connected(connection), on_disconnected and on_stanza(stanza)
|
79
|
+
|
80
|
+
== ADDITIONAL INFORMATION :
|
81
|
+
|
82
|
+
Feel free to pull, branch, improve and commit the {code|specs|tests|docs} : we will merge it if it's a step ahead!
|
83
|
+
|
84
|
+
Skates's edge versions are located at Github : http://github.com/julien51/skates/tree/master
|
85
|
+
|
86
|
+
== REQUIREMENTS :
|
87
|
+
|
88
|
+
Gems : Eventmachine, nokogiri, YAML, log4r, templater
|
89
|
+
|
90
|
+
== LICENSE:
|
91
|
+
|
92
|
+
(The MIT License)
|
93
|
+
|
94
|
+
Copyright (c) 2009 Julien Genestoux http://notifixio.us
|
95
|
+
|
96
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
97
|
+
a copy of this software and associated documentation files (the
|
98
|
+
'Software'), to deal in the Software without restriction, including
|
99
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
100
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
101
|
+
permit persons to whom the Software is furnished to do so, subject to
|
102
|
+
the following conditions:
|
103
|
+
|
104
|
+
The above copyright notice and this permission notice shall be
|
105
|
+
included in all copies or substantial portions of the Software.
|
106
|
+
|
107
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
108
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
109
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
110
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
111
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
112
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
113
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "skates"
|
8
|
+
gem.summary = %Q{Skates is a framework to create EventMachine based XMPP External Components in Ruby.}
|
9
|
+
gem.email = "julien.genestoux@gmail.com"
|
10
|
+
gem.homepage = "http://github.com/julien51/skates"
|
11
|
+
gem.authors = ["julien Genestoux"]
|
12
|
+
|
13
|
+
gem.add_dependency('eventmachine', ">= 0.12.10")
|
14
|
+
gem.add_dependency('log4r')
|
15
|
+
gem.add_dependency('nokogiri', "= 1.4.2")
|
16
|
+
gem.add_dependency('utf8cleaner')
|
17
|
+
gem.requirements = ["eventmachine", "yaml", "fileutils", "log4r", "nokogiri", "optparse", "digest/sha1", "base64", "resolv", "utf8cleaner"]
|
18
|
+
gem.executables = "skates"
|
19
|
+
gem.files = [ "bin/skates",
|
20
|
+
"lib/skates.rb",
|
21
|
+
"lib/skates/ext/array.rb",
|
22
|
+
"lib/skates/base/controller.rb",
|
23
|
+
"lib/skates/base/view.rb",
|
24
|
+
"lib/skates/base/stanza.rb",
|
25
|
+
"lib/skates/client_connection.rb",
|
26
|
+
"lib/skates/component_connection.rb",
|
27
|
+
"lib/skates/router/dsl.rb",
|
28
|
+
"lib/skates/router.rb",
|
29
|
+
"lib/skates/runner.rb",
|
30
|
+
"lib/skates/generator.rb",
|
31
|
+
"lib/skates/xmpp_connection.rb",
|
32
|
+
"lib/skates/xmpp_parser.rb",
|
33
|
+
"LICENSE",
|
34
|
+
"Rakefile",
|
35
|
+
"README.rdoc",
|
36
|
+
"templates/skates/app/controllers/controller.rb",
|
37
|
+
"templates/skates/app/views/view.rb",
|
38
|
+
"templates/skates/app/stanzas/stanza.rb",
|
39
|
+
"templates/skates/config/boot.rb",
|
40
|
+
"templates/skates/config/config.yaml",
|
41
|
+
"templates/skates/config/dependencies.rb",
|
42
|
+
"templates/skates/config/routes.rb",
|
43
|
+
"templates/skates/script/component",
|
44
|
+
"templates/skates/log/test.log",
|
45
|
+
"templates/skates/log/development.log",
|
46
|
+
"templates/skates/log/production.log",
|
47
|
+
"templates/skates/tmp/pids/README"
|
48
|
+
]
|
49
|
+
gem.rubyforge_project = 'skates'
|
50
|
+
end
|
51
|
+
rescue LoadError
|
52
|
+
puts "Jeweler not available. Install it with: sudo gem jeweler"
|
53
|
+
end
|
54
|
+
|
55
|
+
require 'rake/rdoctask'
|
56
|
+
Rake::RDocTask.new do |rdoc|
|
57
|
+
rdoc.rdoc_dir = 'rdoc'
|
58
|
+
rdoc.title = 'Skates : a framework to create EventMachine based XMPP External Components in Ruby.'
|
59
|
+
rdoc.rdoc_files.include('README*')
|
60
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
61
|
+
rdoc.options << '--line-numbers'
|
62
|
+
end
|
63
|
+
|
64
|
+
require 'rake/testtask'
|
65
|
+
Rake::TestTask.new(:test) do |test|
|
66
|
+
test.libs << 'lib' << 'test'
|
67
|
+
test.pattern = 'test/**/*_test.rb'
|
68
|
+
test.verbose = false
|
69
|
+
end
|
70
|
+
|
71
|
+
begin
|
72
|
+
require 'rcov/rcovtask'
|
73
|
+
Rcov::RcovTask.new do |test|
|
74
|
+
test.libs << 'test'
|
75
|
+
test.pattern = 'test/**/*_test.rb'
|
76
|
+
test.verbose = true
|
77
|
+
end
|
78
|
+
rescue LoadError
|
79
|
+
task :rcov do
|
80
|
+
abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
begin
|
85
|
+
require 'spec/rake/spectask'
|
86
|
+
desc "Run all Spec"
|
87
|
+
Spec::Rake::SpecTask.new('spec') do |spec|
|
88
|
+
spec.spec_files = FileList['spec/**/*.rb']
|
89
|
+
spec.verbose = true
|
90
|
+
spec.warning = false
|
91
|
+
spec.rcov = true
|
92
|
+
end
|
93
|
+
rescue LoadError
|
94
|
+
task :spec do
|
95
|
+
abort "Rspec is not available. In order to run rspec, you must: sudo gem install rspec"
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
begin
|
100
|
+
require 'spec/rake/verify_rcov'
|
101
|
+
|
102
|
+
RCov::VerifyTask.new(:verify_rcov => 'spec') do |t|
|
103
|
+
t.threshold = 100.0
|
104
|
+
t.index_html = 'coverage/index.html'
|
105
|
+
end
|
106
|
+
rescue LoadError
|
107
|
+
task :spec do
|
108
|
+
abort "Rcov is not available. In order to run rcov, you must: sudo gem install rcov"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
# These are Rubyforge tasks
|
113
|
+
begin
|
114
|
+
require 'rake/contrib/sshpublisher'
|
115
|
+
namespace :rubyforge do
|
116
|
+
|
117
|
+
desc "Release gem and RDoc documentation to RubyForge"
|
118
|
+
task :release => ["rubyforge:release:gem", "rubyforge:release:docs"]
|
119
|
+
|
120
|
+
namespace :release do
|
121
|
+
desc "Publish RDoc to RubyForge."
|
122
|
+
task :docs => [:rdoc] do
|
123
|
+
config = YAML.load(
|
124
|
+
File.read(File.expand_path('~/.rubyforge/user-config.yml'))
|
125
|
+
)
|
126
|
+
|
127
|
+
host = "#{config['username']}@rubyforge.org"
|
128
|
+
remote_dir = "/var/www/gforge-projects/skates"
|
129
|
+
local_dir = 'rdoc'
|
130
|
+
|
131
|
+
Rake::SshDirPublisher.new(host, remote_dir, local_dir).upload
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
rescue LoadError
|
136
|
+
puts "Rake SshDirPublisher is unavailable or your rubyforge environment is not configured."
|
137
|
+
end
|
138
|
+
|
139
|
+
|
140
|
+
task :install => :build
|
141
|
+
|
142
|
+
task :default => :test
|
data/bin/skates
ADDED
data/lib/skates.rb
ADDED
@@ -0,0 +1,154 @@
|
|
1
|
+
$:.unshift(File.dirname(__FILE__)) unless
|
2
|
+
$:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
|
3
|
+
|
4
|
+
require 'eventmachine'
|
5
|
+
require 'log4r'
|
6
|
+
require 'nokogiri'
|
7
|
+
require 'yaml'
|
8
|
+
require 'fileutils'
|
9
|
+
require 'digest/sha1'
|
10
|
+
require 'base64'
|
11
|
+
require 'resolv'
|
12
|
+
require 'cgi'
|
13
|
+
require 'utf8cleaner'
|
14
|
+
require 'pathname'
|
15
|
+
|
16
|
+
require 'skates/ext/array.rb'
|
17
|
+
require 'skates/xmpp_connection'
|
18
|
+
require 'skates/xmpp_parser'
|
19
|
+
require 'skates/component_connection'
|
20
|
+
require 'skates/client_connection'
|
21
|
+
require 'skates/router'
|
22
|
+
require 'skates/runner'
|
23
|
+
require 'skates/base/controller'
|
24
|
+
require 'skates/base/view'
|
25
|
+
require 'skates/base/stanza'
|
26
|
+
|
27
|
+
# Skates is a XMPP Component Framework based on EventMachine. It uses the Nokogiri GEM, which is a Ruby wrapper for Libxml2.
|
28
|
+
# It implements the MVC paradigm.
|
29
|
+
# You can create your own application by running :
|
30
|
+
# $> skates app_name
|
31
|
+
# This will generate some folders and files for your application. Please see README.rdoc for further instructions
|
32
|
+
|
33
|
+
module Skates
|
34
|
+
|
35
|
+
@@config_file = nil
|
36
|
+
|
37
|
+
def self.environment=(_env)
|
38
|
+
@@env = _env
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.environment
|
42
|
+
unless self.class_variable_defined?("@@env")
|
43
|
+
@@env = "development"
|
44
|
+
end
|
45
|
+
@@env
|
46
|
+
end
|
47
|
+
|
48
|
+
##
|
49
|
+
# Sets up the router
|
50
|
+
def self.router=(router)
|
51
|
+
@@router = router
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# Retruns the router
|
56
|
+
def self.router
|
57
|
+
unless self.class_variable_defined?("@@router")
|
58
|
+
@@router = nil
|
59
|
+
end
|
60
|
+
@@router
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# Caches the view files to improve performance.
|
65
|
+
def self.cache_views
|
66
|
+
@@views= {}
|
67
|
+
Dir.glob('app/views/*/*').each do |f|
|
68
|
+
@@views[f] = File.read(f)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.views
|
73
|
+
unless self.class_variable_defined?("@@views")
|
74
|
+
@@views= {}
|
75
|
+
end
|
76
|
+
@@views
|
77
|
+
end
|
78
|
+
|
79
|
+
##
|
80
|
+
# Returns a shared logger for this component.
|
81
|
+
def self.logger
|
82
|
+
unless self.class_variable_defined?("@@logger")
|
83
|
+
reopen_logs
|
84
|
+
end
|
85
|
+
@@logger
|
86
|
+
end
|
87
|
+
|
88
|
+
##
|
89
|
+
# Returns the log directory
|
90
|
+
def self.log_dir
|
91
|
+
unless self.class_variable_defined?("@@log_dir")
|
92
|
+
@@log_dir = "log"
|
93
|
+
end
|
94
|
+
@@log_dir
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.log_dir=(log_dir)
|
98
|
+
@@log_dir = log_dir
|
99
|
+
reopen_logs
|
100
|
+
end
|
101
|
+
|
102
|
+
##
|
103
|
+
# Re-opens the logs
|
104
|
+
# In "development" environment, the log will be on stdout
|
105
|
+
def self.reopen_logs
|
106
|
+
# Open a new logger
|
107
|
+
logger = Log4r::Logger.new("")
|
108
|
+
logger.add(Log4r::Outputter.stdout) if Skates.environment == "development"
|
109
|
+
log_file = Log4r::RollingFileOutputter.new("#{Skates.environment}", :filename => "#{Skates.log_dir}/#{Skates.environment}.log", :trunc => false)
|
110
|
+
case Skates.environment
|
111
|
+
when "production"
|
112
|
+
log_file.formatter = Log4r::PatternFormatter.new(:pattern => "%d (#{Process.pid}) [%l] :: %m #{Skates.router.nil? ? "" : (Skates.router.connection.nil? ? "" : "(" + Skates.router.connection.jid + ")") }", :date_pattern => "%d/%m %H:%M")
|
113
|
+
when "development"
|
114
|
+
log_file.formatter = Log4r::PatternFormatter.new(:pattern => "%d (#{Process.pid}) [%l] :: %m #{Skates.router.nil? ? "" : (Skates.router.connection.nil? ? "" : "(" + Skates.router.connection.jid + ")") }", :date_pattern => "%d/%m %H:%M")
|
115
|
+
else
|
116
|
+
log_file.formatter = Log4r::PatternFormatter.new(:pattern => "%d (#{Process.pid}) [%l] :: %m #{Skates.router.nil? ? "" : (Skates.router.connection.nil? ? "" : "(" + Skates.router.connection.jid + ")") }", :date_pattern => "%d/%m %H:%M")
|
117
|
+
end
|
118
|
+
logger.add(log_file)
|
119
|
+
# Set up the variable.
|
120
|
+
@@logger = logger
|
121
|
+
end
|
122
|
+
|
123
|
+
##
|
124
|
+
# Set the configuration file for this component.
|
125
|
+
def self.config_file=(file)
|
126
|
+
@@config_file = file
|
127
|
+
end
|
128
|
+
|
129
|
+
##
|
130
|
+
# Return the configuration file for this component.
|
131
|
+
def self.config_file
|
132
|
+
@@config_file
|
133
|
+
end
|
134
|
+
|
135
|
+
##
|
136
|
+
# Set the configuration for this component.
|
137
|
+
def self.config=(conf)
|
138
|
+
@@config = conf
|
139
|
+
end
|
140
|
+
|
141
|
+
##
|
142
|
+
# Return the configuration for this component.
|
143
|
+
def self.config
|
144
|
+
@@config
|
145
|
+
end
|
146
|
+
|
147
|
+
##
|
148
|
+
# Decodes XML special characters.
|
149
|
+
def self.decode_xml(str)
|
150
|
+
CGI.unescapeHTML(str)
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
@@ -0,0 +1,116 @@
|
|
1
|
+
module Skates
|
2
|
+
module Base
|
3
|
+
|
4
|
+
##
|
5
|
+
# Your application's controller should be descendant of this class.
|
6
|
+
class Controller
|
7
|
+
|
8
|
+
attr_accessor :stanza, :rendered, :action_name # Stanza received by the controller (Nokogiri::XML::Node)
|
9
|
+
|
10
|
+
##
|
11
|
+
# Creates a new controller (you should not override this class) and assigns the stanza as well as any other value of the hash to instances named after the keys of the hash.
|
12
|
+
def initialize(stanza = nil)
|
13
|
+
@stanza = stanza
|
14
|
+
@view = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# Performs the action and calls back the optional block argument : you should not override this function
|
19
|
+
def perform(action)
|
20
|
+
@action_name = action
|
21
|
+
begin
|
22
|
+
self.send(@action_name)
|
23
|
+
rescue
|
24
|
+
Skates.logger.error {
|
25
|
+
"#{$!}:\n#{$!.backtrace.join("\n")}"
|
26
|
+
}
|
27
|
+
end
|
28
|
+
self.render
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# Returns the list of variables assigned during the action.
|
33
|
+
def assigns
|
34
|
+
vars = Hash.new
|
35
|
+
instance_variables.each do |var|
|
36
|
+
if !["@view", "@action_name", "@block"].include? var
|
37
|
+
vars[var[1..-1]] = instance_variable_get(var)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
vars
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Called by default after each action to "build" a XMPP stanza. By default, it will use the /controller_name/action.xml.builder
|
45
|
+
# You can use the following options :
|
46
|
+
# - :file : render a specific file (can be in a different controller)
|
47
|
+
# - :action : render another action of the current controller
|
48
|
+
# - :nothing : doesn't render anything
|
49
|
+
def render(options = {})
|
50
|
+
return if @view and !options[:force] # Avoid double rendering, if we have already attached a view
|
51
|
+
|
52
|
+
if options == {} # default rendering
|
53
|
+
render(:file => default_template_name)
|
54
|
+
|
55
|
+
elsif action_name = options[:action]
|
56
|
+
result = render(:file => default_template_name(action_name.to_s))
|
57
|
+
|
58
|
+
elsif options[:file]
|
59
|
+
file = options[:file]
|
60
|
+
if file =~ /^\// # Render from view root
|
61
|
+
@view = render_for_file(File.join("app", "views", "#{file}.xml.builder"))
|
62
|
+
else
|
63
|
+
@view = render_for_file(view_path(file))
|
64
|
+
end
|
65
|
+
|
66
|
+
elsif options[:nothing]
|
67
|
+
@view = Skates::Base::View.new()
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
##
|
72
|
+
# Actually evaluates the view
|
73
|
+
def evaluate
|
74
|
+
@view.evaluate if @view
|
75
|
+
end
|
76
|
+
|
77
|
+
##
|
78
|
+
# Render and evaluate a given view
|
79
|
+
def render_and_evaluate(options = {})
|
80
|
+
render(options)
|
81
|
+
evaluate
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# Renders, evaluate and sends
|
86
|
+
def render_evaluate_and_send(options)
|
87
|
+
response = render_and_evaluate(options)
|
88
|
+
Skates.router.connection.send_xml response
|
89
|
+
end
|
90
|
+
|
91
|
+
protected
|
92
|
+
|
93
|
+
##
|
94
|
+
# Builds the view path.
|
95
|
+
def view_path(file_name)
|
96
|
+
File.join("app", "views", "#{self.class.name.gsub("Controller","").downcase}", file_name)
|
97
|
+
end
|
98
|
+
|
99
|
+
##
|
100
|
+
# Default template name used to build stanzas
|
101
|
+
def default_template_name(action_name = nil)
|
102
|
+
"#{action_name || @action_name}.xml.builder"
|
103
|
+
end
|
104
|
+
|
105
|
+
##
|
106
|
+
# Creates the view and "evaluates" it to build the XML for the stanza
|
107
|
+
def render_for_file(file)
|
108
|
+
Skates.logger.info {
|
109
|
+
"RENDERING : #{file}"
|
110
|
+
}
|
111
|
+
Skates::Base::View.new(file, assigns)
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|