Class: RackR::Middleware

Inherits:
Struct
  • Object
show all
Defined in:
lib/rack_r/middleware.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#appObject

Returns the value of attribute app

Returns:

  • (Object)

    the current value of app



8
9
10
# File 'lib/rack_r/middleware.rb', line 8

def app
  @app
end

#optionsObject

Returns the value of attribute options

Returns:

  • (Object)

    the current value of options



8
9
10
# File 'lib/rack_r/middleware.rb', line 8

def options
  @options
end

Instance Method Details

#ajaxer(key) ⇒ Object



109
110
111
# File 'lib/rack_r/middleware.rb', line 109

def ajaxer(key)
  ERB.new(config.ajaxer).result(binding)
end

#call(env) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
# File 'lib/rack_r/middleware.rb', line 10

def call(env)
  @env = env
  return call_app unless config.enabled
  if get? and md = match_path
    key = md.to_a.last
    return [200, {}, ['RackR OK.']] if key.empty?
    process key
  else
    extract
  end
end

#call_appObject



22
23
24
# File 'lib/rack_r/middleware.rb', line 22

def call_app
  app.call(@env)
end

#configObject



123
124
125
126
127
# File 'lib/rack_r/middleware.rb', line 123

def config
  return @config unless @config.nil?
  write_file(config_path, default_config) unless ::File.exist?(config_path)
  @config = deep_ostruct(::File.open(config_path) { |yf| YAML::load(yf) })
end

#config_pathObject



117
118
119
120
121
# File 'lib/rack_r/middleware.rb', line 117

def config_path
  options[:config].tap do |path|
    raise "no config path given" unless path
  end
end

#default_configObject



113
114
115
# File 'lib/rack_r/middleware.rb', line 113

def default_config
  ::File.read(__FILE__).gsub(/.*__END__\n/m, '')
end

#exec_r_script(file, path = nil) ⇒ Object



88
89
90
91
92
# File 'lib/rack_r/middleware.rb', line 88

def exec_r_script(file, path=nil)
  cmd = path.nil? ? "R CMD BATCH #{file}" :
    "(cd #{path} && R CMD BATCH #{file})"
  %x[#{cmd}]
end

#extractObject



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/rack_r/middleware.rb', line 26

def extract
  status, headers, response = call_app
  if headers["Content-Type"] =~ /text\/html|application\/xhtml\+xml/
    # TODO if contains <script type="text/r">
    body = ""
    response.each { |part| body << part }
    while md = body.match(node_regex)
      tempdir = temp_dir
      key = File.basename(tempdir)
      r_script = ERB.new(config.r_header).result(binding) + md.to_a.last
      write_file(File.join(tempdir, config.r_file), r_script)
      body.sub!(node_regex, ajaxer(key))
    end
    headers["Content-Length"] = body.length.to_s
    response = [ body ]
  end
  [ status, headers, response ]
end

#get?Boolean

return true if request method is GET

Returns:

  • (Boolean)


67
68
69
# File 'lib/rack_r/middleware.rb', line 67

def get?
  @env["REQUEST_METHOD"] == "GET"
end

#match_pathObject



84
85
86
# File 'lib/rack_r/middleware.rb', line 84

def match_path
  path_info.match(path_regex)
end

#node_regexObject



75
76
77
78
# File 'lib/rack_r/middleware.rb', line 75

def node_regex
  opts = Regexp::IGNORECASE + Regexp::MULTILINE
  Regexp.new config.node_regex, opts
end

#path_infoObject



80
81
82
# File 'lib/rack_r/middleware.rb', line 80

def path_info
  @env["PATH_INFO"]
end

#path_regexObject



71
72
73
# File 'lib/rack_r/middleware.rb', line 71

def path_regex
  Regexp.new "^#{config.url_scope}/(.*)"
end

#process(key) ⇒ Object



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/rack_r/middleware.rb', line 45

def process(key)
  path = temp_dir(key)
  return call_app unless File.directory?(path) # TODO render error msg
  time = exec_r_script(config.r_file, path)
  files = Dir.entries(path).sort
  # build body
  body = [ config.html.prefix ]
  files.each do |file|
    config.templates.each do |template|
      if file =~ Regexp.new(template['pattern'], Regexp::IGNORECASE)
        src = File.join(path, file)
        eval(template['process']) unless template['process'].nil?
        body << ERB.new(template['template']).result(binding)
      end
    end
  end
  # TODO remove temp dir
  body << config.html.suffix
  [ 200, { "Content-Type" => "text/html" }, body ]
end

#public_pathObject



103
104
105
106
107
# File 'lib/rack_r/middleware.rb', line 103

def public_path
  config.public_path.tap do |path|
    FileUtils.mkdir_p(path) unless File.directory?(path)
  end
end

#temp_dir(key = nil) ⇒ Object



94
95
96
97
# File 'lib/rack_r/middleware.rb', line 94

def temp_dir(key=nil)
  return Dir.mktmpdir(config.temp.prefix, config.temp.dir) if key.nil?
  File.join config.temp.dir, key
end

#write_file(path, content) ⇒ Object



99
100
101
# File 'lib/rack_r/middleware.rb', line 99

def write_file(path, content)
  ::File.open(path, 'w') { |f| f.puts content }
end