Skip to content

Commit

Permalink
Work on sorting out file uploads (currently no check for uploading twice
Browse files Browse the repository at this point in the history
to same location!)
  • Loading branch information
addrummond committed Jan 2, 2010
1 parent bdce194 commit 0fa7e88
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 51 deletions.
1 change: 1 addition & 0 deletions Makefile.PL
Expand Up @@ -19,6 +19,7 @@ requires 'Catalyst::Plugin::Session';
requires 'Catalyst::Plugin::Session::Store::FastMmap';
requires 'Catalyst::Plugin::Session::State::Cookie';
requires 'Catalyst::Plugin::RequireSSL';
requires 'Catalyst::Plugin::UploadProgress';
#requires 'Authentication::Store::Minimal';

catalyst;
Expand Down
3 changes: 3 additions & 0 deletions lib/IbexFarm.pm
Expand Up @@ -24,6 +24,9 @@ use Catalyst qw/ConfigLoader
Session::State::Cookie
RequireSSL
Cache::FastMmap
UploadProgress
/;
our $VERSION = '0.01';

Expand Down
37 changes: 3 additions & 34 deletions lib/IbexFarm/Controller/Ajax.pm
Expand Up @@ -155,7 +155,7 @@ my $get_wables = sub {
close $wable or die "Unable to close 'WRITABLE' file in browse request.";
# Ditto for the UPLOADED file (users can modify files which they uploaded).
open my $upl, catfile($base, 'UPLOADED') or die "Unable to open 'UPLOADED' file in browse request.";
my @upls = grep { $_ !~ /^\s*$/ } (map { chomp; $_; } <$wable>);
my @upls = grep { $_ !~ /^\s*$/ } (map { chomp; $_; } <$upl>);
close $upl or die "Unable to close 'UPLOADED' file in browse request.";
push @wables, @upls;
return @wables;
Expand Down Expand Up @@ -393,8 +393,6 @@ sub delete_file :Path("delete_file") {
# This is a bit unusual, in that it returns a string as its response (or the empty string
# for success) rather than JSON. This is to compensate for the inadequacies of the nasty
# Javascript handling the uploading.
my %currently_being_uploaded = ( );
my %currently_being_uploaded_sizes = ( );
sub upload_file :Path("upload_file") {
my ($self, $c) = (shift, shift);
$c->detach('unauthorized') unless $c->user_exists;
Expand All @@ -419,7 +417,7 @@ sub upload_file :Path("upload_file") {

my $file = $getfilename->($c, $expname, $dir, $fname);

if (defined $currently_being_uploaded{$file}) {
if (0) {#(defined $currently_being_uploaded{$file}) {
$ajax_headers->($c, 'text/html', 'UTF-8');
$c->res->body("This location is already being uploaded to.");
return 0;
Expand All @@ -440,27 +438,13 @@ sub upload_file :Path("upload_file") {
$expname,
IbexFarm->config->{ibex_archive_root_dir}));
my $fff = catfile($dir, $fname);
if ((-e $file) && (! grep { $_ == $fff } @wables)) {
if ((-e $file) && (! grep { $_ eq $fff } @wables)) {
$ajax_headers->($c, 'text/html', 'UTF-8');
$c->res->body("You do not have permission to upload to this location.");
}
else {
$currently_being_uploaded{$file} = 0;
$currently_being_uploaded_sizes{$file} = $u->size;
my $fh = $u->fh;

my $n;
while (($n = $fh->read(my $data, 1024*8)) > 0) {
$currently_being_uploaded{$file} += $n;
}
die "Error reading upload(ed/ing) file: $!" if ($n < 0);
$fh->close or die "Unable to close temporary file handle during upload: $!";

$u->copy_to($file) or die "Unable to copy uploaded file to final location: $!";

undef $currently_being_uploaded{$file};
undef $currently_being_uploaded_sizes{$file};

# Keep a record of the fact that the user uploaded this file, so that
# we know they're allowed to write to it. (First check that the user
# hasn't already uploaded this file to make sure that we don't add
Expand Down Expand Up @@ -491,21 +475,6 @@ sub upload_file :Path("upload_file") {
}
}

sub get_progress :Path("get_progress") {
my ($self, $c) = (shift, shift);
$c->detach('unauthorized') unless $c->user_exists;
$c->detach('bad_request') unless scalar(@_) == 3;

my ($expname, $dir, $fname) = @_;
my $file = $getfilename->($c, $expname, $dir, $fname);

$c->detach('default') unless (defined $currently_being_uploaded{$file});

$c->stash->{bytes} = $currently_being_uploaded{$file};
$c->stash->{size} = $currently_being_uploaded_sizes{$file};
$c->detach($c->view("JSON"));
}

sub rename_experiment :Path("rename_experiment") {
my ($self, $c) = (shift, shift);
$c->detach('bad_request') unless $c->req->method eq "POST";
Expand Down
63 changes: 46 additions & 17 deletions root/fman.js
Expand Up @@ -2,6 +2,18 @@ function show_date (date) {
return date[0] + '-' + date[1] + '-' + date[2] + ' ' + date[3] + ':' + date[4] + ':' + date[5];
}

var generateProgressID;
(function () {
var alpha = "0123456789abcdef";
generateProgressID = function () {
var id = '';
for(var i=0; i < 32; i++) {
id += alpha.charAt(Math.round(Math.random()*14));
}
return id;
}
})();

$.widget("ui.browseFile", {
_init: function () {
this.element.addClass("file").addClass(this.options.writable ? "writable" : "unwritable");
Expand Down Expand Up @@ -148,11 +160,13 @@ $.widget("ui.browseFile", {
if (upload) {
var intervalId;

var progressId = generateProgressID();
new AjaxUpload(upload, {
action: BASE_URI + 'ajax/upload_file/' +
escape(EXPERIMENT) + '/' +
escape(t.options.dir) + '/' +
escape(t.options.filename)
escape(t.options.filename) +
'?progress_id=' + progressId
,
name: "userfile",
autoSubmit: true,
Expand All @@ -166,20 +180,25 @@ $.widget("ui.browseFile", {
// Poll server for progress info on file upload.
var first = 0;
intervalId = setInterval(function () {
return;
if (! first++) return;
var xmlhttp = $.getJSON(
BASE_URI + 'ajax/get_progress/' +
escape(EXPERIMENT) + '/' +
escape(t.options.dir) + '/' +
escape(t.options.filename)
,
BASE_URI + 'progress?progress_id=' + progressId,
function (data) {
if (! (data && data.bytes && data.size))
clearInterval(intervalId);
else if (data.aborted) {
ulmsg.addClass("error");
ulmsg.text("Upload aborted.");
clearInterval(intervalId);
}
else {
var bytes = data.bytes;
var size = data.size;
ulmsg.text("Uploading: " + parseInt(bytes*100.0 / size) + "%");
if (size > 0)
ulmsg.text("Uploading: " + parseInt(bytes*100.0 / size) + "%");
if (bytes == size)
clearInterval(intervalId);
}
}
);
Expand Down Expand Up @@ -240,14 +259,17 @@ $.widget("ui.browseDir", {
.append($("<td>")
.append(upload_msg = $("<div>").hide()))));

var progressId = generateProgressID();
var intervalId;
new AjaxUpload(upload, {
action: BASE_URI + 'ajax/upload_file/' +
escape(EXPERIMENT) + '/' +
escape(t.options.dir)
escape(t.options.dir) +
'?progress_id=' + progressId
,
name: "userfile",
autoSubmit: true,
data: { },
data: { progress_id: progressId },
responseType: false,
onSubmit: function (file, extension) {
upload_msg.removeClass("error");
Expand All @@ -256,21 +278,26 @@ $.widget("ui.browseDir", {

// Poll server for progress info on file upload.
var first = 0;
var intervalId = setInterval(function () {
intervalId = setInterval(function () {
if (! first++) return;
var xmlhttp = $.getJSON(
BASE_URI + 'ajax/get_progress/' +
escape(EXPERIMENT) + '/' +
escape(t.options.dir) + '/' +
escape(file)
BASE_URI + 'progress?progress_id=' + progressId
,
function (data) {
if (! (data && data.bytes && data.size))
if (! (data && data.received && data.size))
clearInterval(intervalId);
else if (data.aborted) {
upload_msg.addClass("error");
upload_msg.text("Upload aborted.");
clearInterval(intervalId);
}
else {
var bytes = data.bytes;
var bytes = data.received;
var size = data.size;
upload_msg.text("Uploading: " + parseInt(bytes*100.0 / size) + "%");
if (size > 0)
upload_msg.text("Uploading: " + parseInt(bytes*100.0 / size) + "%");
if (bytes == size)
clearInterval(intervalId);
}
}
);
Expand All @@ -282,6 +309,8 @@ $.widget("ui.browseDir", {
}, 500);
},
onComplete: function (file, response) {
clearInterval(intervalId);

if (! response.match(/^\s*$/)) {
upload_msg.addClass("error");
upload_msg.html(response)
Expand Down

0 comments on commit 0fa7e88

Please sign in to comment.