thin_upload 0.0.1.pre1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +7 -0
- data/Gemfile.lock +31 -0
- data/Manifest +44 -0
- data/README.rdoc +40 -0
- data/Rakefile +33 -0
- data/html/README_rdoc.html +133 -0
- data/html/Thin.html +149 -0
- data/html/Thin/Request.html +537 -0
- data/html/Thin/Server.html +194 -0
- data/html/created.rid +4 -0
- data/html/images/brick.png +0 -0
- data/html/images/brick_link.png +0 -0
- data/html/images/bug.png +0 -0
- data/html/images/bullet_black.png +0 -0
- data/html/images/bullet_toggle_minus.png +0 -0
- data/html/images/bullet_toggle_plus.png +0 -0
- data/html/images/date.png +0 -0
- data/html/images/find.png +0 -0
- data/html/images/loadingAnimation.gif +0 -0
- data/html/images/macFFBgHack.png +0 -0
- data/html/images/package.png +0 -0
- data/html/images/page_green.png +0 -0
- data/html/images/page_white_text.png +0 -0
- data/html/images/page_white_width.png +0 -0
- data/html/images/plugin.png +0 -0
- data/html/images/ruby.png +0 -0
- data/html/images/tag_green.png +0 -0
- data/html/images/wrench.png +0 -0
- data/html/images/wrench_orange.png +0 -0
- data/html/images/zoom.png +0 -0
- data/html/index.html +124 -0
- data/html/js/darkfish.js +116 -0
- data/html/js/jquery.js +32 -0
- data/html/js/quicksearch.js +114 -0
- data/html/js/thickbox-compressed.js +10 -0
- data/html/lib/thin_upload/parser_rb.html +54 -0
- data/html/lib/thin_upload/request_rb.html +54 -0
- data/html/lib/thin_upload_rb.html +54 -0
- data/html/rdoc.css +763 -0
- data/lib/thin_upload.rb +3 -0
- data/lib/thin_upload/request.rb +93 -0
- data/test/test_helper.rb +30 -0
- data/test/thin_upload/request_test.rb +91 -0
- data/thin_upload.gemspec +33 -0
- metadata +111 -0
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
allison (2.0.3)
|
5
|
+
daemons (1.1.4)
|
6
|
+
echoe (4.6.1)
|
7
|
+
allison (>= 2.0.3)
|
8
|
+
gemcutter (>= 0.7.0)
|
9
|
+
rake (>= 0.9.2)
|
10
|
+
rdoc (>= 3.6.1)
|
11
|
+
rubyforge (>= 2.0.4)
|
12
|
+
eventmachine (0.12.10)
|
13
|
+
gemcutter (0.7.0)
|
14
|
+
json_pure (1.6.1)
|
15
|
+
rack (1.3.3)
|
16
|
+
rake (0.9.2)
|
17
|
+
rdoc (3.9.4)
|
18
|
+
rubyforge (2.0.4)
|
19
|
+
json_pure (>= 1.1.7)
|
20
|
+
thin (1.2.11)
|
21
|
+
daemons (>= 1.0.9)
|
22
|
+
eventmachine (>= 0.12.6)
|
23
|
+
rack (>= 1.0.0)
|
24
|
+
|
25
|
+
PLATFORMS
|
26
|
+
ruby
|
27
|
+
|
28
|
+
DEPENDENCIES
|
29
|
+
echoe
|
30
|
+
rdoc
|
31
|
+
thin
|
data/Manifest
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
Gemfile
|
2
|
+
Gemfile.lock
|
3
|
+
Manifest
|
4
|
+
README.rdoc
|
5
|
+
Rakefile
|
6
|
+
html/README_rdoc.html
|
7
|
+
html/Thin.html
|
8
|
+
html/Thin/Request.html
|
9
|
+
html/Thin/Server.html
|
10
|
+
html/created.rid
|
11
|
+
html/images/brick.png
|
12
|
+
html/images/brick_link.png
|
13
|
+
html/images/bug.png
|
14
|
+
html/images/bullet_black.png
|
15
|
+
html/images/bullet_toggle_minus.png
|
16
|
+
html/images/bullet_toggle_plus.png
|
17
|
+
html/images/date.png
|
18
|
+
html/images/find.png
|
19
|
+
html/images/loadingAnimation.gif
|
20
|
+
html/images/macFFBgHack.png
|
21
|
+
html/images/package.png
|
22
|
+
html/images/page_green.png
|
23
|
+
html/images/page_white_text.png
|
24
|
+
html/images/page_white_width.png
|
25
|
+
html/images/plugin.png
|
26
|
+
html/images/ruby.png
|
27
|
+
html/images/tag_green.png
|
28
|
+
html/images/wrench.png
|
29
|
+
html/images/wrench_orange.png
|
30
|
+
html/images/zoom.png
|
31
|
+
html/index.html
|
32
|
+
html/js/darkfish.js
|
33
|
+
html/js/jquery.js
|
34
|
+
html/js/quicksearch.js
|
35
|
+
html/js/thickbox-compressed.js
|
36
|
+
html/lib/thin_upload/parser_rb.html
|
37
|
+
html/lib/thin_upload/request_rb.html
|
38
|
+
html/lib/thin_upload_rb.html
|
39
|
+
html/rdoc.css
|
40
|
+
lib/thin_upload.rb
|
41
|
+
lib/thin_upload/request.rb
|
42
|
+
test/test_helper.rb
|
43
|
+
test/thin_upload/request_test.rb
|
44
|
+
thin_upload.gemspec
|
data/README.rdoc
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
{<img src="http://travis-ci.org/dombesz/thin_upload.png" />}[http://travis-ci.org/dombesz/thin_upload]
|
2
|
+
|
3
|
+
=Install
|
4
|
+
|
5
|
+
gem install thin_upload --pre
|
6
|
+
|
7
|
+
=Usage
|
8
|
+
|
9
|
+
In your Gemfile
|
10
|
+
gem "thin"
|
11
|
+
gem "thin_upload", "~> 0.0.1.pre"
|
12
|
+
|
13
|
+
Note: Works only with thin server!
|
14
|
+
|
15
|
+
Upload progress is available for any file upload request.
|
16
|
+
|
17
|
+
Example:
|
18
|
+
<iframe id="upload_frame" name="upload_frame" style="width: 0px; height: 0px;"></iframe>
|
19
|
+
|
20
|
+
<%= form_tag(photos_path, {:multipart => true ,:target=>"upload_frame"}) do %>
|
21
|
+
<%= text_field_tag :uuid, UUID.new.generate %>
|
22
|
+
<%= file_field_tag :file %>
|
23
|
+
<p><%= submit_tag "Continue →".html_safe, :id=>'submit_form' %></p>
|
24
|
+
<% end %>
|
25
|
+
|
26
|
+
To have progress tracking, we need to send a +uuid param in the submited form,
|
27
|
+
and the +uuid param MUST be before the file field.
|
28
|
+
|
29
|
+
If you want to ask for progress use get request.
|
30
|
+
|
31
|
+
$.getJSON('/progress?uuid='+$("#uuid").attr('value'),function(response){
|
32
|
+
//process response
|
33
|
+
}
|
34
|
+
|
35
|
+
While your upload is processing you can request the progress from rack.
|
36
|
+
|
37
|
+
@progress = request.env['rack.progress'][params[:uuid]]
|
38
|
+
@progress is an integer in range 0..100 or nil if doesn't exists
|
39
|
+
|
40
|
+
Note: This is just an experiment, so I don't know if it's production ready. Any suggestions are welcome.
|
data/Rakefile
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
begin
|
2
|
+
require 'psych'
|
3
|
+
rescue ::LoadError
|
4
|
+
end
|
5
|
+
require 'rubygems'
|
6
|
+
require 'rake'
|
7
|
+
require 'echoe'
|
8
|
+
require 'rake/testtask'
|
9
|
+
|
10
|
+
|
11
|
+
Echoe.new('thin_upload', '0.0.1.pre1') do |p|
|
12
|
+
p.summary = "Upload progress meter for thin ruby server."
|
13
|
+
p.description = "thin_upload provides upload progress measuring functionality for thin ruby server, progresses can be accessed via rack middleware."
|
14
|
+
p.author = 'Dombi Attila'
|
15
|
+
p.email = 'dombesz.attila-at-gmail.com'
|
16
|
+
p.url = 'https://github.com/dombesz/thin_upload'
|
17
|
+
p.ignore_pattern = ["tmp/*", "script/*"]
|
18
|
+
p.development_dependencies = ['thin']
|
19
|
+
end
|
20
|
+
|
21
|
+
Dir["#{File.dirname(__FILE__)}/tasks/*.rake"].sort.each { |ext| load ext }
|
22
|
+
|
23
|
+
Rake::TestTask.new do |t|
|
24
|
+
t.libs << 'test'
|
25
|
+
end
|
26
|
+
|
27
|
+
Rake::RDocTask.new do |rd|
|
28
|
+
rd.main = "README.rdoc"
|
29
|
+
rd.rdoc_files.include("README.rdoc", "lib/**/*.rb")
|
30
|
+
end
|
31
|
+
|
32
|
+
desc "Run tests"
|
33
|
+
task :default => :test
|
@@ -0,0 +1,133 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
3
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
4
|
+
|
5
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
6
|
+
<head>
|
7
|
+
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
|
8
|
+
|
9
|
+
<title>File: README.rdoc [RDoc Documentation]</title>
|
10
|
+
|
11
|
+
<link type="text/css" media="screen" href="./rdoc.css" rel="stylesheet" />
|
12
|
+
|
13
|
+
<script src="./js/jquery.js" type="text/javascript"
|
14
|
+
charset="utf-8"></script>
|
15
|
+
<script src="./js/thickbox-compressed.js" type="text/javascript"
|
16
|
+
charset="utf-8"></script>
|
17
|
+
<script src="./js/quicksearch.js" type="text/javascript"
|
18
|
+
charset="utf-8"></script>
|
19
|
+
<script src="./js/darkfish.js" type="text/javascript"
|
20
|
+
charset="utf-8"></script>
|
21
|
+
</head>
|
22
|
+
|
23
|
+
<body class="file">
|
24
|
+
<div id="metadata">
|
25
|
+
<div id="home-metadata">
|
26
|
+
<div id="home-section" class="section">
|
27
|
+
<h3 class="section-header">
|
28
|
+
<a href="./index.html">Home</a>
|
29
|
+
<a href="./index.html#classes">Classes</a>
|
30
|
+
<a href="./index.html#methods">Methods</a>
|
31
|
+
</h3>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div id="project-metadata">
|
36
|
+
|
37
|
+
|
38
|
+
<div id="fileindex-section" class="section project-section">
|
39
|
+
<h3 class="section-header">Files</h3>
|
40
|
+
<ul>
|
41
|
+
|
42
|
+
<li class="file"><a href="./README_rdoc.html">README.rdoc</a></li>
|
43
|
+
|
44
|
+
</ul>
|
45
|
+
</div>
|
46
|
+
|
47
|
+
|
48
|
+
<div id="classindex-section" class="section project-section">
|
49
|
+
<h3 class="section-header">Class Index
|
50
|
+
<span class="search-toggle"><img src="./images/find.png"
|
51
|
+
height="16" width="16" alt="[+]"
|
52
|
+
title="show/hide quicksearch" /></span></h3>
|
53
|
+
<form action="#" method="get" accept-charset="utf-8" class="initially-hidden">
|
54
|
+
<fieldset>
|
55
|
+
<legend>Quicksearch</legend>
|
56
|
+
<input type="text" name="quicksearch" value=""
|
57
|
+
class="quicksearch-field" />
|
58
|
+
</fieldset>
|
59
|
+
</form>
|
60
|
+
|
61
|
+
<ul class="link-list">
|
62
|
+
|
63
|
+
<li><a href="./Thin.html">Thin</a></li>
|
64
|
+
|
65
|
+
<li><a href="./Thin/Request.html">Thin::Request</a></li>
|
66
|
+
|
67
|
+
<li><a href="./Thin/Server.html">Thin::Server</a></li>
|
68
|
+
|
69
|
+
</ul>
|
70
|
+
<div id="no-class-search-results" style="display: none;">No matching classes.</div>
|
71
|
+
</div>
|
72
|
+
|
73
|
+
|
74
|
+
</div>
|
75
|
+
</div>
|
76
|
+
|
77
|
+
<div id="documentation">
|
78
|
+
|
79
|
+
<p><a href="http://travis-ci.org/dombesz/thin_upload"><img
|
80
|
+
src="http://travis-ci.org/dombesz/thin_upload.png" /></a></p>
|
81
|
+
|
82
|
+
<h1>Install</h1>
|
83
|
+
|
84
|
+
<pre>gem install thin_upload --pre</pre>
|
85
|
+
|
86
|
+
<h1>Usage</h1>
|
87
|
+
|
88
|
+
<p>In your Gemfile</p>
|
89
|
+
|
90
|
+
<pre>gem "thin"
|
91
|
+
gem "thin_upload", "~> 0.0.1.pre"</pre>
|
92
|
+
|
93
|
+
<p>Note: Works only with thin server!</p>
|
94
|
+
|
95
|
+
<p>Upload progress is available for any file upload request.</p>
|
96
|
+
|
97
|
+
<p>Example:</p>
|
98
|
+
|
99
|
+
<pre><iframe id="upload_frame" name="upload_frame" style="width: 0px; height: 0px;"></iframe>
|
100
|
+
|
101
|
+
<%= form_tag(photos_path, {:multipart => true ,:target=>"upload_frame"}) do %>
|
102
|
+
<%= text_field_tag :uuid, UUID.new.generate %>
|
103
|
+
<%= file_field_tag :file %>
|
104
|
+
<p><%= submit_tag "Continue &rarr;".html_safe, :id=>'submit_form' %></p>
|
105
|
+
<% end %></pre>
|
106
|
+
|
107
|
+
<p>To have progress tracking, we need to send a +uuid param in the submited
|
108
|
+
form, and the +uuid param MUST be before the file field.</p>
|
109
|
+
|
110
|
+
<p>If you want to ask for progress use get request.</p>
|
111
|
+
|
112
|
+
<pre>$.getJSON('/progress?uuid='+$("#uuid").attr('value'),function(response){
|
113
|
+
//process response
|
114
|
+
}</pre>
|
115
|
+
|
116
|
+
<p>While your upload is processing you can request the progress from rack.</p>
|
117
|
+
|
118
|
+
<pre>@progress = request.env['rack.progress'][params[:uuid]]
|
119
|
+
@progress is an integer in range 0..100 or nil if doesn't exists</pre>
|
120
|
+
|
121
|
+
<p>Note: This is just an experiment, so I don’t know if it’s production ready.
|
122
|
+
Any suggestions are welcome.</p>
|
123
|
+
|
124
|
+
</div>
|
125
|
+
|
126
|
+
<div id="validator-badges">
|
127
|
+
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
128
|
+
<p><small>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish
|
129
|
+
Rdoc Generator</a> 2</small>.</p>
|
130
|
+
</div>
|
131
|
+
</body>
|
132
|
+
</html>
|
133
|
+
|
data/html/Thin.html
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
3
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
4
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
5
|
+
<head>
|
6
|
+
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
|
7
|
+
|
8
|
+
<title>Module: Thin</title>
|
9
|
+
|
10
|
+
<link rel="stylesheet" href="./rdoc.css" type="text/css" media="screen" />
|
11
|
+
|
12
|
+
<script src="./js/jquery.js" type="text/javascript" charset="utf-8"></script>
|
13
|
+
<script src="./js/thickbox-compressed.js" type="text/javascript" charset="utf-8"></script>
|
14
|
+
<script src="./js/quicksearch.js" type="text/javascript" charset="utf-8"></script>
|
15
|
+
<script src="./js/darkfish.js" type="text/javascript" charset="utf-8"></script>
|
16
|
+
|
17
|
+
</head>
|
18
|
+
<body id="top" class="module">
|
19
|
+
|
20
|
+
<div id="metadata">
|
21
|
+
<div id="home-metadata">
|
22
|
+
<div id="home-section" class="section">
|
23
|
+
<h3 class="section-header">
|
24
|
+
<a href="./index.html">Home</a>
|
25
|
+
<a href="./index.html#classes">Classes</a>
|
26
|
+
<a href="./index.html#methods">Methods</a>
|
27
|
+
</h3>
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
|
31
|
+
<div id="file-metadata">
|
32
|
+
<div id="file-list-section" class="section">
|
33
|
+
<h3 class="section-header">In Files</h3>
|
34
|
+
<div class="section-body">
|
35
|
+
<ul>
|
36
|
+
|
37
|
+
<li><a href="./lib/thin_upload/request_rb.html?TB_iframe=true&height=550&width=785"
|
38
|
+
class="thickbox" title="lib/thin_upload/request.rb">lib/thin_upload/request.rb</a></li>
|
39
|
+
|
40
|
+
</ul>
|
41
|
+
</div>
|
42
|
+
</div>
|
43
|
+
|
44
|
+
|
45
|
+
</div>
|
46
|
+
|
47
|
+
<div id="class-metadata">
|
48
|
+
|
49
|
+
|
50
|
+
|
51
|
+
|
52
|
+
|
53
|
+
<!-- Namespace Contents -->
|
54
|
+
<div id="namespace-list-section" class="section">
|
55
|
+
<h3 class="section-header">Namespace</h3>
|
56
|
+
<ul class="link-list">
|
57
|
+
|
58
|
+
<li><span class="type">CLASS</span> <a href="Thin/Request.html">Thin::Request</a></li>
|
59
|
+
|
60
|
+
<li><span class="type">CLASS</span> <a href="Thin/Server.html">Thin::Server</a></li>
|
61
|
+
|
62
|
+
</ul>
|
63
|
+
</div>
|
64
|
+
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
</div>
|
70
|
+
|
71
|
+
<div id="project-metadata">
|
72
|
+
|
73
|
+
|
74
|
+
<div id="fileindex-section" class="section project-section">
|
75
|
+
<h3 class="section-header">Files</h3>
|
76
|
+
<ul>
|
77
|
+
|
78
|
+
<li class="file"><a href="./README_rdoc.html">README.rdoc</a></li>
|
79
|
+
|
80
|
+
</ul>
|
81
|
+
</div>
|
82
|
+
|
83
|
+
|
84
|
+
<div id="classindex-section" class="section project-section">
|
85
|
+
<h3 class="section-header">Class/Module Index
|
86
|
+
<span class="search-toggle"><img src="./images/find.png"
|
87
|
+
height="16" width="16" alt="[+]"
|
88
|
+
title="show/hide quicksearch" /></span></h3>
|
89
|
+
<form action="#" method="get" accept-charset="utf-8" class="initially-hidden">
|
90
|
+
<fieldset>
|
91
|
+
<legend>Quicksearch</legend>
|
92
|
+
<input type="text" name="quicksearch" value=""
|
93
|
+
class="quicksearch-field" />
|
94
|
+
</fieldset>
|
95
|
+
</form>
|
96
|
+
|
97
|
+
<ul class="link-list">
|
98
|
+
|
99
|
+
<li><a href="./Thin.html">Thin</a></li>
|
100
|
+
|
101
|
+
<li><a href="./Thin/Request.html">Thin::Request</a></li>
|
102
|
+
|
103
|
+
<li><a href="./Thin/Server.html">Thin::Server</a></li>
|
104
|
+
|
105
|
+
</ul>
|
106
|
+
<div id="no-class-search-results" style="display: none;">No matching classes.</div>
|
107
|
+
</div>
|
108
|
+
|
109
|
+
|
110
|
+
</div>
|
111
|
+
</div>
|
112
|
+
|
113
|
+
<div id="documentation">
|
114
|
+
<h1 class="module">Thin</h1>
|
115
|
+
|
116
|
+
<div id="description" class="description">
|
117
|
+
|
118
|
+
<p><a href="Thin.html">Thin</a> module from thin server</p>
|
119
|
+
|
120
|
+
</div><!-- description -->
|
121
|
+
|
122
|
+
|
123
|
+
|
124
|
+
|
125
|
+
<div id="5Buntitled-5D" class="documentation-section">
|
126
|
+
|
127
|
+
|
128
|
+
|
129
|
+
|
130
|
+
|
131
|
+
|
132
|
+
|
133
|
+
|
134
|
+
<!-- Methods -->
|
135
|
+
|
136
|
+
</div><!-- 5Buntitled-5D -->
|
137
|
+
|
138
|
+
|
139
|
+
</div><!-- documentation -->
|
140
|
+
|
141
|
+
<div id="validator-badges">
|
142
|
+
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
143
|
+
<p><small>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish
|
144
|
+
Rdoc Generator</a> 2</small>.</p>
|
145
|
+
</div>
|
146
|
+
|
147
|
+
</body>
|
148
|
+
</html>
|
149
|
+
|
@@ -0,0 +1,537 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
3
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
4
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
5
|
+
<head>
|
6
|
+
<meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
|
7
|
+
|
8
|
+
<title>Class: Thin::Request</title>
|
9
|
+
|
10
|
+
<link rel="stylesheet" href="../rdoc.css" type="text/css" media="screen" />
|
11
|
+
|
12
|
+
<script src="../js/jquery.js" type="text/javascript" charset="utf-8"></script>
|
13
|
+
<script src="../js/thickbox-compressed.js" type="text/javascript" charset="utf-8"></script>
|
14
|
+
<script src="../js/quicksearch.js" type="text/javascript" charset="utf-8"></script>
|
15
|
+
<script src="../js/darkfish.js" type="text/javascript" charset="utf-8"></script>
|
16
|
+
|
17
|
+
</head>
|
18
|
+
<body id="top" class="class">
|
19
|
+
|
20
|
+
<div id="metadata">
|
21
|
+
<div id="home-metadata">
|
22
|
+
<div id="home-section" class="section">
|
23
|
+
<h3 class="section-header">
|
24
|
+
<a href="../index.html">Home</a>
|
25
|
+
<a href="../index.html#classes">Classes</a>
|
26
|
+
<a href="../index.html#methods">Methods</a>
|
27
|
+
</h3>
|
28
|
+
</div>
|
29
|
+
</div>
|
30
|
+
|
31
|
+
<div id="file-metadata">
|
32
|
+
<div id="file-list-section" class="section">
|
33
|
+
<h3 class="section-header">In Files</h3>
|
34
|
+
<div class="section-body">
|
35
|
+
<ul>
|
36
|
+
|
37
|
+
<li><a href="../lib/thin_upload/request_rb.html?TB_iframe=true&height=550&width=785"
|
38
|
+
class="thickbox" title="lib/thin_upload/request.rb">lib/thin_upload/request.rb</a></li>
|
39
|
+
|
40
|
+
</ul>
|
41
|
+
</div>
|
42
|
+
</div>
|
43
|
+
|
44
|
+
|
45
|
+
</div>
|
46
|
+
|
47
|
+
<div id="class-metadata">
|
48
|
+
|
49
|
+
<!-- Parent Class -->
|
50
|
+
<div id="parent-class-section" class="section">
|
51
|
+
<h3 class="section-header">Parent</h3>
|
52
|
+
|
53
|
+
<p class="link">Object</p>
|
54
|
+
|
55
|
+
</div>
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
|
60
|
+
|
61
|
+
|
62
|
+
|
63
|
+
<!-- Method Quickref -->
|
64
|
+
<div id="method-list-section" class="section">
|
65
|
+
<h3 class="section-header">Methods</h3>
|
66
|
+
<ul class="link-list">
|
67
|
+
|
68
|
+
<li><a href="#method-i-cleanup_progress_hash">#cleanup_progress_hash</a></li>
|
69
|
+
|
70
|
+
<li><a href="#method-i-new_parse">#new_parse</a></li>
|
71
|
+
|
72
|
+
<li><a href="#method-i-parse">#parse</a></li>
|
73
|
+
|
74
|
+
<li><a href="#method-i-progress">#progress</a></li>
|
75
|
+
|
76
|
+
<li><a href="#method-i-scan_content">#scan_content</a></li>
|
77
|
+
|
78
|
+
<li><a href="#method-i-store_progress">#store_progress</a></li>
|
79
|
+
|
80
|
+
<li><a href="#method-i-thin_parse">#thin_parse</a></li>
|
81
|
+
|
82
|
+
<li><a href="#method-i-uuid_found_or_limit_reached-3F">#uuid_found_or_limit_reached?</a></li>
|
83
|
+
|
84
|
+
</ul>
|
85
|
+
</div>
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
</div>
|
90
|
+
|
91
|
+
<div id="project-metadata">
|
92
|
+
|
93
|
+
|
94
|
+
<div id="fileindex-section" class="section project-section">
|
95
|
+
<h3 class="section-header">Files</h3>
|
96
|
+
<ul>
|
97
|
+
|
98
|
+
<li class="file"><a href="../README_rdoc.html">README.rdoc</a></li>
|
99
|
+
|
100
|
+
</ul>
|
101
|
+
</div>
|
102
|
+
|
103
|
+
|
104
|
+
<div id="classindex-section" class="section project-section">
|
105
|
+
<h3 class="section-header">Class/Module Index
|
106
|
+
<span class="search-toggle"><img src="../images/find.png"
|
107
|
+
height="16" width="16" alt="[+]"
|
108
|
+
title="show/hide quicksearch" /></span></h3>
|
109
|
+
<form action="#" method="get" accept-charset="utf-8" class="initially-hidden">
|
110
|
+
<fieldset>
|
111
|
+
<legend>Quicksearch</legend>
|
112
|
+
<input type="text" name="quicksearch" value=""
|
113
|
+
class="quicksearch-field" />
|
114
|
+
</fieldset>
|
115
|
+
</form>
|
116
|
+
|
117
|
+
<ul class="link-list">
|
118
|
+
|
119
|
+
<li><a href="../Thin.html">Thin</a></li>
|
120
|
+
|
121
|
+
<li><a href="../Thin/Request.html">Thin::Request</a></li>
|
122
|
+
|
123
|
+
<li><a href="../Thin/Server.html">Thin::Server</a></li>
|
124
|
+
|
125
|
+
</ul>
|
126
|
+
<div id="no-class-search-results" style="display: none;">No matching classes.</div>
|
127
|
+
</div>
|
128
|
+
|
129
|
+
|
130
|
+
</div>
|
131
|
+
</div>
|
132
|
+
|
133
|
+
<div id="documentation">
|
134
|
+
<h1 class="class">Thin::Request</h1>
|
135
|
+
|
136
|
+
<div id="description" class="description">
|
137
|
+
|
138
|
+
<p>The <a href="Request.html">Request</a> class takes part of the <a
|
139
|
+
href="../Thin.html">Thin</a> module which is responsible for incomming web
|
140
|
+
requests for thin server. The class is opened up here for adding
|
141
|
+
functionality to track progress of file uploads.</p>
|
142
|
+
|
143
|
+
</div><!-- description -->
|
144
|
+
|
145
|
+
|
146
|
+
|
147
|
+
|
148
|
+
<div id="5Buntitled-5D" class="documentation-section">
|
149
|
+
|
150
|
+
|
151
|
+
|
152
|
+
|
153
|
+
|
154
|
+
<!-- Constants -->
|
155
|
+
<div id="constants-list" class="section">
|
156
|
+
<h3 class="section-header">Constants</h3>
|
157
|
+
<dl>
|
158
|
+
|
159
|
+
<dt><a name="GET_REQUEST_REGEXP">GET_REQUEST_REGEXP</a></dt>
|
160
|
+
|
161
|
+
<dd class="description"><p>regexp to identify upload progress requests</p></dd>
|
162
|
+
|
163
|
+
|
164
|
+
<dt><a name="POST_REQUEST_REGEXP">POST_REQUEST_REGEXP</a></dt>
|
165
|
+
|
166
|
+
<dd class="description"><p>Freeze some regexps regexp to identify file upload</p></dd>
|
167
|
+
|
168
|
+
|
169
|
+
<dt><a name="RACK_PROGRESS">RACK_PROGRESS</a></dt>
|
170
|
+
|
171
|
+
<dd class="description"><p>Freeze Rack header for progress hash</p></dd>
|
172
|
+
|
173
|
+
|
174
|
+
</dl>
|
175
|
+
</div>
|
176
|
+
|
177
|
+
|
178
|
+
|
179
|
+
<!-- Attributes -->
|
180
|
+
<div id="attribute-method-details" class="method-section section">
|
181
|
+
<h3 class="section-header">Attributes</h3>
|
182
|
+
|
183
|
+
|
184
|
+
<div id="data_buffer-attribute-method" class="method-detail">
|
185
|
+
<a name="data_buffer"></a>
|
186
|
+
|
187
|
+
<a name="data_buffer="></a>
|
188
|
+
|
189
|
+
<div class="method-heading attribute-method-heading">
|
190
|
+
<span class="method-name">data_buffer</span><span
|
191
|
+
class="attribute-access-type">[RW]</span>
|
192
|
+
</div>
|
193
|
+
|
194
|
+
<div class="method-description">
|
195
|
+
|
196
|
+
|
197
|
+
|
198
|
+
</div>
|
199
|
+
</div>
|
200
|
+
|
201
|
+
<div id="parser-attribute-method" class="method-detail">
|
202
|
+
<a name="parser"></a>
|
203
|
+
|
204
|
+
<div class="method-heading attribute-method-heading">
|
205
|
+
<span class="method-name">parser</span><span
|
206
|
+
class="attribute-access-type">[R]</span>
|
207
|
+
</div>
|
208
|
+
|
209
|
+
<div class="method-description">
|
210
|
+
|
211
|
+
|
212
|
+
|
213
|
+
</div>
|
214
|
+
</div>
|
215
|
+
|
216
|
+
</div><!-- attribute-method-details -->
|
217
|
+
|
218
|
+
|
219
|
+
<!-- Methods -->
|
220
|
+
|
221
|
+
<div id="public-instance-method-details" class="method-section section">
|
222
|
+
<h3 class="section-header">Public Instance Methods</h3>
|
223
|
+
|
224
|
+
|
225
|
+
<div id="cleanup_progress_hash-method" class="method-detail ">
|
226
|
+
<a name="method-i-cleanup_progress_hash"></a>
|
227
|
+
|
228
|
+
|
229
|
+
<div class="method-heading">
|
230
|
+
<span class="method-name">cleanup_progress_hash</span><span
|
231
|
+
class="method-args">(req_uuid)</span>
|
232
|
+
<span class="method-click-advice">click to toggle source</span>
|
233
|
+
</div>
|
234
|
+
|
235
|
+
|
236
|
+
<div class="method-description">
|
237
|
+
|
238
|
+
<p>deleting progress entry from +<a
|
239
|
+
href="Server.html#method-c-progress">Thin::Server::progress</a>+ if the
|
240
|
+
upload is finished and the result was requested Arguments:</p>
|
241
|
+
|
242
|
+
<pre>data: (String)</pre>
|
243
|
+
|
244
|
+
|
245
|
+
|
246
|
+
<div class="method-source-code" id="cleanup_progress_hash-source">
|
247
|
+
<pre>
|
248
|
+
<span class="ruby-comment"># File lib/thin_upload/request.rb, line 82</span>
|
249
|
+
<span class="ruby-keyword">def</span> <span class="ruby-identifier">cleanup_progress_hash</span>(<span class="ruby-identifier">req_uuid</span>)
|
250
|
+
<span class="ruby-constant">Thin</span><span class="ruby-operator">::</span><span class="ruby-constant">Server</span><span class="ruby-operator">::</span><span class="ruby-identifier">progress</span>.<span class="ruby-identifier">delete</span>(<span class="ruby-identifier">req_uuid</span>) <span class="ruby-keyword">if</span> <span class="ruby-constant">Thin</span><span class="ruby-operator">::</span><span class="ruby-constant">Server</span><span class="ruby-operator">::</span><span class="ruby-identifier">progress</span>[<span class="ruby-identifier">req_uuid</span>] <span class="ruby-operator">==</span> <span class="ruby-value">100</span> <span class="ruby-operator">&&</span> <span class="ruby-identifier">finished?</span><span class="ruby-comment">#delete when progress is returned and 100%</span>
|
251
|
+
<span class="ruby-keyword">end</span></pre>
|
252
|
+
</div><!-- cleanup_progress_hash-source -->
|
253
|
+
|
254
|
+
</div>
|
255
|
+
|
256
|
+
|
257
|
+
|
258
|
+
|
259
|
+
</div><!-- cleanup_progress_hash-method -->
|
260
|
+
|
261
|
+
|
262
|
+
<div id="new_parse-method" class="method-detail ">
|
263
|
+
<a name="method-i-new_parse"></a>
|
264
|
+
|
265
|
+
|
266
|
+
<div class="method-heading">
|
267
|
+
<span class="method-name">new_parse</span><span
|
268
|
+
class="method-args">(data)</span>
|
269
|
+
<span class="method-click-advice">click to toggle source</span>
|
270
|
+
</div>
|
271
|
+
|
272
|
+
|
273
|
+
<div class="method-description">
|
274
|
+
|
275
|
+
<p><tt>new_parse</tt> method extends the original <tt>parse</tt> method's
|
276
|
+
functionality with the upload progress tracking Arguments:</p>
|
277
|
+
|
278
|
+
<pre>data: (String)</pre>
|
279
|
+
|
280
|
+
|
281
|
+
|
282
|
+
<div class="method-source-code" id="new_parse-source">
|
283
|
+
<pre>
|
284
|
+
<span class="ruby-comment"># File lib/thin_upload/request.rb, line 25</span>
|
285
|
+
<span class="ruby-keyword">def</span> <span class="ruby-identifier">new_parse</span>(<span class="ruby-identifier">data</span>)
|
286
|
+
<span class="ruby-identifier">puts</span> <span class="ruby-node">"Limit #{uuid_found_or_limit_reached? ? "true" : "false"}"</span>
|
287
|
+
<span class="ruby-identifier">scan_content</span>(<span class="ruby-identifier">data</span>) <span class="ruby-keyword">unless</span> <span class="ruby-identifier">uuid_found_or_limit_reached?</span>
|
288
|
+
<span class="ruby-identifier">success</span> = <span class="ruby-identifier">thin_parse</span>(<span class="ruby-identifier">data</span>) <span class="ruby-comment">#execute the the original +parse+ method</span>
|
289
|
+
<span class="ruby-identifier">store_progress</span>(<span class="ruby-ivar">@upload_uuid</span>)
|
290
|
+
<span class="ruby-identifier">cleanup_progress_hash</span>(<span class="ruby-ivar">@request_uuid</span>)
|
291
|
+
<span class="ruby-identifier">success</span> <span class="ruby-comment">#returns the result from Thin's parse method</span>
|
292
|
+
<span class="ruby-keyword">end</span></pre>
|
293
|
+
</div><!-- new_parse-source -->
|
294
|
+
|
295
|
+
</div>
|
296
|
+
|
297
|
+
|
298
|
+
<div class="aliases">
|
299
|
+
Also aliased as: <a href="Request.html#method-i-parse">parse</a>
|
300
|
+
</div>
|
301
|
+
|
302
|
+
|
303
|
+
|
304
|
+
</div><!-- new_parse-method -->
|
305
|
+
|
306
|
+
|
307
|
+
<div id="parse-method" class="method-detail method-alias">
|
308
|
+
<a name="method-i-parse"></a>
|
309
|
+
|
310
|
+
|
311
|
+
<div class="method-heading">
|
312
|
+
<span class="method-name">parse</span><span
|
313
|
+
class="method-args">(data)</span>
|
314
|
+
<span class="method-click-advice">click to toggle source</span>
|
315
|
+
</div>
|
316
|
+
|
317
|
+
|
318
|
+
<div class="method-description">
|
319
|
+
|
320
|
+
|
321
|
+
|
322
|
+
|
323
|
+
|
324
|
+
</div>
|
325
|
+
|
326
|
+
|
327
|
+
<div class="aliases">
|
328
|
+
Also aliased as: <a href="Request.html#method-i-thin_parse">thin_parse</a>
|
329
|
+
</div>
|
330
|
+
|
331
|
+
|
332
|
+
|
333
|
+
<div class="aliases">
|
334
|
+
Alias for: <a href="Request.html#method-i-new_parse">new_parse</a>
|
335
|
+
</div>
|
336
|
+
|
337
|
+
</div><!-- parse-method -->
|
338
|
+
|
339
|
+
|
340
|
+
<div id="progress-method" class="method-detail ">
|
341
|
+
<a name="method-i-progress"></a>
|
342
|
+
|
343
|
+
|
344
|
+
<div class="method-heading">
|
345
|
+
<span class="method-name">progress</span><span
|
346
|
+
class="method-args">()</span>
|
347
|
+
<span class="method-click-advice">click to toggle source</span>
|
348
|
+
</div>
|
349
|
+
|
350
|
+
|
351
|
+
<div class="method-description">
|
352
|
+
|
353
|
+
<p>Calculating the progress based on <tt>content_length</tt> and received body
|
354
|
+
size <tt>body.size</tt> Arguments:</p>
|
355
|
+
|
356
|
+
<pre>none</pre>
|
357
|
+
|
358
|
+
|
359
|
+
|
360
|
+
<div class="method-source-code" id="progress-source">
|
361
|
+
<pre>
|
362
|
+
<span class="ruby-comment"># File lib/thin_upload/request.rb, line 67</span>
|
363
|
+
<span class="ruby-keyword">def</span> <span class="ruby-identifier">progress</span>
|
364
|
+
((<span class="ruby-identifier">body</span>.<span class="ruby-identifier">size</span><span class="ruby-operator">/</span><span class="ruby-identifier">content_length</span>.<span class="ruby-identifier">to_f</span>)*<span class="ruby-value">100</span>).<span class="ruby-identifier">to_i</span>
|
365
|
+
<span class="ruby-keyword">end</span></pre>
|
366
|
+
</div><!-- progress-source -->
|
367
|
+
|
368
|
+
</div>
|
369
|
+
|
370
|
+
|
371
|
+
|
372
|
+
|
373
|
+
</div><!-- progress-method -->
|
374
|
+
|
375
|
+
|
376
|
+
<div id="scan_content-method" class="method-detail ">
|
377
|
+
<a name="method-i-scan_content"></a>
|
378
|
+
|
379
|
+
|
380
|
+
<div class="method-heading">
|
381
|
+
<span class="method-name">scan_content</span><span
|
382
|
+
class="method-args">(data)</span>
|
383
|
+
<span class="method-click-advice">click to toggle source</span>
|
384
|
+
</div>
|
385
|
+
|
386
|
+
|
387
|
+
<div class="method-description">
|
388
|
+
|
389
|
+
<p>Scans unparsed data for uuids, the unparsed data is stored in a string for
|
390
|
+
buffering purposes which is deleted after the uuid has been found.
|
391
|
+
Arguments:</p>
|
392
|
+
|
393
|
+
<pre>data: (String)</pre>
|
394
|
+
|
395
|
+
|
396
|
+
|
397
|
+
<div class="method-source-code" id="scan_content-source">
|
398
|
+
<pre>
|
399
|
+
<span class="ruby-comment"># File lib/thin_upload/request.rb, line 46</span>
|
400
|
+
<span class="ruby-keyword">def</span> <span class="ruby-identifier">scan_content</span>(<span class="ruby-identifier">data</span>)
|
401
|
+
<span class="ruby-ivar">@data_buffer</span> = <span class="ruby-ivar">@data_buffer</span>.<span class="ruby-identifier">to_s</span> <span class="ruby-operator">+</span> <span class="ruby-identifier">data</span>
|
402
|
+
<span class="ruby-ivar">@upload_uuid</span> <span class="ruby-operator">||=</span> <span class="ruby-identifier">data_buffer</span>.<span class="ruby-identifier">scan</span>(<span class="ruby-constant">POST_REQUEST_REGEXP</span>).<span class="ruby-identifier">flatten</span>.<span class="ruby-identifier">first</span>
|
403
|
+
<span class="ruby-ivar">@request_uuid</span> <span class="ruby-operator">||=</span> <span class="ruby-identifier">data_buffer</span>.<span class="ruby-identifier">scan</span>(<span class="ruby-constant">GET_REQUEST_REGEXP</span>).<span class="ruby-identifier">flatten</span>.<span class="ruby-identifier">first</span>
|
404
|
+
<span class="ruby-keyword">end</span></pre>
|
405
|
+
</div><!-- scan_content-source -->
|
406
|
+
|
407
|
+
</div>
|
408
|
+
|
409
|
+
|
410
|
+
|
411
|
+
|
412
|
+
</div><!-- scan_content-method -->
|
413
|
+
|
414
|
+
|
415
|
+
<div id="store_progress-method" class="method-detail ">
|
416
|
+
<a name="method-i-store_progress"></a>
|
417
|
+
|
418
|
+
|
419
|
+
<div class="method-heading">
|
420
|
+
<span class="method-name">store_progress</span><span
|
421
|
+
class="method-args">(uuid)</span>
|
422
|
+
<span class="method-click-advice">click to toggle source</span>
|
423
|
+
</div>
|
424
|
+
|
425
|
+
|
426
|
+
<div class="method-description">
|
427
|
+
|
428
|
+
<p>progress can be accessed via +<a
|
429
|
+
href="http://'rack.progress'">request.env</a>+ in the app Arguments:</p>
|
430
|
+
|
431
|
+
<pre>uuid: (String)</pre>
|
432
|
+
|
433
|
+
|
434
|
+
|
435
|
+
<div class="method-source-code" id="store_progress-source">
|
436
|
+
<pre>
|
437
|
+
<span class="ruby-comment"># File lib/thin_upload/request.rb, line 74</span>
|
438
|
+
<span class="ruby-keyword">def</span> <span class="ruby-identifier">store_progress</span>(<span class="ruby-identifier">uuid</span>)
|
439
|
+
<span class="ruby-constant">Thin</span><span class="ruby-operator">::</span><span class="ruby-constant">Server</span><span class="ruby-operator">::</span><span class="ruby-identifier">progress</span>[<span class="ruby-identifier">uuid</span>] = <span class="ruby-identifier">progress</span> <span class="ruby-keyword">if</span> <span class="ruby-identifier">uuid</span> <span class="ruby-comment">#storing the progress with the uiid</span>
|
440
|
+
<span class="ruby-ivar">@env</span>.<span class="ruby-identifier">merge!</span>(<span class="ruby-constant">RACK_PROGRESS</span>=<span class="ruby-operator">></span><span class="ruby-constant">Thin</span><span class="ruby-operator">::</span><span class="ruby-constant">Server</span><span class="ruby-operator">::</span><span class="ruby-identifier">progress</span>.<span class="ruby-identifier">clone</span>) <span class="ruby-keyword">if</span> <span class="ruby-identifier">finished?</span> <span class="ruby-comment">#merging the progress hash into the environment</span>
|
441
|
+
<span class="ruby-keyword">end</span></pre>
|
442
|
+
</div><!-- store_progress-source -->
|
443
|
+
|
444
|
+
</div>
|
445
|
+
|
446
|
+
|
447
|
+
|
448
|
+
|
449
|
+
</div><!-- store_progress-method -->
|
450
|
+
|
451
|
+
|
452
|
+
<div id="thin_parse-method" class="method-detail method-alias">
|
453
|
+
<a name="method-i-thin_parse"></a>
|
454
|
+
|
455
|
+
|
456
|
+
<div class="method-heading">
|
457
|
+
<span class="method-name">thin_parse</span><span
|
458
|
+
class="method-args">(data)</span>
|
459
|
+
<span class="method-click-advice">click to toggle source</span>
|
460
|
+
</div>
|
461
|
+
|
462
|
+
|
463
|
+
<div class="method-description">
|
464
|
+
|
465
|
+
<p>The <tt>Thin</tt>‘s <tt>parse</tt> method is aliased to <tt>thin_parse</tt>
|
466
|
+
and the <tt>new_parse</tt> method is aliased to <tt>parse</tt></p>
|
467
|
+
|
468
|
+
|
469
|
+
|
470
|
+
</div>
|
471
|
+
|
472
|
+
|
473
|
+
|
474
|
+
|
475
|
+
<div class="aliases">
|
476
|
+
Alias for: <a href="Request.html#method-i-parse">parse</a>
|
477
|
+
</div>
|
478
|
+
|
479
|
+
</div><!-- thin_parse-method -->
|
480
|
+
|
481
|
+
|
482
|
+
<div id="uuid_found_or_limit_reached-3F-method" class="method-detail ">
|
483
|
+
<a name="method-i-uuid_found_or_limit_reached-3F"></a>
|
484
|
+
|
485
|
+
|
486
|
+
<div class="method-heading">
|
487
|
+
<span class="method-name">uuid_found_or_limit_reached?</span><span
|
488
|
+
class="method-args">()</span>
|
489
|
+
<span class="method-click-advice">click to toggle source</span>
|
490
|
+
</div>
|
491
|
+
|
492
|
+
|
493
|
+
<div class="method-description">
|
494
|
+
|
495
|
+
<p>Checking if we still have to search for uuid’s Arguments:</p>
|
496
|
+
|
497
|
+
<pre>none</pre>
|
498
|
+
|
499
|
+
|
500
|
+
|
501
|
+
<div class="method-source-code" id="uuid_found_or_limit_reached-3F-source">
|
502
|
+
<pre>
|
503
|
+
<span class="ruby-comment"># File lib/thin_upload/request.rb, line 55</span>
|
504
|
+
<span class="ruby-keyword">def</span> <span class="ruby-identifier">uuid_found_or_limit_reached?</span>
|
505
|
+
<span class="ruby-keyword">if</span> <span class="ruby-ivar">@upload_uuid</span> <span class="ruby-operator">||</span> <span class="ruby-ivar">@request_uuid</span> <span class="ruby-operator">||</span> (<span class="ruby-identifier">body</span>.<span class="ruby-identifier">size</span> <span class="ruby-operator">></span> <span class="ruby-constant">MAX_BODY</span>)
|
506
|
+
<span class="ruby-ivar">@data_buffer</span> = <span class="ruby-keyword">nil</span>
|
507
|
+
<span class="ruby-keyword">true</span>
|
508
|
+
<span class="ruby-keyword">else</span>
|
509
|
+
<span class="ruby-keyword">false</span>
|
510
|
+
<span class="ruby-keyword">end</span>
|
511
|
+
<span class="ruby-keyword">end</span></pre>
|
512
|
+
</div><!-- uuid_found_or_limit_reached-3F-source -->
|
513
|
+
|
514
|
+
</div>
|
515
|
+
|
516
|
+
|
517
|
+
|
518
|
+
|
519
|
+
</div><!-- uuid_found_or_limit_reached-3F-method -->
|
520
|
+
|
521
|
+
|
522
|
+
</div><!-- public-instance-method-details -->
|
523
|
+
|
524
|
+
</div><!-- 5Buntitled-5D -->
|
525
|
+
|
526
|
+
|
527
|
+
</div><!-- documentation -->
|
528
|
+
|
529
|
+
<div id="validator-badges">
|
530
|
+
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
531
|
+
<p><small>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish
|
532
|
+
Rdoc Generator</a> 2</small>.</p>
|
533
|
+
</div>
|
534
|
+
|
535
|
+
</body>
|
536
|
+
</html>
|
537
|
+
|