Gearsのドキュメントはアップロードについての情報不足な気がする。というわけであとで忘れないようにめも。ここではバイナリファイルをアップロードする場合です。
構成ファイル
DEMO
実際にファイル保存しないようになってますがプログレスバーは動きます。
gears.js
addEvents(window, 'load', function(){ var file; var bg = document.getElementById('progress_bg'); var text = document.getElementById('progress_text'); var uinfo = document.getElementById('upload_info'); var status = document.getElementById('progress_status'); var selectFile = document.getElementById('select'); var uploadFile = document.getElementById('upload'); var desktop = google.gears.factory.create('beta.desktop'); var request = google.gears.factory.create('beta.httprequest'); var KB = 1024; var MB = KB * 1024; var GB = MB * 1024; var toFixedSize = function(num){ var length = parseFloat(num); if(length > GB) return (length/GB).toFixed(2) + ' GB' else if(length > MB) return (length/MB).toFixed(2) + ' MB' else return (length/KB).toFixed(2) + ' KB'; } addEvents(selectFile, 'click', function(){ file = null; uinfo.innerHTML = ''; bg.style.width = '0%'; var options = { singleFile: true, filter: [ 'video/quicktime','video/avi', 'video/mpeg', 'video/mpg'] }; desktop.openFiles(function(files){ if (files.length) { var file_info = document.getElementById('file_info'); file = files[0]; file_info.innerHTML=(file.name + ' : '+ toFixedSize(file.blob.length)); text.innerHTML = '0 of ' + toFixedSize(file.blob.length) + ' : 0%'; } } , options); }); addEvents(uploadFile, 'click', function(){ if (file) { request.open('POST', 'upload.php?fname='+file.name+'&fsize='+file.blob.length); request.onreadystatechange = function(){ if (request.readyState == 4) { if (request.status != 200){ uinfo.innerHTML = "upload failed: " + toFixedSize(request.responseText); }else { uinfo.innerHTML= "Complete : " + toFixedSize(request.responseText); console.log(request.responseText); } } }; request.upload.onprogress = function(e){ var percent = Math.round( (e.loaded / e.total) * 100 ); bg.style.width = percent + '%'; text.innerHTML = toFixedSize(e.loaded) + ' of ' + toFixedSize(e.total) + ' : '+ percent + '%'; }; request.send(file.blob); } }); }); function addEvents(elem, eventType, func, cap) { var capture = cap || false; if(elem.addEventListener) { elem.addEventListener(eventType, func, capture); } else if(elem.attachEvent) { elem.attachEvent('on' + eventType, func); } else { return false; } }
upload.php
<?php $length = $_GET['fsize']; $fd = fopen("php://input", "r"); while($data = fread($fd, 1024 * 1024)) file_put_contents( "./{$_GET['fname']}", $data, FILE_APPEND); echo $length;
index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="content-script-type" content="text/javascript" /> <meta http-equiv="content-style-type" content="text/css" /> <title>Gearsでプログレスバー付きアップロードのテスト</title> <link href="upload.css" rel="stylesheet" type="text/css" media="all" /> <script type="text/javascript" src="gears_init.js"></script> <script type="text/javascript" src="gears.js" charset="utf-8"></script> </head> <body> <h1>Gearsでプログレスバー付きアップロードのテスト</h1> <div id="file_info"></div> <div id="upload_info"></div> <div id="progress_bar"> <div id="progress_bg"></div> </div> <div id="status_window"> <div id="progress_status"></div> <div id="progress_text"> 0 of 0 : 0%</div> </div> <button type="button" id="select">select</button> <button type="button" id="upload">upload</button> </body> </html>
まず手順としては
1.selctボタンを押してアップロードしたいファイルを選択。
(Gearsのdesktopを使って動画ファイルだけをフィルタリングして選択)
2.uploadボタンを押してファイルをアップロード。
(Gearsのhttprequestとblobの機能をつかって動画をアップロード)
細かく見てくと
gears.jsの23行目あたりの
addEvents(selectFile, 'click', function(){
でselectボタンを押したときのハンドラ.
まず、
file = null; uinfo.innerHTML = ''; bg.style.width = '0%';
で初期化。 ファイル選択はdesktop.openFiles(callback, [options])を呼び出す必要があるので
var options = { singleFile: true, filter: [ 'video/quicktime','video/avi', 'video/mpeg', 'video/mpg'] };
でGearsのdesktop.openFilesに渡すoptio設定.filterでファイル選択のときにフィルタがかけれる。
callbackの引数には選択したファイルが入るのでそれをつかってごにょごにょ。
次にuploadボタンを押したときの動作は38行目あたりから。
request.open('POST', 'upload.php?fname='+file.name+'&fsize='+file.blob.length);
バイナリファイルなんでPOSTでアップするけど58行目あたりを見てもらうとわかるように
request.send(file.blob);
バイナリデータしか送れないみたいなんで、urlにくっつけてGETでファイル名を取得させる。
42行目あたりのonreadystatechangeで正しくアップロードできたかの判定。適当。
request.onreadystatechange = function(){ if (request.readyState == 4) { if (request.status != 200){ uinfo.innerHTML = "upload failed: " + toFixedSize(request.responseText); }else { uinfo.innerHTML= "Complete : " + toFixedSize(request.responseText); console.log(request.responseText); } } };
53行目当たりの
request.upload.onprogress = function(e){ var percent = Math.round( (e.loaded / e.total) * 100 ); bg.style.width = percent + '%'; text.innerHTML = toFixedSize(e.loaded) + ' of ' + toFixedSize(e.total) + ' : '+ percent + '%'; };
がプログレスバー表示部分。POSTかPUTを使うとuploadってオブジェクトが帰ってくるらしいのでその中のonprogressを使ってます。 かえってくるprogressEventの情報にはloadedとtotalがあるのでそれでちょこちょこ。
モード(エイリアス) | 引数 | 動作 |
---|---|---|
web(search,s,w) | [keywords] | google検索 |
images(image,i) | [keywords] | google画像検索 |
wiki(wikipedia) | [keywords] | ウィキペディア検索 |
news(n) | [keywords] | googleニュース検索 |
blogs(blog,b) | [keywords] | googleブログ検索 |
feeds(feed,f) | [keywords] | googleフィード検索 |
video(videos,v) | [keywords] | googleビデオ検索 |
place(places,map,p) | [address] | googleマップ検索 |
translate(trans,t) | [lang1] [lang2] <words> | google翻訳。lang1からlang2にwordsを翻訳する |
コマンド(エイリアス) | 引数 | 動作 |
---|---|---|
lucky(l) | [keywords] | 検索と同時に一番目のリンクに飛ぶ |
clear© | 画面をクリアする | |
help(man,h,?) | [command] | へるぷ |
open(o) | <url> | 新しい窓でurlに飛ぶ |
go(g) | <url> | urlに飛ぶ |
more(m) | 検索結果をもっと出す | |
in(site) | <url> <keywords> | search in a specific website |
load | <extension_url> | エクステンションを読み込み |
read(rss,r) | <url> | urlのフィードを読み込み |
lang | <language> | 言語変更 |
addengine | firefoxの検索ボックスにgooshを追加する | |
ls | [command] | gooshなls |
cd | <mode> | modoを変更する |
こんなかんじ
guest@goosh.org:/web> lang ja #言語を日本語に
guest@goosh.org:/web> cd blog #blog検索にモード変更 guest@goosh.org:/blog>
guest@goosh.org:/web> translate ja en 名前解決 #名前解決を日本語から英語に翻訳 translating "名前解決" from "japanese" to "english": "Name resolution"