require 'rbbt/util/misc'
require 'rbbt/rest/common/cache'
require 'tilt'
Tilt::SYMBOL_ARRAY_SORTABLE = false
module RbbtRESTHelpers
def error_for(job, layout = nil)
if ex = job.info[:exception]
klass = ex[:class]
msg = ex[:message]
bkt = ex[:backtrace]
elsif job.dirty?
klass = "Exception"
msg = "Job dirty"
bkt = []
else
klass = "Exception"
msg = job.messages[-1]
bkt = []
end
code = klass.to_s == "ParameterException" ? 400 : 500
case @format
when :json
halt code, {"message" => msg, "backtrace" => bkt}.to_json
when :html
layout = @layout if layout.nil?
layout_file = (layout ? locate_template('layout') : nil)
template_file = locate_template('error')
reset_js_css
result = render template_file, {:job => job}, layout_file
content_type :html
halt code, result
else
content_type :text
halt code, "#{klass}: " << msg << "\nBacktrace: " << bkt * "\n"
end
end
def wait_on(job, layout = nil)
layout = @layout if layout.nil?
3.times do |rep|
raise RbbtRESTHelpers::Retry if job.done? or job.error?
sleep 1
end if layout
raise RbbtRESTHelpers::Retry if job.done? or job.error?
layout_file = (layout ? locate_template('layout') : nil)
template_file = locate_template('wait')
status 202
render template_file, {:job => job}, layout_file
end
def render(template_file, locals = {}, layout_file = nil, cache = nil, cache_options = {})
raise TemplateMissing, "Template #{ template_file } not found" unless template_file.exists?
raise TemplateMissing, "Template #{ layout_file } not found" unless layout_file.nil? or layout_file.exists?
layout_file = layout_file.find if layout_file.respond_to? :find
if Path === template_file
documentation_file = template_file.annotate((template_file.original || template_file).sub(/haml$/, 'md'))
template_file = template_file.find
documentation_file = documentation_file.find
else
documentation_file = template_file.sub(/haml$/, 'md')
end
if layout_file
Tilt::HamlTemplate.new(layout_file, :filename => layout_file).render(self, locals) do
Log.debug{ "Rendering #{template_file} with layout #{Misc.fingerprint cache_options}" }
cache(cache, locals.merge(:_template_file => template_file, :user => user).merge(cache_options)) do
if locals[:result] == :load && Step === locals[:job]
res = locals[:job].load
locals[:result] = res
end
if Open.exists?(documentation_file)
documentation_layout_file = locate_template('documented_section').find
markdown = Open.read(documentation_file)
Tilt::HamlTemplate.new(documentation_layout_file, :filename => documentation_layout_file).render(self, :markdown => markdown) do
Tilt::HamlTemplate.new(template_file, :filename => template_file).render(self, locals)
end
else
Tilt::HamlTemplate.new(template_file, :filename => template_file).render(self, locals)
end
end
end
else
Log.debug{ "Rendering #{template_file} without layout #{Misc.fingerprint cache_options}" }
cache(cache, locals.merge(:_template_file => template_file, :user => user).merge(cache_options)) do
if locals[:result] == :load && Step === locals[:job]
res = locals[:job].load
locals[:result] = res
end
if Open.exists?(documentation_file)
markdown = Open.read(documentation_file)
documentation_layout_file = locate_template('documented_section').find
Tilt::HamlTemplate.new(documentation_layout_file, :filename => documentation_layout_file).render(self, :markdown => markdown) do
Tilt::HamlTemplate.new(template_file, :filename => template_file).render(self, locals)
end
else
Tilt::HamlTemplate.new(template_file, :filename => template_file).render(self, locals)
end
end
end
end
def render_sass(file)
renderer = SassC::Engine.new(Open.read(file), :filename => file, :syntax => :sass,
:style => production? ? :compressed : :nested, :include_paths => RbbtRESTHelpers.sass_resources * ":",
:debug_info => development? ? true : false)
renderer.render
end
def render_partial(template_file, locals = {}, cache = nil, cache_options = {})
render(template_file, locals, nil, cache, cache_options)
end
def template_render(template, locals = {}, cache = nil, cache_options = {})
template_file = locate_template(template)
layout_file = @layout ? locate_template("layout") : nil
render(template_file, locals, layout_file, cache, cache_options)
end
def partial_render(template, locals = {}, cache = nil, cache_options = {})
template_file = locate_template(template)
render(template_file, locals, nil, cache, cache_options)
end
def fragment(link = nil, &block)
fragment_code, link = [link.to_s, nil] if link and not link.to_s[0] == '<'
text = fragment_code if fragment_code
if block_given?
if defined? @step and (@cache_type == :asynchronous or @cache_type == :async)
fragment_code ||= (rand * 100000).to_i.to_s
fragment_file = @step.file(fragment_code)
pid_file = fragment_file + '.pid'
pid = @step.child{
begin
class << @step
def status=(message)
nil
end
end
Log.low("Fragment started: #{ fragment_file } - #{Process.pid}")
#res = capture_haml fragment_code, &block
res = $haml_6 ? capture(&block) : capture_haml(&block)
Log.low("Fragment writing: #{ fragment_file } - #{Process.pid}")
Open.write(fragment_file, res)
Log.low("Fragment done: #{ fragment_file } - #{Process.pid}")
rescue Exception
Open.write(fragment_file + '.error', [$!.class.to_s, $!.message] * ": ")
Open.write(fragment_file + '.backtrace', $!.backtrace * "\n") if $!.backtrace
Log.error("Error in fragment: #{ fragment_file }")
Log.exception $!
Open.rm pid_file if Open.exists? pid_file
Kernel.exit! -1
ensure
Open.rm pid_file if Open.exists? pid_file
end
Kernel.exit! 0
}
Open.write(pid_file, pid.to_s)
url = @fullpath
url = remove_GET_param(url, "_update")
url = remove_GET_param(url, "_")
fragment_url = add_GET_param(url, "_fragment", fragment_code)
if link.nil?
html_tag('a', "", :href => fragment_url, :class => 'fragment', "data-text" => text)
else
if FalseClass === link
return fragment_code
elsif TrueClass === link
return fragment_url
elsif link =~ / href=/
link = link.sub(/ href=('|")/," href='#{fragment_url}'")
else
link = link.sub(/"
when :link
"#{ text }"
when :linked_image
""
when :zoomable_image
id = options[:id] || Misc.digest(filename)
width, height= [600, 600]
"