dojox.form.Uploaderを使っててほいほいハマるので、ほぼ備忘録としてのメモ。
* POST時に他のデータも渡したい
uploadWithFormData()を使う。uploadOnSelectをtrueにすると勝手にsubmitされてしまうので、ファイルを選択されたらすぐにsubmitしたければ
<button data-dojo-type="dojox.form.Uploader" data-dojo-props="
id: 'uploader'
, name: 'uploaded'
, multiple: false
, uploadOnSelect: false
, url: 'xxx'
, onChange: function(){
doUpload();
}">upload now!</button>
function doUpload(){
var uploader = dijit.byId("uploader");
uploader.onComplete = function(array){
if (array[0] == "succeeded"){
// succeeded
}
else {
// failed
}
uploader.reset();
};
uploader.uploadWithFormData({
"hoge": "hoehoe"
});
}
とやっておけば概ねおk
* 1回目は動いたけど、2回目が動かない
ファイル名が同じだとonChangeが発生しない。同じファイル名でもsubmitしたければ、onCompleteの最後のほうでreset()を呼ぶ。
djangoでバッチ処理や非同期処理を組もうとしてceleryを導入。使い方も簡単でとても便利。
が、多重起動されたら困る処理を制限しようとしても、celery自体にはそういう機能がない模様。celeryのcookbookをみると、celery.task.Taskを継承したクラスを自分で作ればいいらしい。でもいちいちclassを定義するのは面倒。
というわけでdecoratorでsingletonなタスクを実現できるようにしてみた。
Webアプリを開発中で、ブラウザ側はdojoを使っているのですが、色々とハマっております。現在最も困っているのがdojox.grid.DataGridに埋め込んだdijit.form.Buttonの挙動。
dojox.grid.DataGridがなかなか強力で、これが使いたいためにdojoを選んだわけですが、このgridの各行にbuttonを配置すると途端に挙動が怪しくなってきます。
ファイルアップロードをする際にposterを使っています。とても便利なのですが、実体ファイルを構築して、posterに食わせて、ファイル削除、という手順が面倒だったので、tempfileを使ってみました。
# make temporary file
temp = tempfile.TemporaryFile()
temp.write(simplejson.dumps({
"seq": 1,
"abc": 123,
"def": "ASD"
}))
temp.write("\n")
temp.write(simplejson.dumps({
"seq": 2,
"abc": 123,
"def": "ASD"
}))
temp.write("\n")
temp.write(simplejson.dumps({
"seq": 3,
"abc": 123,
"def": "ASD"
}))
temp.flush()
temp.seek(0)
# encoding
datagen, headers = multipart_encode({
"args": "other parameter",
"datas": temp
})
# create request
request = urllib2.Request("http://localhost:8000/fileupload/", datagen, headers)
# do post !
response = urllib2.urlopen(request)
これで少なくともファイルの後始末は気にしなくてよいので便利。ちなみにSpooledTemporaryFileだとうまくいかない。rollover()すればイケるかもしれないけど未検証。
最近djangoでWebシステムを作るお仕事しています。python、djangoはなかなかよく出来ていてハマるところが少ないのですが、うっかり軽くハマったのでメモ。
あるクラスがあるクラスを継承しているかどうかをチェックするためには組み込み関数のissubclass()を使いますが、継承元が抽象クラスだとissubclass()はFalseを返してくるらしい。
最近TitaniumでiPhone&Androidアプリを作ってたりしますが、これが死ぬほどハマる地獄道でした。特にAndroid。iPhoneはそれなりにクセがあるけど、理解さえすればそうでもないのですが、Androidは別格です。
いまハマっているのはカメラ。ただ写真を撮って、それをアプリで使いたいだけなのに、なぜか写真を撮り終わったときのイベントハンドラが呼ばれない…。
var test_window = Ti.UI.createWindow({
title:'test',
backgroundColor:'#fff'
});
var tab_test = Ti.UI.createTab({
title: "test",
window: test_window
});
var label1 = Titanium.UI.createLabel({
color:'#999',
text:'I am Window 1',
font:{fontSize:20,fontFamily:'Helvetica Neue'},
textAlign:'center',
width:'auto'
});
test_window.add(label1);
label1.addEventListener("click", function(e){
Ti.Media.showCamera({
saveToPhotoGallery: true,
allowEditing: false,
mediaTypes: [Ti.Media.MEDIA_TYPE_PHOTO],
cancel:function(){
Ti.API.warn("camera cancelled");
},
error:function(){
Ti.API.warn("camera error");
},
success: function(event){
Ti.API.warn("camera succeeded");
}
});
});
やっているのはこれだけ。空っぽのprojectを作って、これをapp.jsに書くと動くのだけど、実際のアプリに組み込むとsuccessもcancelもerrorも呼ばれなくなったりするのです。どうやらapp.jsなら動くというところに回避策がありそうですが、いまのところドハマリ中。
他にもドキュメントに書いてあるけど未実装だったり、ググると出てくるサンプルコードがいまの最新では動かなかったり、そもそもそのサンプルで使ってるAPIはドキュメントに書いてなかったり、まぁ、いろいろ香ばしい。まだ実戦で使うものではない気がしてきています。
以前もハマったxibのローカライズ。またもハマりました。
どうやらxibをローカライズ前(言語環境毎のファイルを作る前)に実機転送してしまうと、その状態を覚えてしまうのか、その後どうやってもxibの内容が反映されなくなるという状態に陥りました。わけわかんない。
他にも、今回はNSLocalizedStringでいままで取れていた日本語リソースが、ある時点を境に英語しか取れなくなったりと、ローカライズ関連でハマりまくりです。
NSLocalizedStringのほうはどうやらフォルダの名前に問題があった模様。古いXcodeで作ったprojectなので、English.lproj や Japanese.lproj とかになっていたのですが、これを en.lproj 、 ja.lproj に変更したら日本語が取れるようになりました。
xibのほうは最後まで解決策がわからず。
仕方ないのでファイル名をrenameしました。renameするととりあえず反映されるようになりました。ホントにもう、わけわかんない。
iPhoneで開発してて、よく突き当たるのがEXC_BAD_ACCESS。
大抵は多重releaseしてしまうなどの単純ミスですが、稀に不可解なEXC_BAD_ACCESSに陥ることがありますよね。今回たまたま不可解なEXC_BAD_ACCESSが解決できたので、その顛末を参考までに書いてみます。
UIWebViewはデフォルトで、リンクを長押ししてるとActionSheetが出てきます。選択肢がOpenとCopyしかないので、実質あまり意味がなかったりしますが。
なのでこのActionSheetのボタンをアプリでカスタマイズしたい諸兄も多いことでしょう。
そんなときのTips。
UIWebViewではページの読込ませ方によってcanGoBack, canGoForwardの挙動が変わるようです。
これはcanGoBackだけでなく、実際にgoBackしても動作しなくなります。historyがきちんと更新されるのはloadRequest:だけのようです。
Javascriptでhistoryがいじれるといいのですが、試しにやってみたところ期待通りにはいきませんでした。できそうなものなんですけどね、、