module RbbtRESTHelpers

Constants

MEMORY_CACHE
PAGE_SIZE

Attributes

javascript_resources[RW]
plugin_resources[RW]
sass_resources[RW]
template_resources[RW]

Public Class Methods

add_sass_load_path(path) click to toggle source

{{{ SASS

# File lib/rbbt/rest/common/locate.rb, line 80
def self.add_sass_load_path(path)
  sass_resources.unshift path
  sass_resources.uniq!
end
css_resources() click to toggle source

{{{ CSS

# File lib/rbbt/rest/common/locate.rb, line 117
def self.css_resources
  @css_resources ||= [Rbbt.share.views.public.find(:lib), Rbbt.share.views.public.css.find(:lib), Rbbt.share.views.public.plugins.find(:lib)]
end
file_resources() click to toggle source

{{{ FILE

# File lib/rbbt/rest/common/locate.rb, line 56
def self.file_resources
  @file_resources ||= template_resources
end
javascript_resources() click to toggle source

{{{ JAVASCRIPT

# File lib/rbbt/rest/common/locate.rb, line 101
def self.javascript_resources
  @@javascript_resources ||= [Rbbt.share.views.public.find(:lib), Rbbt.share.views.public.js.find(:lib), Rbbt.share.views.public.plugins.find(:lib)]
end
load_tsv(file, persist = false) click to toggle source
# File lib/rbbt/rest/common/table.rb, line 412
def self.load_tsv(file, persist = false)
  if persist
    tsv = TSV.open(Open.open(file), :persist => true, :persist_file => file + '.persist')
  else
    tsv = TSV.open(Open.open(file))
  end

  table_options = File.exist?(file + '.table_options') ? YAML.load_file(file + '.table_options') : {}
  tsv.entity_options = table_options[:tsv_entity_options]
  headers = table_options[:headers]
  headers.each{|field,p| tsv.entity_templates[field] = Misc.prepare_entity("TEMPLATE", p.first, (tsv.entity_options || {}).merge(p.last)) } unless headers.nil?

  [tsv, table_options]
end
sass_resources() click to toggle source
# File lib/rbbt/rest/common/locate.rb, line 85
def self.sass_resources
  @sass_resources ||= [Rbbt.share.views.compass.find(:lib)]
end
save_tsv(tsv, path) click to toggle source
# File lib/rbbt/rest/common/table.rb, line 390
def self.save_tsv(tsv, path)
  Open.write(path, tsv.to_s)
  table_options = {:tsv_entity_options => tsv.entity_options, :tsv_entity_templates => tsv.entity_templates}
  if tsv.entity_templates and tsv.entity_templates.any?
    table_options[:headers] ||= {}
    tsv.entity_templates.each do |field,template|
      next if template.nil?
      next if table_options[:headers].include? field
      info = template.info
      info.delete :format
      info.delete :annotation_types
      info.delete :annotated_array
      table_options[:headers][field] = [template.annotation_types.last.to_s, info]
    end
  end
  Open.write(path + '.table_options', table_options.to_yaml )
end
template_resources() click to toggle source

{{{ TEMPLATE

# File lib/rbbt/rest/common/locate.rb, line 40
def self.template_resources
  @template_resources ||= [Rbbt.share.views.find(:lib)]
end

Public Instance Methods

add_GET_param(url, param, value) click to toggle source
# File lib/rbbt/rest/common/misc.rb, line 283
def add_GET_param(url, param, value)
  url = remove_GET_param(url, param)
  if url =~ /\?.+=/
    url + "&#{ param }=#{ value }"
  else
    url + "?#{ param }=#{ value }"
  end
end
add_search_paths(path, resources) click to toggle source

{{{ Common

# File lib/rbbt/rest/common/locate.rb, line 10
def add_search_paths(path, resources)
  resources.reverse.each do |resource|
    name = Misc.snake_case(resource.to_s.gsub('/','_'))
    path.prepend_search_path(name, resource)
  end
end
cache(name, params = {}) { || ... } click to toggle source
# File lib/rbbt/rest/common/cache.rb, line 36
  def cache(name, params = {}, &block)
    @cache_type ||= params.delete :cache_type if params[:cache_type]
    return yield if name.nil? or @cache_type.nil? or @cache_type == :none

    send_file = consume_parameter(:_send_file, params)

    # Setup Step
    
    check = [params[:_template_file]].compact
    check += consume_parameter(:_cache_check, params) || []
    check.flatten!
    
    orig_name = name
    path = if params[:cache_file]
             params[:cache_file] 
           else
             if post_hash = params["__post_hash_id"]
               name = name.gsub("/",'>') << "_" << post_hash
             elsif params
               param_hash = Misc.obj2digest(params)
               name = name.gsub("/",'>') << "_" << param_hash 
             end
             settings.cache_dir[name].find
           end

    task = Task.setup(:name => orig_name, :result_type => :string, &block)

    step = Step.new(path, task, nil, nil, self)

    halt 200, step.info.to_json if @format == :info

    self.instance_variable_set("@step", step)

    if @file
      send_file step.file(@file), :filename => @file
    end

    # Clean/update job

    clean_url = request.url
    clean_url = remove_GET_param(clean_url, :_update)
    clean_url = remove_GET_param(clean_url, :_)

    clean_url =  add_GET_param(clean_url, "__post_hash_id", params["__post_hash_id"]) if params.include?("__post_hash_id") && @is_method_post

    if not @fragment and (old_cache(step.path, check) or update == :reload)
      begin
        pid = step.info[:pid] 
        step.abort if pid and Misc.pid_exists?(pid) and not pid == Process.pid
        step.pid = nil
      rescue Exception
        Log.medium{$!.message}
      end
      step.clean 

      redirect remove_GET_param(clean_url, "__post_hash_id")
    end


    class << step
      def url
        @url
      end

    end

    #step.instance_variable_set(:@url, clean_url)
    #step.instance_variable_set(:@url_path, URI(clean_url).path)
    step.instance_variable_set(:@url, clean_url)
    step.instance_variable_set(:@url_path, URI(clean_url).path)
    step.clean if step.error? || step.aborted?

    Thread.current["step_path"] = step.path
    # Issue
    if not step.started?
      if cache_type == :synchronous or cache_type == :sync
        step.run 
      else
        # $rest_cache_semaphore is defined in rbbt-util etc/app.d/semaphores.rb
        step.fork(true, $rest_cache_semaphore)
        step.soft_grace
      end
      step.set_info :template_file, params[:_template_file].to_s
    end

    redirect clean_url if params.include?("__post_hash_id") && @is_method_post

    # Return fragment

    if @fragment
      fragment_file = step.file(@fragment)
      if Open.exists?(fragment_file)
        case @format.to_s
        when "query-entity"
          tsv, table_options = load_tsv(fragment_file, true)
          begin
            res = tsv[@entity].to_json
            content_type "application/json" 
          rescue
            res = nil.to_json
          end
          halt 200, res 
        when "query-entity-field"
          tsv, table_options = load_tsv(fragment_file, true)
          begin
            res = tsv[@entity]
            res = [res] if tsv.type == :single or tsv.type == :flat
          rescue
            res = nil.to_json
          end

          fields = tsv.fields
          content_type "application/json" 
          hash = {}
          fields.each_with_index do |f,i|
            hash[f] = res.nil? ? nil : res[i]
          end

          halt 200, hash.to_json 
        when "table"
          halt_html tsv2html(fragment_file)
        when "json"
          content_type "application/json" 
          halt 200, tsv_process(load_tsv(fragment_file).first).to_json
        when "tsv"
          content_type "text/tab-separated-values"
          halt 200, tsv_process(load_tsv(fragment_file).first).to_s
        when "values"
          tsv = tsv_process(load_tsv(fragment_file).first)
          list = tsv.values.flatten
          content_type "application/json" 
          halt 200, list.compact.to_json
        when "entities"
          raw_tsv, tsv_options = load_tsv(fragment_file)
          tsv = tsv_process(raw_tsv)

          list = tsv.values.flatten
          tsv.prepare_entity(list, tsv.fields.first, tsv.entity_options)
          type = list.annotation_types.last
          list_id = "List of #{type} in table #{ @fragment }"
          list_id << " (#{ @filter })" if @filter
          Entity::List.save_list(type.to_s, list_id, list, user)
          url =  Entity::REST.entity_list_url(list_id, type)
          url = url + '?_layout=false' unless @layout
          url = escape_url(url)
          redirect to(url)
        when "map"
          raw_tsv, tsv_options = load_tsv(fragment_file)
          raw_tsv.unnamed = true
          tsv = tsv_process(raw_tsv)

          field = tsv.key_field
          column = tsv.fields.first

          if tsv.entity_templates[field] 
            type = tsv.entity_templates[field].annotation_types.first
          else
            type = [Entity.formats[field]].compact.first || field
          end

          map_id = "Map #{type}-#{column} in #{ @fragment }"
          map_id << " (#{ @filter.gsub(';','|') })" if @filter
          Entity::Map.save_map(type.to_s, column, map_id, tsv, user)
          url = Entity::REST.entity_map_url(map_id, type, column)
          url = url + '?_layout=false' unless @layout
          url = escape_url(url)
          redirect to(url)
        when "excel"
          require 'rbbt/tsv/excel'
          tsv, tsv_options = load_tsv(fragment_file)
          tsv = tsv_process(tsv)
          data = nil
          excel_file = TmpFile.tmp_file
          tsv.excel(excel_file, :sort_by => @excel_sort_by, :sort_by_cast => @excel_sort_by_cast, :name => true, :remove_links => true)
          name = tsv_options[:table_id]
          name ||= "rbbt-table"
          name = name.sub(/\s/,'_')
          name = name.sub('.tsv','')
          send_file excel_file, :type => 'application/vnd.ms-excel', :filename => "#{name}.xls"
        when "heatmap"
          require 'rbbt/util/R'
          tsv, tsv_options = load_tsv(fragment_file)
          content_type "text/html"
          data = nil
          png_file = TmpFile.tmp_file + '.png'
          width = tsv.fields.length * 10 + 500
          height = tsv.size * 10 + 500
          width = 10000 if width > 10000
          height = 10000 if height > 10000
          tsv.R <<-EOF
rbbt.pheatmap(file='#{png_file}', data, width=#{width}, height=#{height})
data = NULL
          EOF
          send_file png_file, :type => 'image/png', :filename => fragment_file + ".heatmap.png"
        when 'binary'
          send_file fragment_file, :type => 'application/octet-stream'
        else

          require 'mimemagic'
          mime = nil
          Open.open(fragment_file) do |io|
            begin
              mime = MimeMagic.by_path(fragment_file) 
              if mime.nil?
                io.rewind
                mime = MimeMagic.by_magic(io) 
              end
              if mime.nil?
                io.rewind if IO === io
                mime = "text/tab-separated-values" if io.gets =~ /^#/ and io.gets.include? "\t"
              end
            rescue Exception
              Log.exception $!
            end
          end

          if mime.nil?
            txt = Open.read(fragment_file)

            if txt =~ /<([^> ]+)[^>]*>.*?<\/\1>/m
              mime = "text/html"
            else
              begin
                JSON.parse(txt)
                mime = "application/json"
              rescue
              end
            end
          else
            txt = nil
          end

          if mime
            content_type mime 
          else
            content_type "text/plain"
          end

          if mime && mime.to_s.include?("text/html")
            halt_html txt || Open.read(fragment_file)
          else
            if File.exist?(fragment_file)
              send_file fragment_file
            else
              halt 200, Open.read(fragment_file)
            end
          end
        end
      elsif Open.exists?(fragment_file + '.error') 
        klass, _sep, message = Open.read(fragment_file + '.error').partition(": ")
        backtrace = Open.read(fragment_file + '.backtrace').split("\n")
        exception =  Kernel.const_get(klass).new message || "no message"
        exception.set_backtrace backtrace
        raise exception
        #halt 500, html_tag(:span, File.read(fragment_file + '.error'), :class => "message") +
        #  html_tag(:ul, File.read(fragment_file + '.backtrace').split("\n").collect{|l| html_tag(:li, l)} * "\n", :class => "backtrace")
      elsif Open.exists?(fragment_file + '.pid') 
        pid = Open.read(fragment_file + '.pid')
        if Misc.pid_exists?(pid.to_i)
          halt 202, "Fragment not completed"
        else
          halt 500, "Fragment aborted"
        end
      else
        halt 500, "Fragment not completed and no pid file"
      end
    end

    # Monitor
    
    begin

      if step.done?
        case
        when @permalink
          redirect to(permalink(step.path))
        when send_file
          send_file step.path
        else
          step.load
        end
      else

        case step.status
        when :error, :aborted
          error_for step, !@ajax

        else
          # check for problems
          begin
            check_step step
          rescue Aborted
            step.clean
            raise RbbtRESTHelpers::Retry
          end

          #if File.exist?(step.info_file) and Time.now - File.atime(step.info_file) > 60
          #  Log.debug{ "Checking on #{step.info_file}" }
          #  running = (not step.done?) and step.running?
          #  if FalseClass === running
          #    Log.debug{ "Aborting zombie #{step.info_file}" }
          #    step.abort unless step.done?
          #    raise RbbtRESTHelpers::Retry
          #  end
          #  FileUtils.touch(step.info_file)
          #end

          wait_on step, false
        end
      end
    rescue RbbtRESTHelpers::Retry
      retry
    end
  end
capture(*args, &block) click to toggle source
# File lib/rbbt/rest/common/table.rb, line 150
def capture(*args, &block)

  variables = block.binding.local_variables
  #variables.each do |v|
  #  iif [v, block.binding.local_variable_get(v)]
  #end
  buff_var = variables.select{|v| v.to_s =~ /^_module\d+$/}.sort_by{|v| v.to_s.scan(/\d+/).first.to_i}.last
  buff_was = block.binding.local_variable_get(buff_var) if variables.include? buff_var
  block.binding.local_variable_set(buff_var,'') if buff_var
  begin
    raw = block.call(*args)
    #variables = block.binding.local_variables
    #iii variables
    #variables.each do |v|
    #  iif [v, block.binding.local_variable_get(v)]
    #end
    captured = block.binding.local_variable_get(buff_var) if block.binding.local_variables.include?(buff_var)
    captured = "" if captured.nil?
    captured = raw if captured.empty? 
    captured
  ensure
    block.binding.local_variable_set(buff_var, buff_was) if buff_was
  end
end
check_step(step) click to toggle source
# File lib/rbbt/rest/common/misc.rb, line 7
def check_step(step)
  if File.exist?(step.info_file) and Time.now - File.atime(step.info_file) > 60
    done = step.done?
    running = done ? false : step.running?
    Log.debug{ "Checking on #{step.info_file} (done: #{done}; running: #{running})" }
    if FalseClass === running
      if step.done?
        Log.debug{ "Not aborting zombie #{step.info_file}: it is done" }
      else
        Log.debug{ "Aborting zombie #{step.info_file}" }
        step.abort 
        raise Aborted, "Zombie job aborted"
      end
    end
    FileUtils.touch(step.info_file)
  end
end
consume_parameter(parameter, params = nil) click to toggle source
# File lib/rbbt/rest/common/misc.rb, line 145
def consume_parameter(parameter, params = nil)
  params = self.params if params.nil?

  val = params.delete(parameter.to_sym) 
  val = params.delete(parameter.to_s) if val.nil?

  val = nil if String === val and val.empty?

  val
end
css_resources() click to toggle source
# File lib/rbbt/rest/common/locate.rb, line 121
def css_resources
  RbbtRESTHelpers.css_resources
end
development?() click to toggle source
# File lib/rbbt/rest/common/misc.rb, line 51
def development?
  ENV["RACK_ENV"] == "develoment"
end
error_for(job, layout = nil) click to toggle source
# File lib/rbbt/rest/common/render.rb, line 7
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
escape_url(url) click to toggle source
# File lib/rbbt/rest/common/cache.rb, line 7
def escape_url(url)
  base, _sep, query = url.partition("?")
  base = base.split("/").collect{|p| CGI.escape(p) }* "/"
  if query && ! query.empty?
    query = query.split("&").collect{|e| e.split("=").collect{|pe| CGI.escape(pe) } * "=" } * "&"
    [base, query] * "?"
  else
    base
  end
end
file_or_text_area(id, name, value, tsv = false) click to toggle source
# File lib/rbbt/rest/common/forms.rb, line 18
def file_or_text_area(id, name, value, tsv = false)
  text_area_string = tsv ? "or use the text area below (you may use ',' intead of tabs)" : "or use the text area below"

  html_tag("input", nil, :type => "file", :id => (id.nil? ? nil : id +  "__" + "param_file"), :name => name.to_s + "__" + "param_file") + 
  html_tag("span", text_area_string, :class => "file_or_text_area") + 
  html_tag("textarea", value || "" , :name => name, :id => id )
end
file_resources() click to toggle source
# File lib/rbbt/rest/common/locate.rb, line 60
def file_resources
 [Rbbt.www.views] + RbbtRESTHelpers.file_resources
end
filter(field, type = :string) click to toggle source
# File lib/rbbt/rest/common/table.rb, line 385
def filter(field, type = :string)
  @table_filters ||= {}
  @table_filters[field] = type
end
find_all(file) click to toggle source
# File lib/rbbt/rest/common/locate.rb, line 70
def find_all(file)
  find_all_server_files(file, file_resources)
end
find_all_server_files(file, resource) click to toggle source
# File lib/rbbt/rest/common/locate.rb, line 32
def find_all_server_files(file, resource)
  path = Path.setup(file)
  add_search_paths(path, resources)
  path.find_all
end
fix_html(html) click to toggle source
# File lib/rbbt/rest/common/misc.rb, line 309
def fix_html(html)
  if html !~ /^\s*<html/i
    "<html><meta charset=#{html.encoding.to_s}/><body>" + html + "<body/><html/>"
  else
    html
  end
end
fix_input(type, value, param_file = nil) click to toggle source
# File lib/rbbt/rest/common/misc.rb, line 156
def fix_input(type, value, param_file = nil)
  case type

  when nil, :string, :select
    value

  when :integer
    value.to_i

  when :float
    value.to_f

  when :multiple
    value.keys

  when :boolean
    param2boolean(value)

  when :text, :file
    if param_file and (value.nil? or (String === value and value.empty?))
      param_file[:tempfile].read
    else
      case value
      when String
        value.gsub(/\r\n/, "\n")
      when File, IO
        value
      when Hash
        value[:tempfile]
      else
        raise "Missing class for #{ type }: #{ Misc.fingerprint value }"
      end
    end

  when :array
    text = if param_file and (value.nil? or (String === value and value.empty?))
             param_file[:tempfile].read
           else
             value
           end

    case
    when Array === text
      text
    when text =~ /^list:([^:]+):(.+)$/
      Entity::List.load_list($1, $2, user)
    when text =~ /^\[.*\]$/sm
      JSON.parse(text)
    when text =~ /\n/
      text.split(/\r?\n/).collect{|l| l.strip}
    when text =~ /\|/
      text.split(/\|/).collect{|l| l.strip}
    when IO === text
      text
    when Hash === text
      io = text[:tempfile].open
      class << io
        attr_accessor :filename
      end
      io.filename = text[:filename]
      io
    when text == "EMPTY_ARRAY"
      []
    when text.nil?
      []
    else
      text.split(/,/).collect{|l| l.strip}
    end

  when :tsv
    if param_file and (value.nil? or (String === value and value.empty?))
      TSV.open(param_file[:tempfile].open)
    else
      TSV.open(StringIO.new(value), :sep=>/\t|,/)
    end
  when :directory
    param_file[:tempfile].close
    Path.setup(param_file[:tempfile].path)
  end
end
form_input(name, type, default = nil, current = nil, description = nil, id = nil, extra = {}) click to toggle source
# File lib/rbbt/rest/common/forms.rb, line 33
def form_input(name, type, default = nil, current = nil, description = nil, id = nil, extra = {})
  html_options = consume_parameter(:html_options, extra) || {}

  no_file = extra[:no_file] if extra

  case type
  when :multiple
    choices = consume_parameter(:choices, extra)
    default = default.collect{|o| o.to_s} if default
    current = current.collect{|o| o.to_s} if current
    input_label(id, name, description, Array === default ? default * ", " : nil, extra) +
      choices.collect do |choice|
        choice_name = name.to_s + "[#{ choice }]"
      
        check_true = (current && current.include?(choice.to_s)) || (default && default.include?(choice.to_s))

        check_true = false if check_true.nil?
          check_false = ! check_true
          
          choice_id = id + "[#{ Misc.snake_case(choice) }]"
          if id
            false_id = choice_id + '_false'
            true_id  = choice_id + '_true'
          else
            false_id = nil
            true_id = nil
          end

            choice_html = html_tag("input", nil, :type => :checkbox, :checked => check_true, :name => choice_name, :value => "true", :id => choice_id) +
              input_label(choice_id, choice, choice, nil, extra.merge({:class => :inline})) 

            html_tag('span', choice_html, :class => 'choice')
        end * "\n"


  when :boolean
    current = param2boolean(current) unless current.nil?
    default = param2boolean(default) unless default.nil?

    check_true = current.nil? ? default : current
    check_true = false if check_true.nil?
    check_false = ! check_true
    
    if id
      false_id = id + '__' << 'false'
      true_id = id + '__' << 'true'
    else
      false_id = nil
      true_id = nil
    end

    input_label(id, name, description, default, extra) +
      html_tag("input", nil, :type => :checkbox, :checked => check_true, :name => name, :value => "true", :id => id) +
      html_tag("input", nil, :type => :hidden, :name => name.to_s + "_checkbox_false", :value => "false") 

  when :string, :float, :integer, :hidden
    value = current.nil?  ? default : current

    input_type = case type
                 when :string
                   "text"
                 when :hidden
                   "hidden"
                 else
                   "number"
                 end

    step = case type
           when :string
             nil
           when :float
             "any"
           when :integer
             1
           end

    if input_type == 'hidden'
        html_tag("input", nil, html_options.merge(:type => input_type, :name => name, :value => value, :id => id, :step => step))
    else
      input_label(id, name, description, default, extra) +
        html_tag("input", nil, html_options.merge(:type => input_type, :name => name, :value => value, :id => id, :step => step))
    end

  when :tsv, :array, :text, :file
    value = current.nil? ? default : current
    value = value * "\n" if Array === value

    if no_file
      input_label(id, name, description, nil, extra) +
        html_tag("textarea", value || "" , :name => name, :id => id )
    else
      input_label(id, name, description, nil, extra) +
        file_or_text_area(id, name, value, type == :tsv)
    end

  when :select
    value = current.nil? ? default : current

    allow_empty = consume_parameter :allow_empty, extra
    select_options = consume_parameter :select_options, extra
    
    if select_options 
      options = select_options.collect do |option|
        option, option_name = option if Array === option
        option_name = option if option_name.nil?
        html_tag('option', option_name, :value => option, :selected => option.to_s == value.to_s)
      end 
    else
      options = []
    end

    options.unshift html_tag('option', 'none', :value => 'none', :selected => value.to_s == 'none') if allow_empty

    input_label(id, name, description, default, extra) +
      html_tag('select', options * "\n", html_options.merge(:name => name, :id => id, "attr-selected" => (value ? value.to_s : "")))
  when :directory
    value = current.nil? ? default : current

    input_label(id, name, description, nil, extra) +
      tar_file(id, name, value)
  else
    "<span> Unsupported input '#{name}' type: #{type} </span>"
  end
end
fragment(link = nil, &block) click to toggle source
# File lib/rbbt/rest/common/render.rb, line 136
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(/<a /,"<a href='#{fragment_url}' ")
        end

        if text
          link.sub(/<a /,"<a data-text='#{text}' ")
        else
          link
        end
      end
    else
      $haml_6 ? capture(&block) : capture_haml(&block)
    end
  else
    if link =~ / class=/
      link = link.sub(/ class=('|")/,' class=\1fragment ')
    else
      link = link.sub(/<a /,'<a class="fragment" ')
    end
    
    if text
      link.sub(/<a /,"<a data-text='#{text}' ")
    else
      link
    end
  end
end
glob_all(file) click to toggle source
# File lib/rbbt/rest/common/locate.rb, line 74
def glob_all(file)
  glob_all_server_files(file, file_resources)
end
glob_all_server_files(file, resources) click to toggle source
# File lib/rbbt/rest/common/locate.rb, line 26
def glob_all_server_files(file, resources)
  path = Path.setup(file)
  add_search_paths(path, resources)
  path.glob_all
end
halt_html(html, response = 200) click to toggle source
# File lib/rbbt/rest/common/misc.rb, line 317
def halt_html(html, response = 200)
  content_type "text/html; charset=#{html.encoding.to_s}"
  html = fix_html html
  halt response, html
end
hash2dl(hash, options = {}) click to toggle source
# File lib/rbbt/rest/common/misc.rb, line 292
def hash2dl(hash, options = {})
  entries = hash.collect{|k,v|
    v = v * ", " if Array === v
    v = hash2dl(v) if Hash === v
    html_tag(:dt, k) + html_tag(:dd, v)
  } * "\n"
  html_tag(:dl, entries, options)
end
header(field, entity_type, entity_options = {}) click to toggle source
# File lib/rbbt/rest/common/table.rb, line 380
def header(field, entity_type, entity_options = {})
  @table_headers ||= {}
  @table_headers[field] = [entity_type, entity_options]
end
html_tag(*args) click to toggle source
# File lib/rbbt/rest/common/misc.rb, line 268
def html_tag(*args)
  Misc.html_tag(*args)
end
input_label(id, name, description = nil, default = nil, options = {}) click to toggle source
# File lib/rbbt/rest/common/forms.rb, line 5
def input_label(id, name, description = nil, default = nil, options = {})
  options ||= {}
  text = consume_parameter :label, options

  if text.nil?
    text = name.to_s
    text += html_tag('span', " (default: " << default.to_s << ")", :class => 'input_default') unless default.nil?
  end

  label_id = id.nil? ? nil : 'label_for__' << id
  html_tag('label', text, {:id => label_id, :for => id, :title => description}.merge(options))
end
json_resource(object, filename = nil, promise = true) click to toggle source
# File lib/rbbt/rest/common/render.rb, line 269
def json_resource(object, filename = nil, promise = true)
  filename = File.basename(TmpFile.tmp_file) if filename.nil?

  if @step
    url = add_GET_param(remove_GET_param(@uri, ["_update", "_"]), "_fragment", "json_resources/#{ filename }")
    f = @step.file(:json_resources)[filename].find
  else
    url = "/files/#{ filename }"
    f = settings.file_dir[filename].find
  end

  Open.write(f, object.to_json)

  if promise
    "rbbt.get('#{url}')"
  else
    url
  end
end
load_tsv(*args) click to toggle source
# File lib/rbbt/rest/common/table.rb, line 427
def load_tsv(*args)
  RbbtRESTHelpers.load_tsv(*args)
end
locate_css(template) click to toggle source
# File lib/rbbt/rest/common/locate.rb, line 125
def locate_css(template)
  path = locate_server_file(template, css_resources, 'css')
  raise TemplateMissing, "CSS file #{ template } not found" if path.nil?
  path
end
locate_file(file) click to toggle source
# File lib/rbbt/rest/common/locate.rb, line 64
def locate_file(file)
  path = locate_server_file(file, file_resources)
  raise TemplateMissing, "File #{ file } not found" if path.nil?
  path
end
locate_javascript(template) click to toggle source
# File lib/rbbt/rest/common/locate.rb, line 109
def locate_javascript(template)
  path = locate_server_file(template, javascript_resources, 'js')
  raise TemplateMissing, "Javascript file #{ template } not found" if path.nil?
  path
end
locate_sass(template) click to toggle source
# File lib/rbbt/rest/common/locate.rb, line 93
def locate_sass(template)
  path = locate_server_file(template, sass_resources, 'sass')
  raise TemplateMissing, "Sass file #{ template } not found" if path.nil?
  path
end
locate_server_file(template, resources, extension = nil) click to toggle source
# File lib/rbbt/rest/common/locate.rb, line 17
def locate_server_file(template, resources, extension = nil)
  path = Path.setup(template)
  add_search_paths(path, resources)

  return path.find if path.exists? and not path.directory?
  path = path.set_extension(extension) if extension
  return path.find if path.exists?
end
locate_template(template) click to toggle source
# File lib/rbbt/rest/common/locate.rb, line 48
def locate_template(template)
  path = locate_server_file(template, template_resources, 'haml')
  raise TemplateMissing, "Template #{ template } not found" if path.nil?
  path
end
log(status, message = nil) click to toggle source
# File lib/rbbt/rest/common/misc.rb, line 27
def log(status, message = nil)
  if @step
    @step.log(status, message)
  else
    Log.info{ "[#{ status }] #{ message }" }
  end
end
modal_fragment(text, &block) click to toggle source
old_cache(path, check) click to toggle source
# File lib/rbbt/rest/common/cache.rb, line 20
def old_cache(path, check)
  return false if production?
  return false if check.nil? or check.empty?
  return false if not File.exist? path
  check = [check] unless Array === check
  check.each do |file|
    if not File.exist?(file)
      return true 
    end
    if File.mtime(file) > File.mtime(path)
      return true 
    end
  end
  return false
end
paginate(object, page = nil, just_keys = false) click to toggle source
# File lib/rbbt/rest/common/table.rb, line 202
def paginate(object, page = nil, just_keys = false)
  return object unless TSV === object and not page.nil?

  return object if page == "all" or page.nil? or page.empty?
  num, size, field = parse_page(page)

  if field and field[0] == "-"[0]
    field = field[1..-1]
    reverse = true
  else
    reverse = false
  end

  field =  CGI.unescapeHTML(Entity::REST.restore_element(field))

  if object.entity_templates[field]
    entity = object.entity_templates[field].annotation_types.last
  else
    entity = Entity.formats[field] 
  end

  if num == 'all'
    num = 1
    size = object.size.to_i
    max = 1
  else
    num = num.to_i
    size = size.to_i
    max = (object.size / size) + 1
  end

  num = max if num > max
  num = - max if num < - max

  object.with_unnamed do
    if entity and entity.respond_to? :tsv_sort
      object.page(num, size, field, false, reverse, &entity.method(:tsv_sort))
    else
      object.page(num, size, field, false, reverse)
    end
  end
end
param2boolean(value) click to toggle source
# File lib/rbbt/rest/common/misc.rb, line 257
def param2boolean(value)
  case value
  when "true", "True", "TRUE", "T", "yes", "Yes", "y", "Y"
    true
  when "false", "False", "FALSE", "F", "no", "No", "N", "n"
    false
  else
    value
  end
end
parse_page(page) click to toggle source
# File lib/rbbt/rest/common/table.rb, line 191
def parse_page(page)
  num, size, field = page.split("~").values_at 0, 1, 2

  field, size = size, nil if field.nil?

  field = "key" if field.nil? or field.empty?
  size = PAGE_SIZE if size.nil? or size.empty?

  [num, size, field]
end
partial_render(template, locals = {}, cache = nil, cache_options = {}) click to toggle source
# File lib/rbbt/rest/common/render.rb, line 131
def partial_render(template, locals = {}, cache = nil, cache_options = {})
  template_file = locate_template(template)
  render(template_file, locals, nil, cache, cache_options)
end
prepare_input(params, input, type, stream = false) click to toggle source
# File lib/rbbt/rest/common/misc.rb, line 237
def prepare_input(params, input, type, stream = false)
  value = consume_parameter(input, params)
  param_file = consume_parameter(input.to_s + '__param_file', params)

  param_file, value = value, nil if Hash === value and value.include? :tempfile

  if stream and param_file
    filename = param_file[:head].match(/filename="(.*?)"\r\n/)[1]
    io = param_file[:tempfile].open
    return ConcurrentStream.setup(io, :filename => filename)
  end

  return nil if value.nil? and param_file.nil?

  fixed_value = fix_input(type, value, param_file)

  fixed_value
end
process_common_parameters() click to toggle source
# File lib/rbbt/rest/common/misc.rb, line 59
def process_common_parameters
  @ajax = request.xhr?

  @uri = request.env["REQUEST_URI"]
  @uri = remove_GET_param(@uri, ["_update", "_", "_layout"])
  @request_method = request.env["REQUEST_METHOD"]
  @is_method_post = @request_method.to_s.downcase == 'post'

  @uri = post_uri if @is_method_post

  @path = request.env["PATH_INFO"]
  @query = request.env["QUERY_STRING"]
  @fullpath = (@query && ! @query.empty?) ? @path + "?" + @query : @path
  @fullpath = remove_GET_param(@fullpath, ["_update", "_", "_layout"])

  @ajax_url = @uri

  @layout = consume_parameter(:_layout)

  @layout = false if @layout.nil? and     @ajax
  @layout = true  if @layout.nil? and not @ajax
  @layout = false if @layout == "false"
  @layout = true  if @layout == "true"

  @format = consume_parameter(:_format)
  @format = :html if @format.nil?
  @format = @format.to_sym if String === @format


  @size = consume_parameter(:_size)
  @size = @size.to_sym if String === @size

  @update = consume_parameter(:_update) unless @update
  @update = @update.to_sym if String === @update

  @profile = consume_parameter(:_profile) unless @profile
  @profile = @profile.to_sym if String === @profile

  @cache_type = consume_parameter(:_cache_type)
  @cache_type = @cache_type.to_sym if String === @cache_type

  @debug_js = consume_parameter(:_debug_js)
  @debug_js = false if @debug_js.nil? or @debug_js == "false"

  @debug_css = consume_parameter(:_debug_css)
  @debug_css = false if @debug_css.nil? or @debug_css == "false"

  @_ = consume_parameter(:_)

  @fragment = consume_parameter(:_fragment)
  @file     = consume_parameter(:_file)

  @excel_use_name     = consume_parameter(:_excel_use_name)
  @excel_sort_by      = consume_parameter(:_excel_sort_by)
  @excel_sort_by_cast = consume_parameter(:_excel_sort_by_cast)
  @excel_use_name = true if @excel_use_name.nil?

  @splat = consume_parameter :splat
  @captures = consume_parameter :captures

  # TSV table pagination, filtering, and slicing
  @page = consume_parameter :_page
  @filter = consume_parameter :_filter
  @column = consume_parameter :_column

  # TSV table query
  @entity = consume_parameter :_entity

  # Fix boolean inputs sumbitted using checkboxes
  params.keys.each do |param|
    if param =~ /(.*)_checkbox_false$/
      params[$1] = false if params[$1].nil?
      params.delete param
    end
  end

  @array_separator = consume_parameter(:_array_separator) || ','

  @permalink = consume_parameter :_permalink

  @clean_params = {}
  params.each do |k,v|
    @clean_params[k] = v
  end
end
production?() click to toggle source
# File lib/rbbt/rest/common/misc.rb, line 55
def production?
  settings.environment && settings.environment.to_s == 'production'
end
progress(msg = nil, max = nil, &block) click to toggle source
# File lib/rbbt/rest/common/misc.rb, line 45
def progress(msg = nil, max = nil, &block)
  msg = "Processing" if msg.nil?
  bar = @step.progress_bar(msg, :max => max)
  block.call(bar)
end
record_css(file) click to toggle source
# File lib/rbbt/rest/common/resources.rb, line 23
def record_css(file)
  recorded_css_files << file
end
record_js(file) click to toggle source
# File lib/rbbt/rest/common/resources.rb, line 19
def record_js(file)
  recorded_js_files << file
end
recorded_css_files() click to toggle source
# File lib/rbbt/rest/common/resources.rb, line 9
def recorded_css_files
  @recorded_css_files ||= []
end
recorded_js_files() click to toggle source
# File lib/rbbt/rest/common/resources.rb, line 5
def recorded_js_files
  @recorded_js_files ||= []
end
remove_GET_param(url, param) click to toggle source
# File lib/rbbt/rest/common/misc.rb, line 272
def remove_GET_param(url, param)
  if Array === param
    param.each do |p|
      url = remove_GET_param(url, p)
    end
    url
  else
    url.gsub(/&?#{param}=[^&]+/,'').sub(/\?$/, '')
  end
end
render(template_file, locals = {}, layout_file = nil, cache = nil, cache_options = {}) click to toggle source
# File lib/rbbt/rest/common/render.rb, line 60
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
render_partial(template_file, locals = {}, cache = nil, cache_options = {}) click to toggle source
# File lib/rbbt/rest/common/render.rb, line 120
def render_partial(template_file, locals = {}, cache = nil, cache_options = {})
  render(template_file, locals, nil, cache, cache_options)
end
render_sass(file) click to toggle source
# File lib/rbbt/rest/common/render.rb, line 113
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
reset_js_css() click to toggle source
# File lib/rbbt/rest/common/resources.rb, line 13
def reset_js_css
  @recorded_js_files = []
  @recorded_css_files = []
end
resource(filename = nil, text = nil, type = nil, options = {}) { |f| ... } click to toggle source
# File lib/rbbt/rest/common/render.rb, line 221
def resource(filename = nil, text = nil, type = nil, options = {})
  case
  when filename.nil?
    filename = File.basename(TmpFile.tmp_file)
  when filename[0] == "."[0]
    extension = filename
    filename = File.basename(TmpFile.tmp_file) + extension
  end

  text ||= filename

  filename = Misc.sanitize_filename(Misc.name2basename(filename))

  if @step
    url = add_GET_param(remove_GET_param(@uri, ["_update", "_"]), "_fragment", "html_resources/#{ filename }")
    f = @step.file(:html_resources)[filename].find
  else
    url = "/files/#{ filename }"
    f = settings.file_dir[filename].find
  end

  Open.mkdir(File.dirname(f))

  yield(f)


  type ||= :link
  case type
  when :image
    "<img src='#{url}' alt='#{text}' class='file_resource'/>"
  when :link
    "<a href='#{url}' class='file_resource'>#{ text }</a>"
  when :linked_image
    "<a href='#{url}' class='file_resource' target='_blank'><img src='#{url}' class='file_resource'/></a>"
  when :zoomable_image
    id = options[:id] || Misc.digest(filename)
    width, height= [600, 600]
    "<div class='zoomable_image'><img id='#{id}' style='width:#{width}px; height:#{height}px' rel='#{url}' src='#{url}' class='file_resource'/></div>"
  when :mapped_image
    mapid = options[:mapid] || options[:id] + '_map'
    width, height= [300, 300]
    mapfile = f.sub(/\.[^.]+$/, '.html')
    "<div class='mapped_image'>#{Open.read(mapfile)}<img class='has_map' usemap='##{mapid}' rel='#{url}' src='#{url}' class='file_resource'/></div>"
  else
    raise "Type not understood: #{ type }"
  end
end
reveal(text, id = nil, options = nil, &block) click to toggle source
# File lib/rbbt/rest/common/render.rb, line 294
def reveal(text, id = nil, options = nil, &block)
  id ||= "rbbt_reveal_" << (rand * 10000).to_i.to_s

  #content_html = capture_haml(&block)
  content_html = $haml_6 ? capture(&block) : 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
save_tsv(file) click to toggle source
# File lib/rbbt/rest/common/table.rb, line 408
def save_tsv(file)
  RbbtRESTHelpers.save_tsv(file)
end
serve_css() click to toggle source
# File lib/rbbt/rest/common/resources.rb, line 73
def serve_css
  res = recorded_css_files.collect{|file|
    link_css(file)
  } * "\n"

  recorded_css_files.clear

  res
end
serve_js(compress = true) click to toggle source
# File lib/rbbt/rest/common/resources.rb, line 38
def serve_js(compress = true)
  if production? and compress and not @debug_js 
    md5 = Misc.digest(recorded_js_files * ",")
    filename = settings.file_dir["all_js-#{md5}.js"].find

    if not File.exist?(filename)
      Log.debug{ "Regenerating JS Compressed file: #{ filename }" }

      text = recorded_js_files.collect{|file| 
        begin
          path = locate_javascript(file)
        rescue
          path = locate_javascript(file.split("/")[2..-1] * "/")
        end

        "//FILE: #{ File.basename(path) }\n" +  Open.read(path)
      } * "\n"

      FileUtils.mkdir_p File.dirname(filename) unless File.exist? File.dirname(filename)
      Open.write(filename, Uglifier.compile(text))
    end

    res = "<script src='/files/#{File.basename(filename)}' type='text/javascript'></script>"
  else
    res = recorded_js_files.collect{|file|
      link_js(file)
    } * "\n"

  end

  recorded_js_files.clear

  res
end
sync_json_resources(objects) click to toggle source
# File lib/rbbt/rest/common/render.rb, line 289
def sync_json_resources(objects)
  gets = objects.collect{|object| json_resource(object) }
  "m.sync([#{gets * ", "}])"
end
table(options = {},&block) click to toggle source
# File lib/rbbt/rest/common/table.rb, line 431
def table(options = {},&block)
  options = {} if options.nil?

  tsv = $haml_6 ? capture(&block) : block.call

  raise "Use next to return the table" if String === tsv

  table_code = options[:table_id] || (rand * 100000).to_i.to_s
  table_code = Entity::REST.clean_element(table_code)
  table_code.sub!(/[^\w]/,'_')

  if @step
    table_file = @step.file(table_code) if @step

    url = add_GET_param(@uri, "_fragment", File.basename(table_file))
    url = remove_GET_param(url, "_update")
    url = remove_GET_param(url, "_layout")
    url = remove_GET_param(url, "_")
  end

  table_class = options[:table_class] || options[:class] || []
  table_class = [table_class] unless Array === table_class
  table_class << 'wide responsive' if tsv.fields.length > 4

  options[:url] = url
  options[:table_class] = table_class
  options[:tsv_entity_options] = tsv.entity_options

  if @table_headers and @table_headers.any?
    options[:headers] = @table_headers
    @table_headers = {}
  end

  if tsv.entity_templates and tsv.entity_templates.any?
    options[:headers] ||= {}
    tsv.entity_templates.each do |field,template|
      next if options[:headers].include? field
      next if template.nil?

      info = template.info
      info.delete :format
      info.delete :annotation_types
      info.delete :annotated_array

      options[:headers][field] = [template.annotation_types.last.to_s, info]
    end
  end

  if @table_filters and @table_filters.any?
    options[:filters] = @table_filters
    @table_filters = {}
  end

  if table_file
    Open.write table_file, tsv.to_s
    Open.write table_file + '.table_options', options.to_yaml if defined? options.any?

    total_size = tsv.size
    if options[:page].nil?  and total_size > PAGE_SIZE * 1.2
      @page = "1"
    else
      @page = options[:page]
    end
    tsv2html(table_file, options)
  else
    tsv2html(tsv, options)
  end
end
table_value(value, type = nil, options = {}) click to toggle source
# File lib/rbbt/rest/common/table.rb, line 340
def table_value(value, type = nil, options = {})
  options = {} if options.nil?
  return value.list_link :length, options[:list_id] if Array === value and options[:list_id] and value.respond_to? :list_link

  entity_options = options[:entity_options]

  value = Misc.prepare_entity(value, type, entity_options) if Entity.formats[type] and not options[:unnamed]

  orig_value = value
  value = value.link if value.respond_to? :link and not options[:unnamed]

  if Array === value and value.length > 100
    strip = value.length
    value = value[0..99]
  end

  res = case options[:span]
        when 'semicolon'
          if Array === value
            value.collect do |val|
              val.split(";").collect{|v| "<span class='table_value'>#{v.to_s}</span>" } * ";"
            end * ", "
          else
            value.split(";").collect{|v| "<span class='table_value'>#{v.to_s}</span>" } * ";"
          end
        when true, "true", :true
          Array === value ? value.collect{|v| "<span class='table_value'>#{v.to_s}</span>"} * ", " : "<span class='table_value'>#{value}</span>"
        when :long, "long"
          Array === value ? value.zip(orig_value).collect{|v,ov| "<span class='table_value long' title='#{CGI.escape(ov.to_s)}'>#{v.to_s}</span>"} * " " : "<span class='table_value long' title='#{CGI.escape(orig_value)}'>#{value}</span>"
        when :lines, "lines"
          Array === value ? value.zip(orig_value).collect{|v,ov| "<span class='table_value long lines' title='#{CGI.escape(ov.to_s)}'>#{v.to_s}<br/></span>"} * " " : "<span class='table_value long lines' title='#{CGI.escape(orig_value)}'>#{value}</span>"
        else
          Array === value ? value.collect{|v| v.to_s} * ", " : value
        end

  res = "<span class='table_value strip'>[#{ strip } entries, 100 shown]</span> " + res if strip

  res
end
tabs(&block) click to toggle source
# File lib/rbbt/rest/common/tabs.rb, line 32
def tabs(&block)
  tab = Tabs.new(self)
  block.call(tab)

  tab.headers.each do |header|
    code = tab.codes[header] || Misc.digest(header)
    content = tab.content[header]
  end

  partial_render('partials/tabs', :headers => tab.headers, :codes => tab.codes, :content => tab.content, :active => tab.active)
end
tar_file(id, name, value) click to toggle source
# File lib/rbbt/rest/common/forms.rb, line 26
def tar_file(id, name, value)
  tar_msg = "File in tar.gz format with directory as only first level entry"

  html_tag("input", nil, :type => "file", :id => (id.nil? ? nil : id +  "__" + "param_file"), :name => name.to_s + "__" + "param_file") + 
  html_tag("span", tar_msg, :class => "file_or_text_area")
end
template_render(template, locals = {}, cache = nil, cache_options = {}) click to toggle source
# File lib/rbbt/rest/common/render.rb, line 124
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
traverse(items, msg = nil, max = nil, options = {}, &block) click to toggle source
# File lib/rbbt/rest/common/misc.rb, line 35
def traverse(items, msg = nil, max = nil, options = {}, &block)
  options[:msg] = msg if msg
  options[:max] = max if max
  msg, max = Misc.process_options options, :msg, :max
  max = TSV.guess_max max if max.nil?
  msg = "Processing" if msg.nil?
  bar = @step.progress_bar(msg, :max => max)
  TSV.traverse items, options.merge(:bar => bar), &block
end
tsv2html(file, default_table_options = {}) click to toggle source
# File lib/rbbt/rest/common/table.rb, line 501
def tsv2html(file, default_table_options = {})
  if TSV === file
    tsv, table_options = file, {}
    table_options[:unnamed] = tsv.unnamed
  else
    tsv, table_options = load_tsv(file)
  end

  table_options[:heatmap] = (tsv.cast && %w(to_i to_f).include?(tsv.cast.to_s) && tsv.fields.length > 1) unless table_options.include? :heatmap

  table_options = default_table_options.merge(table_options)
  table_options[:page] = @page if @page
  table_options[:filter] = @filter if @filter
  table_options[:column] = @column if @column

  content_type "text/html"
  rows, length = tsv_rows(tsv, table_options[:page], table_options[:filter], table_options[:column])

  partial_render('partials/table', {:total_size => length, :rows => rows, :header => tsv.all_fields, :table_options => table_options})
end
tsv_process(tsv, filter = nil, column = nil) click to toggle source
# File lib/rbbt/rest/common/table.rb, line 245
def tsv_process(tsv, filter = nil, column = nil)
  filter = @filter if filter.nil?
  column = @column if column.nil?

  if filter and filter.to_s != "false"
    filter.split(";;").each do |f|
      key, value = f.split("~")
      orig_key = key
      format = Entity.formats.find(key)
      type = Entity.formats[format] if format
      next if value.nil? or value.empty?

      value =  Entity::REST.restore_element(value)

      #invert
      if value =~ /^!\s*(.*)/
        value = $1
        invert = true
      else
        invert = false
      end

      #name
      if value =~ /^:name:\s*(.*)/
        value = $1
        name = true
      else
        name = false
      end

      #length
      if value =~ /^:length:\s*(.*)/
        value = $1
        length = true
      else
        length = false
      end

      if name
        old_tsv = tsv
        tsv = tsv.reorder(:key, key).add_field "NAME" do |k,values|
          NamedArray === values ? values[key].name : values.name
        end
        key = "NAME"
      end
      
      if length
        old_tsv = tsv
        tsv = tsv.reorder(:key, key).add_field "LENGTH" do |k,values|
          NamedArray === values ? 
            (values[key] ? values[key].length.to_s : "0") : 
            values.length.to_s
        end
        key = "LENGTH"
      end
      
      case
      when value =~ /^(%in%)\s*(.*)/ 
        raise "Entity type not recognized for field: #{orig_key}" if type.nil?
        list_name = $2
        list = Entity::List.load_list(type, list_name)
        tsv = tsv.select(key, invert){|k| k = k.first if Array === k; (k.nil? or (String === k and k.empty?)) ? false : list.include?(k)}
      when value =~ /^([<>]=?)(.*)/
        tsv = tsv.select(key, invert){|k| k = k.first if Array === k; (k.nil? or (String === k and k.empty?)) ? false : k.to_f.send($1, $2.to_f)}
      when value =~ /^\/(.+)\/.{0,2}\s*$/
        tsv = tsv.select({key => Regexp.new($1)}, invert)
      when (value =~ /^\d+$/ and tsv.type == :double or tsv.type == :flat)
        tsv = tsv.select({key => value.to_i}, invert)
      else
        tsv = tsv.select({key => value}, invert)
      end

      tsv = old_tsv.select(tsv.keys) if name or length

    end
  end


  tsv = tsv.column(column) if column and not column.empty?

  tsv
end
tsv_rows(tsv, page = nil, filter = nil, column = nil) click to toggle source
# File lib/rbbt/rest/common/table.rb, line 328
def tsv_rows(tsv, page = nil, filter = nil, column = nil)
  tsv = tsv_process(tsv, filter, column)
  length = tsv.size
  page = @page if page.nil?
  if page.nil? or page.empty? or page.to_s == "false"
    [tsv_rows_full(tsv), length]
  else
    [tsv_rows_full(paginate(tsv, page)), length]
  end
end
tsv_rows_full(tsv) click to toggle source
# File lib/rbbt/rest/common/table.rb, line 175
def tsv_rows_full(tsv)
  case tsv.type 
  when :single
    tsv.collect{|id, value| [id, value]}
  when :list
    key_field = tsv.key_field
    tsv.collect{|id, values| new_values = [id].concat(values); begin NamedArray.setup(new_values, values.fields, id, values.entity_options, values.entity_templates); new_values.fields = [key_field].concat values.fields end if values.respond_to? :fields; new_values }
  when :flat
    key_field = tsv.key_field
    tsv.collect{|id, values| [id, values]}
  when :double
    key_field = tsv.key_field
    tsv.collect{|id, value_lists| new_value_lists = [id].concat(value_lists); begin NamedArray.setup(new_value_lists, value_lists.fields, id, value_lists.entity_options, value_lists.entity_templates); new_value_lists.fields = ([key_field].concat value_lists.fields) end if value_lists.respond_to? :fields; new_value_lists }
  end
end
wait_on(job, layout = nil) click to toggle source
# File lib/rbbt/rest/common/render.rb, line 43
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