upr 0.1.0 → 0.2.0
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/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>
|