Hello, please sign in or register
You are here: Home

Gears multiple file Upload

I wrote the script below because i couldn't find a plain simple implementation of the gears file uploader.

What is it?

The script below opens with a link to select files. The user may select multiple files from the popup. This i find is the main benefit of Gears which is not catered for in the HTML standard as yet. Alternatives can be found in Flash and Java applets - which are more widely distributed than Gears.

Multiple files selected...

This example also splits files using the blob.slice method. And allows data to be sent in chunks to the master... "This is more beneficial for medium to large files >100MB" say Google. Its in this skit - for fun - but its more than i need.

Example

You must have gears installed in your browser, if your not sure then visit http://gears.google.com/.

sorry, for example simply copy and paste the below script and run locally. Or the slightly maturer version  [Download php gearsuploader]

Code

My example script has the function "upload()" commented out in the declaration of "sendChunk()". This is a nice way to see the file/s which has been partially uploaded (if file >200KB). Click the "Upload" link again and the uploader will send the next chunk of data. The files are stored in the same path as where the script is based by default play around with this and watch the files grow.

Uncomment the "upload()" in "sendChunk()" and the files will be completely uploaded without the need for  prompt. Note that data is appended to files with the same name (so you could mess something up if your not careful).

<?php
/**
 * PHP Gears Multiple File Loader
 * This application uses the Google Gears API, to select and load multiple files
 * 
 * Resources: 
 * 		Brad Neuberg (http://codinginparadise.org)
 * 		Gears (http://gears.google.com)
 * 
 * @author Andrew Dodson
 */
if ( !empty( $_GET['n'] ) )	
{
	$fd = fopen("php://input", "r");
	while( $data = fread( $fd, 10000000 ) ) file_put_contents( "./{$_GET['n']}", $data, FILE_APPEND );
}

?>
<html> 
<head> 
<title>Hello World for the File System API</title> 
<script type="text/javascript" src="http://code.google.com/apis/gears/gears_init.js" ></script>
<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.2.6.min.js" ></script>
<script type="text/javascript">


 
window.onload = function() {
  if (!window.google || !google.gears) {
    addStatus('Gears is not installed', 'error');
    return;
  }
}

var CHUNK_BYTES		= 200000; 	// Send file in packets of 200KB
var MAX_FILE_SIZE	= 10000000;	// Limit the total upload size to 10MB
var UPLOAD_RETRIES	= 3;		// Number of retries
var mylist		= {}; 		// Array of file and properties
var fileName		= "";		// Index of mylist that is being processed

/**
 * Display information to the client
 */
function addStatus(s){ $("#status").append( s + "<br />" ); return 1;}

/**
 * Get the minimum of two results.
 */
function min(a,b){ return (a<b?a:b); }

/**
 * Open file browser window
 */
function browse(){
	var desktop = google.gears.factory.create('beta.desktop');
	desktop.openFiles( function(files) {
		
		for ( var i = 0; i < files.length; i++ )
		{
			if ( mylist[files[i].name] ){ continue; } // Has the file by the same name already been selected?
			
			mylist[files[i].name] = {
				filename:	files[i].name, 
				uploaded:	0,
				length: 	files[i].blob.length, 
				blob:		files[i].blob, 
				bytesUploaded: 0,
				status:		(files[i].blob.length>MAX_FILE_SIZE?"File too large":"Pending")};
			
			addStatus( "Selected: " + files[i].name + " " + files[i].blob.length );
		}
		$('#upload').html('<a href="#upload" onclick="return upload();">Upload</a>');
	},
    {  }
    //  { singleFile: true }
	);
}

