http://snippets.dzone.com/posts/show/6175
http://uploadmovietool.appspot.com/. However, I just show a simple implementation both server side script (Rails) and client side script (JavaScript).
Let's start from select a file to upload with the help of Desktop API, openFiles(). You need to pass the callback, and some option attributes like filter and singleFile. After user has selected a file, the callback will be invoked with one parameter that is a File object of that file. Notice that, this file object has two properties: name and blob. Thus, you can use LocalServer API to capture this file by calling captureBlob() and passing blob object, a unique url for accessing this file, and a content type. If you don't provide a content-type, the browser doesn't know how to view this file when it has intercepted by LocalServer. Usually, it will launch a download of this file. Oop! Don't forget to create a localserver object. I assume you understand gears api good enough.
var desktop = google.gears.factory.create('beta.desktop');
desktop.openFiles(
function(files) {
var file = files[0];
if(!file) return;
//capture file for serving locally
fileName = file.name;
blobStore.captureBlob(file.blob, fileName, "image/JPEG");
},
{ filter: ['.jpg'], singleFile: true }
);
Next, you need to create a HttpRequest object. Then, you do a post to your server side script. You can set some request headers like: 'Content-Disposition', 'Content-Type', and 'Content-Range'. Gears provides an event handler called onprogress. When this event is triggered, you would get ProgressEvent object. This object has 3 properties: total, loaded, and lengthComputable. These 3 properties are useful in updating UI. Last, you need to pass the blob object to send() of HttpRequest object. You can do this by calling getAsBlob() and passing the url that previously called by captureBlob().
function upload() {
var xhrUpload = google.gears.factory.create("beta.httprequest");
xhrUpload.open("POST", '/upload/files');
xhrUpload.setRequestHeader('Content-Disposition', 'attachment; filename="' + fileName + '"');
xhrUpload.setRequestHeader('Content-Type', 'image/JPEG');
xhrUpload.setRequestHeader('Content-Range', 'bytes ' + file.blob.length);
//Update UI
xhrUpload.upload.onprogress = function(progressEvent) {
document.getElementById("status").innerHTML = ((progressEvent.loaded/progressEvent.total)*100).toFixed(0) + "%";
};
xhrUpload.onreadystatechange = function() {
switch(xhrUpload.readyState) {
case 4: //complete
document.getElementById("status").innerHTML = "done";
break;
}
};
xhrUpload.send(blobStore.getAsBlob(fileName));
}
In Rails, it is quite easy to handle actually. You just need to extract file name of request header 'HTTP_CONTENT_DISPOSITION'. Then, you perform an OS check to write a file of the whole request body. It is a method called raw_post of request object.
class UploadController < ApplicationController
def files
path = request.env['HTTP_CONTENT_DISPOSITION'][/^attachment\; filename="([^\"]+)"$/, 1]
if RUBY_PLATFORM.index("win")
File.open("public/images/#{path}", "wb") { |f| f.write(request.raw_post) }
else
File.open("public/images/#{path}", "w") { |f| f.write(request.raw_post) }
end
end
end
No comments:
Post a Comment