How to efficiently show file elaboration

In a project I recently worked in we have the problem to provide users of a web application a nice graphical interface that showed the upload of some files from the user’s PC to the application server. The interface had also the task to give a visual feedback about the elaboration occurring in the application server.

A first implementation

After some experiments with ugly progress bars I came out with the following interface, loosely inspired Google Chrome download bar.

Here you can see the main idea behind the file uploader interface implemented.
The progress bar around the file icon:

  • is turned off when the file is ready to be uploaded;
  • is blue while uploading;
  • turns fully green if the upload succeeds;
  • turns fully red in case the upload fails.

More over while the upload is progressing the length of the blue bar represents the amount of data already upload. There is also a spinner effect to make the user aware of the fact the system does not hang up.

A better implementation

What was missing here was in first hand the clear distinction between the upload phase, which can be perfectly shown, measuring the amount of data uploaded, and the elaboration phase on the application server. In the second hand there was not any feedback about the upload speed.

So I updated the first prototype in the following way.

Here the spinner rotates anticlockwise while uploading and clockwise while waiting for the application server to complete the elaboration of the just uploaded file. This gives quite clearly the user the idea that there is a first uploading phase for which the application can show the progress, and another phase which lasts for a undefined amount of time.

More over, during the upload phase, the spinner velocity is someway proportional to the upload speed, giving another visual feedback.

Drop me a comment if you need some feedback about this solution.

Http commons too standard for some web servers

I spent a whole day trying to figure out how to use http components to send a file from a java program mimicking a POST multipart/form-data form.

The problem was that while a common HTML form worked with no problems at all, the POST generated with http commons was always rejected by the server.

So, I decided to dump the HTTP requests sent by the browser and by http components, and here’s what I got.

Request generated from the browser

------WebKitFormBoundaryYuxYFZoJg4fx2Tfu

Content-Disposition: form-data; name="filename"; filename="index.idx"
Content-Type: application/octet-stream
[file content]

------WebKitFormBoundaryYuxYFZoJg4fx2Tfu--

Request generated from http commons

--xFwQ1jzWbqQIKivTUrK68BurHld66kpMCz3Fv9P

Content-Disposition: form-data; name="filename"; filename="index.idx"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
[file content]
--xFwQ1jzWbqQIKivTUrK68BurHld66kpMCz3Fv9P--

As you can see there’s a “Content-Transfer-Encoding: binary” header that is the one that caused the problem in the server. After a while I discover than when you create a new MultipartEntity, you can optionally specify a mode of operation. Currently supported modes are HttpMultipartMode.STRICT and HttpMultipartMode.BROWSER_COMPATIBLE. It’s not worth to mention that the default mode in STRICT, that maybe does not work with old or not fully standard web servers. If BROWSER_COMPATIBLE is specified instead, the data sent by http commons does not contain any Content-Transfer-Encoding header, and the delivery of the file terminates successfully.

Here’s the piece of code:

MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);

Provide all Ruby Enterprise dependencies

I was trying to install Ruby Enterprise on my Ubuntu machine. I discover you need to be sure to have some package installed if you really want to build all gems needed by Ruby On Rails.
So be sure to install at least the headers for mysql and sqlite before installing Ruby Enterprise.

$ sudo apt-get install libmysqlclient-dev
$ sudo apt-get install libsqlite3-dev

Afterward you can compile the related gems with the following commands.

$ sudo /opt/ruby-enterprise-1.8.7-2010.02/bin/gem install mysql
$ sudo /opt/ruby-enterprise-1.8.7-2010.02/bin/gem install sqlite3-ruby

Worth reading

http://amitava1.blogspot.com/2010/08/ruby-on-rails-on-centos-55-with.html
http://ubuntuforums.org/showthread.php?t=637973
http://theplana.wordpress.com/2007/05/11/install-sqlite3-on-ubuntu/

Svn toolkit

This is a quick SVN reference I update regularly, with the commands I use more. I hope you’ll find it useful.

Task: Browse a remote repository

  1.  svn ls svn+ssh://[alias]/[path]

Task: create a directory on a remote repository

  1.  svn mkdir -m "[message]" svn+ssh://[alias]/[path_to_new_dir]

Task: import a directory

  1. svn import -m "[message]" [path_to_be_imported] [repository_url]

Task: check out

  1. svn checkout [repository url]

Assert statement in Objective C

Hi,
if you like to use assertions in your source code, but you miss this feature in ObjectiveC, give a look to this small class.
Assert.h

  1. #import <Foundation/Foundation.h>
  2. @interface Assert : NSObject {
  3. }
  4. +(void)that:(BOOL)expr;
  5. @end

Assert.m

  1. #import "Assert.h"
  2. @implementation Assert
  3. +(void)that:(BOOL)expr{
  4.  if (!expr) {
  5.   [NSException raise:@"Failed assertion." format:@"Failed assertion", nil];
  6.  }
  7. }
  8. @end

As you can see, there’s only one static method that you can use wherever you want.
In this snippet here’s an example how to use it.

  1. #import "Assert.h"
  2. -(void)doSomething{
  3.  [Assert that:(<your_assertion>)];
  4. }