function upload()
{
	var chunkLength, chunk;

	/**
	 * Loop through the files and upload the next file/chunk
	 */

	for ( file in mylist ) if ( ( mylist[file].uploaded < mylist[file].length && !mylist[file].error ) )
	{
		/**
		 * what is the current filename
		 */
		fileName = file;
		chunkLength = min( mylist[file].uploaded + CHUNK_BYTES, mylist[file].length);
		addStatus( "Uploading " + fileName + ": from " + mylist[file].uploaded + " to " + chunkLength );

		/**
		 * Get the next chunk to send.
		 */
		chunk = mylist[file].blob.slice( mylist[file].uploaded, (chunkLength - mylist[file].uploaded) );
		addStatus( "Chunk length " + chunk.length );
		
		/**
		 * Send Chunk
		 */
		sendChunk( mylist[file], chunk, mylist[file].uploaded, chunkLength, mylist[file].length );
		break;
	}
}


function sendChunk ( entry, chunk, start, end, total )
{
	var req = google.gears.factory.create('beta.httprequest');
	var prcnt = Math.ceil( ( end/total ) * 100 );
	/**
	 * Start Post
	 */
	req.open('POST', '?n='+encodeURIComponent(fileName)+'&b='+encodeURIComponent(start) );

	/**
	 * Assign Headers
	 */
	var h = { 'Content-Disposition'	: 'attachment; filename="' + fileName + '"', 
					'Content-Type' 	: 'application/octet-stream',
					'Content-Range'	: 'bytes ' + start + '-' + end + '/' + total };
	
	for( var x in h ) if (h.hasOwnProperty(x)) { req.setRequestHeader( x, h[x] ); }
	
	/**
	 * Build Response function
	 */
	req.onreadystatechange = function(){
		if (req.readyState == 4 && addStatus( "Resp: (" + req.status + ")" ) && req.status == 200 ) {
			entry.uploaded = end;
			addStatus( fileName + ( (end + 1) >= total ? " Finished" : ' Upload: so far ' + prcnt + '%' ) );
			//upload();
		}
	}

	/**
	 * Send Chunk
	 */
	req.send(chunk);
}

</script>


</head>
<body style='font-family:verdana;'>
<div>
	<a href="#select" onClick="return browse();">Select File</a>
	<span id="upload"></span>
</div>
<p id="status"></p> 
</body> 
</html> 

... and that should get you started

 

Alternatives

Flash: https://user.sitepen.com/~mwilcox/dojotoolkit/demos/uploader/demo.html?multiMode

HTML 5: http://www.w3.org/html/wg/html5/#file-upload-state ( this includes the "accept=filetype" attribute and there is some hint of multiple files, but its unclear what attribute this will take )

Comments

Ties
Hero!
Created 22/02/09
ltYqoaTxlAwhbcpL
Superbly illuminating data here, tahkns!
Created 18/08/11
wwhnOVgtWOhYBZ
QLQYn8 jyvtzykinxur
Created 18/08/11
coXvagoG
st7r8n , [url=http://nlapvzywjxcj.com/]nlapvzywjxcj[/url], [link=http://yewcureksgxw.com/]yewcureksgxw[/link], http://outmuyijwrex.com/
Created 19/08/11
tmNxMyqKPh
SWG35P pyzbbjxaqntj
Created 25/08/11
UPcjcgddOSeLvHTZ
zLIgGH , [url=http://tqmiecdxeted.com/]tqmiecdxeted[/url], [link=http://lcdmzlflztkt.com/]lcdmzlflztkt[/link], http://eutmbxqvhtkp.com/
Created 30/08/11
wq123
This hilfiger outlet time swarovski jewelry something really timberland outlet strange, ...
Created 30/06/16
ninestab123
ninest123 One canada goose pas cher gucci outlet thing
Created 21/07/16
cc
discount oakley sunglasses retro jordans
Created 26/10/16
Title*
Comment

Prove you are not a robot

To prove you are not a robot, please type in the six character code you see in the picture below
Security confirmation codeI can't see this!
Contact
Name*
Email never shown*
Home Page

Author

Andrew Dodson
Since:Feb 2007

Comment | flag

Categories

Bookmark and Share