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] 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) 3.times do raise RbbtRESTHelpers::Retry if job.done? or job.error? sleep 1 end raise RbbtRESTHelpers::Retry if job.done? or job.error? layout = @layout if layout.nil? 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 template_file = template_file.find if template_file.respond_to? :find if layout_file Tilt::HamlTemplate.new(layout_file, :filename => layout_file, :ugly => production?).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 Tilt::HamlTemplate.new(template_file, :filename => template_file, :ugly => production?).render(self, locals) 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 Tilt::HamlTemplate.new(template_file, :filename => template_file, :ugly => production?).render(self, locals) end end end def render_sass(file) renderer = Sass::Engine.new(Open.read(file), :filename => file, :style => production? ? :compressed : nil, :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 Log.low("Fragment started: #{ fragment_file } - #{Process.pid}") res = capture_haml fragment_code, &block 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 $! FileUtils.rm pid_file if File.exists? pid_file Kernel.exit! -1 ensure FileUtils.rm pid_file if File.exists? pid_file end Kernel.exit! 0 } Open.write(pid_file, pid.to_s) url = request.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] "
" when :mapped_image mapid = options[:mapid] || options[:id] + '_map' width, height= [300, 300] mapfile = f.sub(/\.[^.]+$/, '.html') "
#{Open.read(mapfile)}
" else raise "Type not understood: #{ type }" end end def reveal(text, id = nil, options = nil, &block) id ||= "rbbt_reveal_" << (rand * 10000).to_i.to_s content_html = capture_haml(&block) options = {} if options.nil? options = {:href => "#", "data-reveal-id" => 'modal1', 'attr-reveal_id' => id}.merge(options) options[:class] ||= '' options[:class] << ' rbbt_reveal_trigger' str = html_tag('a', text.to_s, options) << "\n" << html_tag('div', "\n" << content_html << "\n", :id => id, 'class' => 'rbbt_reveal_content') << "\n" str end end