Skip to content

Instantly share code, notes, and snippets.

@MSch
Created May 4, 2010 20:48
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MSch/389951 to your computer and use it in GitHub Desktop.
Save MSch/389951 to your computer and use it in GitHub Desktop.
<script>parent.changeParentUrl('<%= url %>');</script>
def post_process
redis = Redis.new
redis.set("pdf_progress:state:#{progress_token}", 'working')
pages.each do |page|
redis.set("pdf_progress:msg:#{progress_token}", "Converting page #{i} out of #{total}")
# Actually post-process the file....
end
redis.set("pdf_progress:state:#{progress_token}", 'done')
rescue
redis.set("pdf_progress:state:#{progress_token}", 'error')
end
class DocumentsController
def new
@document = Document.new
@uuid = UUID.generate :compact
end
def create
progress_token = params[:document][:progress_token]
@document = current_user.documents.new(params[:document])
respond_to do |format|
if @document.save
format.html {
render :partial => 'iframe_redirect', :locals => { :url => document_url(@document.token) }
}
end
end
end
def progress
progress_token = params[:token]
redis = Redis.new
render :json => {:state => redis.get("pdf_progress:state:#{progress_token}"),
:msg => redis.get("pdf_progress:msg:#{progress_token}")}
end
end
<script>
var uuid = '<%= @uuid %>';
var interval = null;
var req = null;
// Called when the user submits the form
function startUpload() {
interval = window.setInterval(function () {
updateUploadProgress();
}, 1000);
return true;
}
// Helper since parent document.location is read-only from iframe
function changeParentUrl(url)
{
document.location = url;
}
// Update the upload progress bar each second
function updateUploadProgress() {
if (req != null)
req.abort();
req = new XMLHttpRequest();
req.open("GET", "/documents/progress/upload", 1);
req.setRequestHeader("X-Progress-ID", uuid);
req.onreadystatechange = function () {
if (req.readyState == 4 && req.status == 200) {
var upload = eval(req.responseText);
document.getElementById('message').innerHTML = "Uploading...";
if (upload.state == 'done' || upload.state == 'uploading') {
bar = document.getElementById('progressbar');
w = 400 * 0.30 * upload.received / upload.size;
bar.style.width = w + 'px';
}
if (upload.received == upload.size || upload.state == 'done' || upload.state == 'error') {
window.clearTimeout(interval);
interval = window.setInterval(function () {
updateConversionProgress();
}, 1000);
}
}
}
req.send(null);
}
// Inform the user about the conversion progress
function updateConversionProgress() {
if (req != null)
req.abort();
req = new XMLHttpRequest();
req.open("GET", "/documents/progress?token=" + uuid, 1);
req.onreadystatechange = function () {
if (req.readyState == 4 && req.status == 200) {
var upload = eval('new Object(' + req.responseText + ')');
document.getElementById('message').innerHTML = upload.msg;
if (upload.state == 'done' || upload.state == 'error') {
window.clearTimeout(interval);
}
}
}
req.send(null);
}
</script>
<% form_for(@document, :url => "/documents/?X-Progress-ID=#{@uuid}", :html => {:multipart => true, :target => "uploadframe",
:onsubmit => "startUpload();"}) do |f| %>
<%= f.error_messages %>
<%= f.hidden_field 'progress_token', :value => @uuid %>
<%= f.file_field :pdf_file %>
<%= f.submit 'Upload' %>
<% end %>
<div id="progress" style="width: 400px; background-color: silver;">
<div id="progressbar" style="width: 1px; height: 10px; background-color: black;">
</div>
</div>
<div id="message"></div>
<iframe id="uploadframe" name="uploadframe" width="100%" height="100%" frameborder="0" border="0" src="about:blank"></iframe>
http {
upload_progress pdf_uploads 256k;
server {
passenger_enabled on;
passenger_use_global_queue on;
location ^~ /documents/ {
# Set the size limit to 100m for big uploads
client_max_body_size 100m;
# We need to repeat that line so that track_uploads works
# (track_uploads must be the last registered handler,
# so we need to register Passenger before track_uploads)
passenger_enabled on;
# Tracking data expires 30s after the upload finishes.
track_uploads pdf_uploads 30s;
}
# report tracked uploads
location ^~ /documents/progress/upload {
report_uploads pdf_uploads;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment