rack-r 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +36 -21
- data/RECEIPES.md +30 -0
- data/lib/rack_r/middleware.rb +41 -12
- data/lib/rack_r/template_handler.rb +19 -0
- data/lib/rack_r/version.rb +1 -1
- data/lib/rack_r.rb +4 -2
- metadata +9 -10
data/README.md
CHANGED
@@ -11,13 +11,13 @@ simple as rendering R code into your output. E.g.
|
|
11
11
|
</script>
|
12
12
|
|
13
13
|
RackR will pick this up on its way out and replace it with an empty
|
14
|
-
container and some JavaScript code to perform an immediate
|
15
|
-
request for processing the R code.
|
14
|
+
container and some JavaScript code to perform an immediate
|
15
|
+
asynchronous request for processing the R code.
|
16
16
|
|
17
|
-
RackR will answer to this
|
18
|
-
directory, then searching this directory for displayable
|
19
|
-
finally return the html code for display. So the example
|
20
|
-
eventually turn into something like this
|
17
|
+
RackR will answer to this request with processing the R code in a
|
18
|
+
temporary directory, then searching this directory for displayable
|
19
|
+
content, and finally return the html code for display. So the example
|
20
|
+
above will eventually turn into something like this:
|
21
21
|
|
22
22
|
<div>
|
23
23
|
<img src='/path/to/sinus.png' />
|
@@ -26,9 +26,9 @@ eventually turn into something like this.
|
|
26
26
|
</pre>
|
27
27
|
</div>
|
28
28
|
|
29
|
-
Almost everything can conveniently be configured in a YAML file
|
30
|
-
will create a sample config file in `config/rack-r.yml` or any
|
31
|
-
path given.
|
29
|
+
**Almost everything can conveniently be configured in a YAML file.**
|
30
|
+
RackR will create a sample config file in `config/rack-r.yml` or any
|
31
|
+
other path given.
|
32
32
|
|
33
33
|
|
34
34
|
Install in Rails
|
@@ -51,6 +51,30 @@ Using RackR outside of Rails
|
|
51
51
|
use RackR::Middleware, :config => 'path/to/config/rack-r.yml'
|
52
52
|
|
53
53
|
|
54
|
+
The RackR-Header
|
55
|
+
----------------
|
56
|
+
|
57
|
+
The RackR-Header is a piece of R code that gets prepended to every R
|
58
|
+
script, which is processed by RackR. Ideally it will read your
|
59
|
+
database config and provide a seperate connection to your database via
|
60
|
+
a DBI compatible object. This is currently provided by a R function
|
61
|
+
called `connect`.
|
62
|
+
|
63
|
+
If you want RackR to automatically connect R scripts to your Rails
|
64
|
+
database it is a good idea to install Jeremy Stephens' YAML for R, as
|
65
|
+
mentioned in Dependencies.
|
66
|
+
|
67
|
+
Additionally there is a function `getPapertrail` which takes a
|
68
|
+
classname and an id, and retrieves previous versions of database entries
|
69
|
+
(stored by the popular versioning library
|
70
|
+
[Papertrail](https://github.com/airblade/paper_trail/)) in form of a
|
71
|
+
proper R dataframe.
|
72
|
+
|
73
|
+
The whole RackR-Header is a work in progress, if you have to adjust it
|
74
|
+
to your database config and/or end up writing helper functions like
|
75
|
+
`getPapertrail`, please consider to contribute your additions.
|
76
|
+
|
77
|
+
|
54
78
|
Dependencies
|
55
79
|
------------
|
56
80
|
|
@@ -58,17 +82,11 @@ These instructions are for Debian Squeeze. Install R.
|
|
58
82
|
|
59
83
|
apt-get install r-base r-cran-dbi
|
60
84
|
|
61
|
-
Alternatively you can use the `rodbc` package.
|
85
|
+
Alternatively to `dbi` you can use the `rodbc` package.
|
62
86
|
|
63
87
|
apt-get install r-cran-rodbc
|
64
88
|
|
65
|
-
|
66
|
-
script which is processed by RackR. Idealy it will read you database
|
67
|
-
config and provide a seperate connection to your database via a DBI
|
68
|
-
compatible `con` object.
|
69
|
-
|
70
|
-
If you want RackR to automatically connect R script to yoyr Rails
|
71
|
-
database it is a good idea to install Jeremy Stephens' YAML for R.
|
89
|
+
### YAML
|
72
90
|
|
73
91
|
wget http://cran.r-project.org/src/contrib/yaml_2.1.4.tar.gz
|
74
92
|
R CMD INSTALL yaml_2.1.4.tar.gz
|
@@ -82,9 +100,6 @@ database it is a good idea to install Jeremy Stephens' YAML for R.
|
|
82
100
|
|
83
101
|
apt-get install r-cran-rmysql
|
84
102
|
|
85
|
-
The whole RackR-Header is a work in progress, if you have to adjust it
|
86
|
-
to your database config, please consider to contribute your addition.
|
87
|
-
|
88
103
|
|
89
104
|
Trouble shooting
|
90
105
|
----------------
|
@@ -103,4 +118,4 @@ a line.
|
|
103
118
|
License
|
104
119
|
-------
|
105
120
|
|
106
|
-
RackR is released under MIT License, see LICENSE.
|
121
|
+
RackR is released under MIT License, see LICENSE.
|
data/RECEIPES.md
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
Receipes
|
2
|
+
========
|
3
|
+
|
4
|
+
Boxplot the ages of users
|
5
|
+
-------------------------
|
6
|
+
|
7
|
+
svg('0_user_age.svg')
|
8
|
+
users <- dbReadTable(con, 'users')
|
9
|
+
users$age <- round(as.numeric(as.Date(users$birth_date) - Sys.Date()) / -365.25)
|
10
|
+
boxplot(users$age)
|
11
|
+
|
12
|
+
|
13
|
+
Output a html table of data
|
14
|
+
---------------------------
|
15
|
+
|
16
|
+
some_data <- dbReadTable(con, 'some_table')
|
17
|
+
write.csv(some_data, file='some_data.csv')
|
18
|
+
|
19
|
+
|
20
|
+
Control the order of content
|
21
|
+
----------------------------
|
22
|
+
|
23
|
+
The resulting files are processed/included aplhabetically. So if you
|
24
|
+
name you output devices accordingly, you can control the order. E.g.
|
25
|
+
|
26
|
+
svg('1st_graphic_is_a_sinus.svg')
|
27
|
+
plot(sin)
|
28
|
+
svg('2nd_graphic_is_a_cosinus.svg')
|
29
|
+
plot(cos)
|
30
|
+
|
data/lib/rack_r/middleware.rb
CHANGED
@@ -10,6 +10,8 @@ module RackR
|
|
10
10
|
def call(env)
|
11
11
|
@env = env
|
12
12
|
return call_app unless config.enabled
|
13
|
+
return call_app if config.skip_pattern &&
|
14
|
+
path_info.match(config.skip_pattern)
|
13
15
|
if get? and md = match_path
|
14
16
|
key = md.to_a.last
|
15
17
|
return [200, {}, ['RackR OK.']] if key.empty?
|
@@ -160,21 +162,34 @@ r_header: |
|
|
160
162
|
# modify this header in rack-r config file
|
161
163
|
library(yaml)
|
162
164
|
library(DBI)
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
165
|
+
root <- '/home/phil/src/controlling'
|
166
|
+
dbconf <- yaml.load_file(paste(root, '/config/database.yml', sep=''))$development
|
167
|
+
connect <- function() {
|
168
|
+
if(dbconf$adapter=='sqlite3') {
|
169
|
+
library(RSQLite)
|
170
|
+
dbfile <- paste(root, '/', dbconf$database, sep='')
|
171
|
+
drv <- dbDriver("SQLite")
|
172
|
+
return(dbConnect(drv, dbname=dbfile))
|
173
|
+
} else if (dbconf$adapter=='mysql') {
|
174
|
+
library(RMySQL)
|
175
|
+
return(dbConnect(MySQL(), user=dbconf$username, dbname=dbconf$database))
|
176
|
+
}
|
177
|
+
}
|
178
|
+
getPapertrail <- function(model, id) {
|
179
|
+
sql <- paste("SELECT object FROM versions WHERE ",
|
180
|
+
"item_type='", model, "' AND item_id='",
|
181
|
+
id, "' AND event='update'", sep='')
|
182
|
+
connection <- connect()
|
183
|
+
result <- dbSendQuery(connection, sql)
|
184
|
+
rows <- fetch(result)
|
185
|
+
lapply(rows$object, yaml.load)
|
186
|
+
}
|
169
187
|
ajaxer: |
|
170
188
|
<div class='rack_r' id='<%= key %>'>Processing R...</div>
|
171
189
|
<script type='text/javascript'>
|
172
190
|
var url = '<%= config.url_scope %>/<%= key %>';
|
173
191
|
$.ajax(url, { success: function(data) { $('#<%= key %>').html(data); } });
|
174
192
|
</script>
|
175
|
-
html:
|
176
|
-
prefix: <div class='rack_r_out'>
|
177
|
-
suffix: </div>
|
178
193
|
templates:
|
179
194
|
- pattern: .svg$
|
180
195
|
process: |
|
@@ -189,15 +204,18 @@ templates:
|
|
189
204
|
url = "#{config.public_url}/#{file}"
|
190
205
|
template: |
|
191
206
|
<img src='<%= url %>' />
|
192
|
-
- pattern: .csv$
|
207
|
+
- pattern: .download.csv$
|
193
208
|
process: |
|
194
|
-
table = CSV.read(src)
|
195
209
|
# TODO build dst with key, otherwise may lead to undesired results
|
196
210
|
dst = File.join(public_path, file)
|
197
211
|
FileUtils.cp(src, dst)
|
198
212
|
url = "#{config.public_url}/#{file}"
|
199
213
|
template: |
|
200
214
|
<a href='<%= url %>'><%= file %></a>
|
215
|
+
- pattern: .table.csv$
|
216
|
+
process: |
|
217
|
+
table = CSV.read(src)
|
218
|
+
template: |
|
201
219
|
<table>
|
202
220
|
<% table.each do |row| %>
|
203
221
|
<tr>
|
@@ -207,12 +225,23 @@ templates:
|
|
207
225
|
</tr>
|
208
226
|
<% end %>
|
209
227
|
</table>
|
228
|
+
- pattern: .lazy.csv$
|
229
|
+
process: |
|
230
|
+
table = CSV.read(src)
|
231
|
+
template: |
|
232
|
+
<pre class="lazycsv"><%= table %></pre>
|
210
233
|
- pattern: .Rout$
|
211
234
|
process: |
|
212
235
|
rout = File.read(src)
|
213
236
|
template: |
|
214
237
|
<pre><%= rout %></pre>
|
215
|
-
node_regex:
|
238
|
+
node_regex: <script\s+type=['"]text/r['"]\s*>(.*?)</script>
|
239
|
+
node_stanza:
|
240
|
+
prefix: <script type='text/r'>
|
241
|
+
suffix: </script>
|
242
|
+
html:
|
243
|
+
prefix: <div class='rack_r_out'>
|
244
|
+
suffix: </div>
|
216
245
|
#
|
217
246
|
# uncomment the following two lines, if your project
|
218
247
|
# doesn't use jquery already
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module RackR
|
2
|
+
class TemplateHandler
|
3
|
+
def call(template)
|
4
|
+
[ "'<script type=\\'text/r\\'>",
|
5
|
+
escape_text(template.source),
|
6
|
+
"</script>'.html_safe" ].join
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
# stolen from erubis
|
12
|
+
def escape_text(text)
|
13
|
+
text.gsub(/['\\]/, '\\\\\&') # "'" => "\\'", '\\' => '\\\\'
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
ActionView::Template.register_template_handler :rackr, RackR::TemplateHandler.new
|
data/lib/rack_r/version.rb
CHANGED
data/lib/rack_r.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,12 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-r
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
4
|
+
prerelease: false
|
6
5
|
segments:
|
7
6
|
- 0
|
8
7
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
8
|
+
- 1
|
9
|
+
version: 0.1.1
|
11
10
|
platform: ruby
|
12
11
|
authors:
|
13
12
|
- Phil Hofmann
|
@@ -15,7 +14,8 @@ autorequire:
|
|
15
14
|
bindir: bin
|
16
15
|
cert_chain: []
|
17
16
|
|
18
|
-
date:
|
17
|
+
date: 2013-05-20 00:00:00 +02:00
|
18
|
+
default_executable:
|
19
19
|
dependencies: []
|
20
20
|
|
21
21
|
description: Use R in your Rack stack
|
@@ -33,16 +33,19 @@ files:
|
|
33
33
|
- Gemfile
|
34
34
|
- LICENSE
|
35
35
|
- README.md
|
36
|
+
- RECEIPES.md
|
36
37
|
- Rakefile
|
37
38
|
- TODO
|
38
39
|
- lib/rack_r.rb
|
39
40
|
- lib/rack_r/middleware.rb
|
40
41
|
- lib/rack_r/railtie.rb
|
42
|
+
- lib/rack_r/template_handler.rb
|
41
43
|
- lib/rack_r/version.rb
|
42
44
|
- rack-r.gemspec
|
43
45
|
- test/example.r
|
44
46
|
- test/helper.rb
|
45
47
|
- test/test_rack_r.rb
|
48
|
+
has_rdoc: true
|
46
49
|
homepage: http://branch14.org/rack-r
|
47
50
|
licenses: []
|
48
51
|
|
@@ -53,27 +56,23 @@ require_paths:
|
|
53
56
|
- lib
|
54
57
|
- rails
|
55
58
|
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
-
none: false
|
57
59
|
requirements:
|
58
60
|
- - ">="
|
59
61
|
- !ruby/object:Gem::Version
|
60
|
-
hash: 3
|
61
62
|
segments:
|
62
63
|
- 0
|
63
64
|
version: "0"
|
64
65
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
66
|
requirements:
|
67
67
|
- - ">="
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
hash: 3
|
70
69
|
segments:
|
71
70
|
- 0
|
72
71
|
version: "0"
|
73
72
|
requirements: []
|
74
73
|
|
75
74
|
rubyforge_project:
|
76
|
-
rubygems_version: 1.
|
75
|
+
rubygems_version: 1.3.6
|
77
76
|
signing_key:
|
78
77
|
specification_version: 3
|
79
78
|
summary: Use R in your Rack stack
|