upr 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/GIT-VERSION-GEN +1 -1
- data/GNUmakefile +1 -1
- data/LICENSE +9 -4
- data/README +29 -13
- data/examples/rails_app-2.3.4/app/controllers/application_controller.rb +8 -1
- data/examples/rails_app-2.3.4/app/controllers/files_controller.rb +35 -12
- data/examples/rails_app-2.3.4/app/controllers/progress_controller.rb +11 -0
- data/examples/rails_app-2.3.4/app/models/upr_status.rb +34 -10
- data/examples/rails_app-2.3.4/app/views/files/index.html.erb +14 -4
- data/examples/rails_app-2.3.4/app/views/files/new.html.erb +71 -0
- data/examples/rails_app-2.3.4/app/views/files/pull.html.erb +60 -0
- data/examples/rails_app-2.3.4/config.ru +3 -0
- data/examples/rails_app-2.3.4/config/initializers/ruby_19_compat.rb +26 -0
- data/examples/rails_app-2.3.4/public/javascripts/ajax_pull/ajax_pull.js +85 -0
- data/examples/rails_app-2.3.4/public/javascripts/ajax_pull/prototype-1_5_1.js +3271 -0
- data/examples/rails_app-2.3.4/public/javascripts/ajax_pull/upload_progress.js +139 -0
- data/examples/rails_app-2.3.4/public/javascripts/jquery.js +32 -0
- data/examples/rails_app-2.3.4/public/javascripts/jquery.uploadProgress.js +116 -0
- data/examples/rails_app-2.3.4/public/stylesheets/site.css +41 -0
- data/examples/rails_app-2.3.4/rainbows_config.rb +1 -1
- data/examples/rails_app-2.3.4/test/fixtures/upr_statuses.yml +22 -0
- data/examples/rails_app-2.3.4/test/unit/upr_status_test.rb +41 -0
- data/lib/upr.rb +4 -5
- data/lib/upr/input_wrapper.rb +17 -13
- data/lib/upr/json.rb +143 -0
- data/lib/upr/monitor.rb +18 -6
- data/lib/upr/params.rb +24 -0
- data/lib/upr/status.rb +9 -0
- data/lib/upr/status_methods.rb +13 -0
- data/test/test_monitor.rb +58 -0
- data/upr.gemspec +1 -0
- metadata +37 -5
data/GIT-VERSION-GEN
CHANGED
data/GNUmakefile
CHANGED
@@ -55,7 +55,7 @@ NEWS: GIT-VERSION-FILE
|
|
55
55
|
$(rake) -s news_rdoc > $@+
|
56
56
|
mv $@+ $@
|
57
57
|
|
58
|
-
SINCE =
|
58
|
+
SINCE = 0.1.0
|
59
59
|
ChangeLog: log_range = $(shell test -n "$(SINCE)" && echo v$(SINCE)..)
|
60
60
|
ChangeLog: GIT-VERSION-FILE
|
61
61
|
@echo "ChangeLog from $(GIT_URL) ($(SINCE)..$(GIT_VERSION))" > $@+
|
data/LICENSE
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
Upload Progress for Rack (upr) is copyrighted Free Software by all
|
2
|
-
contributors, see the logs in revision control for all of them.
|
3
|
-
|
4
|
-
|
5
|
-
|
2
|
+
contributors, see the logs in revision control for all of them.
|
3
|
+
|
4
|
+
Bundled examples in the examples/ directory retain their respective
|
5
|
+
(Free Software) licenses. See copyright headers in individual files for
|
6
|
+
more information. This distribution only includes Free Software.
|
7
|
+
|
8
|
+
You can redistribute upr it and/or modify it under either the terms of
|
9
|
+
the {GPL2}[http://www.gnu.org/licenses/gpl-2.0.txt] (see link:COPYING)
|
10
|
+
or the conditions below:
|
6
11
|
|
7
12
|
1. You may make and give away verbatim copies of the source form of the
|
8
13
|
software without restriction, provided that you duplicate all of the
|
data/README
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
= upr - Upload Progress for Rack
|
2
2
|
|
3
3
|
upr is Rack middleware that allows browser-side upload progress
|
4
|
-
monitoring. It is based on
|
5
|
-
|
6
|
-
|
4
|
+
monitoring. It is based on (and should be client-side compatible with)
|
5
|
+
several upload progress modules including ones used by leading web
|
6
|
+
servers. It allows any Moneta backing store in addition to DRb. There
|
7
|
+
is also a packaged example for using an ActiveRecord model for Rails.
|
7
8
|
|
8
9
|
== Demo
|
9
10
|
|
10
|
-
You can see upr
|
11
|
-
|
12
|
-
|
11
|
+
You can see upr in action at http://upr-demo.bogomips.org/ It will
|
12
|
+
report the size and SHA1 of the file you've uploaded. Much of the demo
|
13
|
+
was stolen from all the existing upload progress examples for other web
|
14
|
+
servers.
|
13
15
|
|
14
16
|
== Web Server Compatibility
|
15
17
|
|
@@ -25,14 +27,27 @@ handful of concurrency models:
|
|
25
27
|
For use with Revactor, the use of network-based Moneta stores or DRb is
|
26
28
|
only advised if those stores are using Revactor-aware sockets.
|
27
29
|
|
28
|
-
== JavaScript/HTML Compatibility
|
30
|
+
== JavaScript/CSS/HTML Compatibility
|
29
31
|
|
30
|
-
The current developer does not react well with GUIs. Thus all (R)HTML
|
31
|
-
and
|
32
|
+
The current developer does not react well with GUIs. Thus all (R)HTML,
|
33
|
+
JavaScript and CSS example code was stolen from one of the following:
|
32
34
|
|
33
|
-
|
34
|
-
|
35
|
+
1. mongrel_upload_progress
|
36
|
+
http://mongrel.rubyforge.org/wiki/UploadProgress
|
37
|
+
2. jquery-upload-progress
|
38
|
+
http://github.com/drogus/jquery-upload-progress
|
39
|
+
3. mongrel_streaming_upload_progress
|
40
|
+
http://rubyforge.org/pipermail/mongrel-users/2007-July/003747.html
|
35
41
|
|
42
|
+
This means our module should also be compatible with any of these
|
43
|
+
interfaces.
|
44
|
+
|
45
|
+
Contributions to enhance compatibility for more modern things like
|
46
|
+
jQuery and HTML5 are very welcome. We would prefer as much as possible
|
47
|
+
to NOT proliferate new AJAX sub-protocols and use existing ones whenever
|
48
|
+
possible. Our current favorite is the Ajax.Pull JavaScript used in
|
49
|
+
Ry Dahl's mongrel_streaming_upload_progress because it only requires a
|
50
|
+
one extra HTTP request to pull all the status notifications.
|
36
51
|
|
37
52
|
== Backend Compatibility
|
38
53
|
|
@@ -84,7 +99,8 @@ and we'll try our best to fix it.
|
|
84
99
|
|
85
100
|
upr is copyright 2009 by all contributors (see logs in git). It is
|
86
101
|
based on mongrel_upload_progress and carries the same license (Ruby +
|
87
|
-
GPL2).
|
102
|
+
GPL2). Bundled examples may different Free Software licenses, see the
|
103
|
+
included LICENSE file for details.
|
88
104
|
|
89
105
|
upr is 100% Free Software. We will never support the proliferation of
|
90
106
|
non-Free browsers or plugins.
|
@@ -99,7 +115,7 @@ To subscribe or post to the mailing list, just send an email to
|
|
99
115
|
upr@librelist.com and follow the instructions in the automated reply.
|
100
116
|
|
101
117
|
* email: mailto:upr@librelist.com
|
102
|
-
* git: git://git.bogomips.org/upr.git
|
118
|
+
* git: git://git.bogomips.org/upr.git or git://repo.or.cz/upr.git
|
103
119
|
* cgit: http://git.bogomips.org/cgit/upr.git
|
104
120
|
|
105
121
|
We will adhere to mostly the same conventions for patch submissions as
|
@@ -1,3 +1,10 @@
|
|
1
1
|
class ApplicationController < ActionController::Base
|
2
|
-
helper :all # include all helpers, all the time
|
2
|
+
# helper :all # include all helpers, all the time
|
3
|
+
defined?($upr) or before_filter do
|
4
|
+
# grab the backend in case we forget to set it (or if we're using DRb)
|
5
|
+
defined?($upr) or ObjectSpace.each_object(Upr::InputWrapper) do |x|
|
6
|
+
$upr ||= x.backend
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
3
10
|
end
|
@@ -1,21 +1,27 @@
|
|
1
1
|
require 'digest/sha1'
|
2
2
|
|
3
3
|
class FilesController < ApplicationController
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
4
|
+
# used by jQuery streaming upload progress
|
5
|
+
def new
|
6
|
+
_sha1_flash_self
|
7
|
+
end
|
8
|
+
|
9
|
+
# based on Ry Dahl's streaming AJAX pull:
|
10
|
+
# http://rubyforge.org/pipermail/mongrel-users/2007-July/003747.html
|
11
|
+
def pull
|
12
|
+
_sha1_flash_self
|
9
13
|
end
|
10
14
|
|
11
15
|
def index
|
12
16
|
end
|
13
17
|
|
18
|
+
# used by mup-compatible upload progress
|
14
19
|
def status
|
15
20
|
tmp = $upr.read(params[:upload_id]).inspect
|
16
21
|
render :text => "#{Rack::Utils.escape_html(tmp)}\n"
|
17
22
|
end
|
18
23
|
|
24
|
+
# used by mup-compatible upload progress
|
19
25
|
def progress
|
20
26
|
render :update do |page|
|
21
27
|
status = $upr.read(params[:upload_id]) and
|
@@ -23,19 +29,36 @@ class FilesController < ApplicationController
|
|
23
29
|
end
|
24
30
|
end
|
25
31
|
|
32
|
+
# used by mup-compatible upload progress
|
26
33
|
def upload
|
27
|
-
|
34
|
+
size, hexdigest = _read_sha1_size
|
35
|
+
render :text => "sha1: #{hexdigest}<br />" \
|
36
|
+
"size: #{size}<br />" \
|
37
|
+
'<script type="text/javascript">' \
|
38
|
+
'window.parent.UploadProgress.finish();</script>'
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def _read_sha1_size
|
44
|
+
file = params[:data] or return [ -1, :unknown ]
|
45
|
+
File.unlink(file.path) if file.respond_to?(:path)
|
28
46
|
digest = Digest::SHA1.new
|
29
47
|
if buf = file.read(16384)
|
30
48
|
begin
|
31
49
|
digest.update(buf)
|
32
50
|
end while file.read(16384, buf)
|
33
51
|
end
|
34
|
-
|
35
|
-
File.unlink(file.path)
|
36
|
-
render :text => "sha1: #{digest.hexdigest}<br />" \
|
37
|
-
"size: #{size}<br />" \
|
38
|
-
'<script type="text/javascript">' \
|
39
|
-
'window.parent.UploadProgress.finish();</script>'
|
52
|
+
[ file.size, digest.hexdigest ]
|
40
53
|
end
|
54
|
+
|
55
|
+
def _sha1_flash_self
|
56
|
+
if request.post?
|
57
|
+
size, hexdigest = _read_sha1_size
|
58
|
+
msg = "Successfully upload file (size: #{size}, sha1: #{hexdigest})"
|
59
|
+
flash[:notice] = msg
|
60
|
+
redirect_to :action => params[:action]
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
41
64
|
end
|
@@ -1,14 +1,8 @@
|
|
1
1
|
class UprStatus < ActiveRecord::Base
|
2
|
-
cattr_accessor :gc_cutoff
|
3
|
-
@@gc_cutoff = 10
|
4
2
|
|
5
3
|
class << self
|
6
4
|
def read(upid)
|
7
|
-
|
8
|
-
rv.time = Time.now.to_i
|
9
|
-
rv.save
|
10
|
-
rv
|
11
|
-
end
|
5
|
+
find_by_upid(upid)
|
12
6
|
end
|
13
7
|
|
14
8
|
def start(upid, length)
|
@@ -22,14 +16,44 @@ class UprStatus < ActiveRecord::Base
|
|
22
16
|
end
|
23
17
|
|
24
18
|
def incr(upid, nr)
|
25
|
-
|
26
|
-
|
19
|
+
transaction do
|
20
|
+
if rv = find_by_upid(upid)
|
21
|
+
rv.time = Time.now.to_i
|
22
|
+
rv.seen += nr if rv.seen >= 0
|
23
|
+
rv.save
|
24
|
+
rv
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def error!(upid)
|
30
|
+
transaction do
|
31
|
+
if rv = find_by_upid(upid)
|
32
|
+
rv.time = Time.now.to_i
|
33
|
+
rv.seen = -1
|
34
|
+
rv.save
|
35
|
+
rv
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def finish(upid)
|
41
|
+
transaction do
|
42
|
+
if rv = find_by_upid(upid)
|
43
|
+
rv.time = Time.now.to_i
|
44
|
+
rv.length ||= rv.seen
|
45
|
+
rv.seen = rv.length
|
46
|
+
rv.save
|
47
|
+
rv
|
48
|
+
end
|
49
|
+
end
|
27
50
|
end
|
28
51
|
|
29
52
|
def gc
|
30
|
-
cutoff = Time.now.to_i -
|
53
|
+
cutoff = Time.now.to_i - Upr::Monitor::OPT[:expires_in]
|
31
54
|
delete_all "time < #{cutoff}"
|
32
55
|
end
|
33
56
|
end
|
34
57
|
|
58
|
+
include Upr::StatusMethods
|
35
59
|
end
|
@@ -2,7 +2,8 @@
|
|
2
2
|
<head>
|
3
3
|
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
|
4
4
|
<title>upr test, http://upr.bogomips.org/</title>
|
5
|
-
<%= javascript_include_tag :
|
5
|
+
<%= javascript_include_tag :defaults %>
|
6
|
+
<%= javascript_include_tag 'upr' %>
|
6
7
|
<style type="text/css">
|
7
8
|
#progress-bar {
|
8
9
|
width:500px;
|
@@ -42,9 +43,18 @@ opt = {
|
|
42
43
|
}
|
43
44
|
-%>
|
44
45
|
<p>
|
45
|
-
This is a demo of <a href="http://upr.bogomips.org/">upr</a> in action.
|
46
|
-
Much of this (including all JS) was stolen from the mongrel_upload_progress
|
47
|
-
examples.
|
46
|
+
This is a demo of <a href="http://upr.bogomips.org/">upr</a> in action.
|
47
|
+
Much of this (including all JS) was stolen from the mongrel_upload_progress
|
48
|
+
examples.
|
49
|
+
</p>
|
50
|
+
<p>
|
51
|
+
Also, see the <a href="/files/new">jQuery-compatible interface</a>
|
52
|
+
that's also compatible with upload progress modules for nginx and lighttpd.
|
53
|
+
</p>
|
54
|
+
<p>
|
55
|
+
Last but not least, check out the <a href="/files/pull">Ajax.Pull</a>
|
56
|
+
example that uses a single, streaming HTTP response to interatively
|
57
|
+
send progress updates.
|
48
58
|
</p>
|
49
59
|
<p><%= link_to upid, :action => 'status', :upload_id => upid %></p>
|
50
60
|
<% form_tag(act, opt) do %>
|
@@ -0,0 +1,71 @@
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
3
|
+
<!-- example taken from git://github.com/drogus/jquery-upload-progress -->
|
4
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
5
|
+
<head>
|
6
|
+
<title>ajaxFileUpload</title>
|
7
|
+
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
8
|
+
<script src="/javascripts/jquery.js"></script>
|
9
|
+
<script src="/javascripts/jquery.uploadProgress.js"></script>
|
10
|
+
<script type="text/javascript">
|
11
|
+
$(function() {
|
12
|
+
$('form').uploadProgress({
|
13
|
+
/* scripts locations for safari */
|
14
|
+
jqueryPath: "/javascripts/jquery.js",
|
15
|
+
uploadProgressPath: "/javascripts/jquery.uploadProgress.js",
|
16
|
+
start:function(){},
|
17
|
+
uploading: function(upload) {$('#percents').html(upload.percents+'%');},
|
18
|
+
interval: 500
|
19
|
+
});
|
20
|
+
});
|
21
|
+
</script>
|
22
|
+
<style type="text/css">
|
23
|
+
.bar {
|
24
|
+
width: 300px;
|
25
|
+
}
|
26
|
+
|
27
|
+
#progress {
|
28
|
+
background: #eee;
|
29
|
+
border: 1px solid #222;
|
30
|
+
margin-top: 20px;
|
31
|
+
}
|
32
|
+
#progressbar {
|
33
|
+
width: 0px;
|
34
|
+
height: 24px;
|
35
|
+
background: #333;
|
36
|
+
}
|
37
|
+
</style>
|
38
|
+
</head>
|
39
|
+
|
40
|
+
<body>
|
41
|
+
<% if flash[:notice] %>
|
42
|
+
<h1><%= flash[:notice] %></h1>
|
43
|
+
<% end %>
|
44
|
+
<p>
|
45
|
+
This is a demo of <a href="http://upr.bogomips.org/">upr</a> in action.
|
46
|
+
Much of this (including all JS) was stolen from the
|
47
|
+
<a href="http://github.com/drogus/jquery-upload-progress"
|
48
|
+
>jQuery-upload-progress</a>
|
49
|
+
</p>
|
50
|
+
<p>
|
51
|
+
Also, see the <a href="/">mongrel_upload_progress-compatible</a> version
|
52
|
+
</p>
|
53
|
+
<p>
|
54
|
+
Last but not least, check out the <a href="/files/pull">Ajax.Pull</a>
|
55
|
+
example that uses a single, streaming HTTP response to interatively
|
56
|
+
send progress updates.
|
57
|
+
</p>
|
58
|
+
|
59
|
+
<form id="upload" enctype="multipart/form-data" action="/files/new" method="post">
|
60
|
+
<input name="data" type="file"/>
|
61
|
+
<input type="submit" value="Upload"/>
|
62
|
+
</form>
|
63
|
+
|
64
|
+
<div id="uploading">
|
65
|
+
<div id="progress" class="bar">
|
66
|
+
<div id="progressbar"> </div>
|
67
|
+
</div>
|
68
|
+
</div>
|
69
|
+
<div id="percents"></div>
|
70
|
+
</body>
|
71
|
+
</html>
|
@@ -0,0 +1,60 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<!-- http://rubyforge.org/pipermail/mongrel-users/2007-July/003747.html -->
|
4
|
+
<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
|
5
|
+
<title>streaming upload progress test</title>
|
6
|
+
<%= javascript_include_tag 'ajax_pull/prototype-1_5_1.js' %>
|
7
|
+
<%= javascript_include_tag 'ajax_pull/ajax_pull.js' %>
|
8
|
+
<%= javascript_include_tag 'ajax_pull/upload_progress.js' %>
|
9
|
+
</head>
|
10
|
+
<body>
|
11
|
+
<%
|
12
|
+
upid = "#{Time.now.to_i}.#{rand}"
|
13
|
+
act = { :action => 'pull', :upload_id => upid }
|
14
|
+
opt = {
|
15
|
+
:multipart => true,
|
16
|
+
:target => 'upload-target',
|
17
|
+
:onsubmit => "UploadProgress.begin('#{upid}')"
|
18
|
+
}
|
19
|
+
-%>
|
20
|
+
|
21
|
+
<% if flash[:notice] %>
|
22
|
+
<div class="notice"><%= flash[:notice] %></div>
|
23
|
+
<% end %>
|
24
|
+
<p>
|
25
|
+
This is a demo of <a href="http://upr.bogomips.org/">upr</a> in action
|
26
|
+
with Ajax.Pull. It only uses a single, streaming AJAX request instead
|
27
|
+
of pulling. It is based on <a
|
28
|
+
href="http://rubyforge.org/pipermail/mongrel-users/2007-July/003747.html"
|
29
|
+
>mongrel_<b>streaming</b>_upload_progress</a>
|
30
|
+
</p>
|
31
|
+
<p>
|
32
|
+
This is different from the polling
|
33
|
+
<a href="/">mongrel_upload_progress-compatible</a> version
|
34
|
+
and also different from the polling
|
35
|
+
<a href="/files/new">jQuery+nginx/lighttpd-compatible</a> version
|
36
|
+
</p>
|
37
|
+
|
38
|
+
<p><%= link_to "#{upid} (single)",
|
39
|
+
:action => 'status', :upload_id => upid %></p>
|
40
|
+
<p><%= link_to "#{upid} (stream)",
|
41
|
+
"/progress?long&upload_id=#{upid}" %></p>
|
42
|
+
|
43
|
+
<% form_tag(act, opt) do %>
|
44
|
+
<div><p><%= file_field_tag :data %></p></div>
|
45
|
+
<p><%= submit_tag :Upload %></p>
|
46
|
+
<% end %>
|
47
|
+
|
48
|
+
<p>Below is the results <code>div</code></p>
|
49
|
+
<div id="results">(nothing)</div>
|
50
|
+
|
51
|
+
<p>Below is the progress bar <code>div</code></p>
|
52
|
+
<div id="progress-bar"></div>
|
53
|
+
|
54
|
+
<p>Below is the debug list</p>
|
55
|
+
<ol id="debug"></ol>
|
56
|
+
|
57
|
+
<iframe id="upload-target" name="upload-target" src="about:blank"></iframe>
|
58
|
+
|
59
|
+
</body>
|
60
|
+
</html>
|