The Traffic Machine - a demonstration of background File Upload with Progress Bar
JavaScript Ruby
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
app
config
db
doc
public
script
test
vendor/plugins
.gitignore
Capfile
README.markdown
Rakefile

README.markdown

Developer Challenge

Design and implement a system that will accept a multipart form upload (say, containing an audio file) while displaying a percentage progress.

Structure

The basic HTML design should look like:

  • Display form with file input field
  • Display a title text field
  • Display a status text paragraph "select file"
  • Optionally display a submit button

Specification

  • When the user picks a file from their computer and optionally presses the submit button, the upload begins.
  • While uploading, the status text paragraph should be updating with the current percentage complete at least once every 2 seconds.
  • While uploading, the user should be able to enter text into the title text field.
  • When the upload completes, the status text should display the path on the server to the saved file.

Requirements

  • The upload should honor proxy settings on the browser
  • The system must function behind a firewall that blocks all but port 80
  • The server must support at least 2 concurrent uploads
  • Any technology that can be web deployed to IE, Firefox, Safari, Chrome on any platform is supported

Solution

I came up with a small & simple rails app called The Traffic Machine - a demonstration of background File Upload with Progress Bar.

According to the specs, two major issues had to be solved:

  1. upload the file in background, while user enters additional title/comment/text to the file
  2. get the upload progress and show it to the user

Usually, Flash solutions address those problems, but bring other disadvantages as well (wrong version/not installed/disabled). So I was looking for a solution without Flash. The latest specs of HTML5 give some further possibilities as well, but are not supported by majority of current web browsers (greetings to IE - ahhrgg!!!). See sources at the bottom for further info

Luckily, I didn't had to reinvent the wheel, as there are already good solutions for both problems out there. For the background upload, Ajaxupload looked just fine for me. It's a jQuery implementation of uploading a file to a hidden iFrame which happens in background and doesn't block the user from adding additional infromation.

To track the upload progress, I used the Apache-upload-progress Module, which adds an access point to Apache, so you can easily retrieve the total and uploaded file size in JSON format.

Basic Infrastrukture

The Magic

Deployment

Passenger File

<VirtualHost *:80> ServerName nups.loc DocumentRoot "/Users/ted/Sites/rails/fup/public" RailsEnv development RailsAllowModRewrite off

#Porter On #PorterSharedSecret fup

<directory "/Users/ted/Sites/rails/fup/public"> Order allow,deny Allow from all

needed for tracking upload progess

# enable tracking uploads in / TrackUploads On

<Location /progress> # enable upload progress reports in /progress ReportUploads On

Future Improvements

A quick step by step Howto:

  • get apachemodule, compile with: sudo apxs -c -i -a -Wc,-arch -Wc,ppc7400 -Wl,-arch -Wl,ppc7400 -Wc,-arch -Wc,x86_64 -Wl,-arch -Wl,x86_64 -Wc,-arch -Wc,i386 -Wl,-arch -Wl,i386 mod_upload_progress.c

  • update apache conf and create vhost

  • create rails app

  • add plugins

    • paperclip: config.gem 'paperclip', :source => 'http://gemcutter.org'
    • default value: script/plugin install git://github.com/FooBarWidget/default_value_for.git
    • jQuery + jRails: script/plugin install git://github.com/aaronchi/jrails.git
  • add blueprint css files

  • add basic html layout

  • add asset controller

  • add asset model, add uuid

  • add tests

  • add ajaxupload for background upload

  • add jQuery Ajax call to check upload progress

  • finish it up and make it nice

  • deploy with capistrano and git+passenger

Further reading and other resources: