* Refined upload.pl a lot, moving it into Anvil::Tools. It also now handles file name collisions and reports basic info about the uploaded file.
* Updated Get->uuid to take the new 'short' parameter that, when passed, asks for just the first 8 bytes of the UUID string. Signed-off-by: Digimer <digimer@alteeve.ca>main
parent
b5378252fd
commit
dd2b9ec026
8 changed files with 154 additions and 51 deletions
@ -1,73 +1,95 @@ |
|||||||
#!/usr/bin/perl |
#!/usr/bin/perl |
||||||
|
# |
||||||
|
# This is a special-purpose mini program used to handle upload requests. It has it's own micro-handling of |
||||||
|
# CGI specifically set to grab data when triggered by Striker using the 'jQuery Upload File Plugin' from |
||||||
|
# files.js. |
||||||
|
# |
||||||
|
# |
||||||
|
|
||||||
use strict; |
use strict; |
||||||
use warnings; |
use warnings; |
||||||
use CGI; |
use CGI; |
||||||
|
use Anvil::Tools; |
||||||
|
|
||||||
my $cgi = CGI->new; |
# Turn off buffering |
||||||
print q|Content-type: text/html; charset=utf-8 |
$| = 1; |
||||||
|
|
||||||
<!DOCTYPE html> |
my $THIS_FILE = ($0 =~ /^.*\/(.*)$/)[0]; |
||||||
<html lang="en_CA"> |
my $running_directory = ($0 =~ /^(.*?)\/$THIS_FILE$/)[0]; |
||||||
<head> |
if (($running_directory =~ /^\./) && ($ENV{PWD})) |
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
{ |
||||||
|
$running_directory =~ s/^\./$ENV{PWD}/; |
||||||
<!-- Disable caching during development. --> |
} |
||||||
<meta http-equiv="cache-control" content="max-age=0" /> |
|
||||||
<meta http-equiv="cache-control" content="no-cache" /> |
|
||||||
<meta http-equiv="expires" content="0" /> |
|
||||||
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" /> |
|
||||||
<meta http-equiv="pragma" content="no-cache" /> <title>Alteeve - Striker</title> |
|
||||||
|
|
||||||
<link rel="stylesheet" href="/skins/alteeve/main.css" media="screen" /> |
|
||||||
<script type="text/javascript" src="/jquery-latest.js"></script> |
|
||||||
<script type="text/javascript" src="/skins/alteeve/main.js"></script> |
|
||||||
|
|
||||||
<!-- NOTE: These are for jquery-ui using the 'smoothness' skin. We may want to move this under the skin directory in case other skins want to use different jquery-ui skins someday. --> |
|
||||||
<link rel="stylesheet" href="/jquery-ui-latest/jquery-ui.css"> |
|
||||||
<script type="text/javascript" src="/jquery-ui-latest/jquery-ui.js"></script> |
|
||||||
|
|
||||||
<script type="text/javascript" src="/skins/alteeve/files.js"></script> |
|
||||||
<link rel="stylesheet" href="/skins/alteeve/files.css"> |
|
||||||
|; |
|
||||||
|
|
||||||
|
my $anvil = Anvil::Tools->new(); |
||||||
|
$anvil->Log->level({set => 2}); |
||||||
|
|
||||||
my $lightweight_fh = $cgi->upload('field_name'); |
my $cgi = CGI->new; |
||||||
|
|
||||||
|
print "Content-type: text/html; charset=utf-8\n\n"; |
||||||
|
print $anvil->Template->get({file => "files.html", name => "upload_header"})."\n"; |
||||||
|
|
||||||
|
my $lightweight_fh = $cgi->upload('field_name'); |
||||||
# undef may be returned if it's not a valid file handle |
# undef may be returned if it's not a valid file handle |
||||||
if ($cgi->param()) |
if ($cgi->param()) |
||||||
{ |
{ |
||||||
print q| |
my $start = time; |
||||||
<title>Saving File...</title> |
|
||||||
</head> |
|
||||||
<body> |
|
||||||
|; |
|
||||||
my $filename = $cgi->upload('upload_file'); |
my $filename = $cgi->upload('upload_file'); |
||||||
my $out = "/mnt/shared/incoming/".$filename; |
my $out_file = $anvil->data->{path}{directories}{shared}{incoming}."/".$filename; |
||||||
print "Saving file: [".$out."]\n"; |
if (-e $out_file) |
||||||
|
{ |
||||||
|
# Don't overwrite |
||||||
|
$out_file .= "_".$anvil->Get->date_and_time({file_name => 1}); |
||||||
|
|
||||||
|
# If this exists (somehow), we'll append a short UUID |
||||||
|
if (-e $out_file) |
||||||
|
{ |
||||||
|
$out_file .= "_".$anvil->Get->uuid({short => 1}); |
||||||
|
} |
||||||
|
} |
||||||
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 1, key => "log_0259", variables => { file => $out_file }}); |
||||||
my $cgi_file_handle = $cgi->param('upload_file'); |
my $cgi_file_handle = $cgi->param('upload_file'); |
||||||
open(my $file_handle, ">$out") or die "failed to write: [$out], error: $!\n"; |
open(my $file_handle, ">$out_file") or $anvil->Log->entry({source => $THIS_FILE, line => __LINE__, level => 0, secure => 0, priority => "err", key => "log_0016", variables => { shell_call => $out_file, error => $! }}); |
||||||
while(<$cgi_file_handle>) |
while(<$cgi_file_handle>) |
||||||
{ |
{ |
||||||
print $file_handle $_; |
print $file_handle $_; |
||||||
} |
} |
||||||
close $file_handle; |
close $file_handle; |
||||||
print "Done.\n"; |
|
||||||
|
### NOTE: The timing is a guide only. The AJAX does a lot of work before this script is invoked. It |
||||||
|
### might be better to just remove the timing stuff entirely... |
||||||
|
my $size = (stat($out_file))[7]; |
||||||
|
my $say_size_human = $anvil->Convert->add_commas({number => $size}); |
||||||
|
my $say_size_comma = $anvil->Convert->bytes_to_human_readable({'bytes' => $size}); |
||||||
|
my $took = time - $start; |
||||||
|
$took = 1 if not $took; |
||||||
|
my $say_took = $anvil->Convert->add_commas({number => $took}); |
||||||
|
my $bytes_per_second = $anvil->Convert->round({number => ($size / $took), places => 0}); |
||||||
|
my $say_rate = $anvil->Words->string({key => "suffix_0001", variables => { number => $anvil->Convert->bytes_to_human_readable({'bytes' => $bytes_per_second}) }}); |
||||||
|
my $file_sum = $anvil->Get->md5sum({file => $out_file}); |
||||||
|
$anvil->Log->variables({source => $THIS_FILE, line => __LINE__, level => 2, list => { |
||||||
|
size => $size, |
||||||
|
say_size_human => $say_size_human, |
||||||
|
say_size_comma => $say_size_comma, |
||||||
|
took => $took, |
||||||
|
say_took => $say_took, |
||||||
|
bytes_per_second => $bytes_per_second, |
||||||
|
say_rate => $say_rate, |
||||||
|
file_sum => $file_sum, |
||||||
|
}}); |
||||||
|
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, key => "log_0260", variables => { |
||||||
|
file => $out_file, |
||||||
|
size_human => $say_size_human, |
||||||
|
size_bytes => $say_size_comma, |
||||||
|
rate => $say_rate, |
||||||
|
took => $say_took, |
||||||
|
md5sum => $file_sum |
||||||
|
}}); |
||||||
} |
} |
||||||
else |
else |
||||||
{ |
{ |
||||||
print q| |
# Why are we here? |
||||||
<title>Test Upload</title> |
$anvil->Log->entry({source => $THIS_FILE, line => __LINE__, 'print' => 1, level => 1, priority => "warn", key => "log_0261", variables => { file => $THIS_FILE }}); |
||||||
</head> |
|
||||||
<body> |
|
||||||
<h1>Upload file</h1> |
|
||||||
<form method="post" enctype="multipart/form-data"> |
|
||||||
<!-- <input type="file" name="upload_file" value="Choose file"> --> |
|
||||||
<!-- <input type="submit" name="submit" value="Upload"> --> |
|
||||||
Upload |
|
||||||
<div id="fileuploader">Upload</div> |
|
||||||
</form> |
|
||||||
|; |
|
||||||
} |
} |
||||||
print "</body>\n"; |
|
||||||
|
|
||||||
exit(0); |
exit(0); |
||||||
|
Loading…
Reference in new issue