サクサク読めて、アプリ限定の機能も多数!
トップへ戻る
パリ五輪
piro-suke.hatenablog.com
ここ数件のプロジェクトでリストやテーブルの行追加、削除やソート、上下移動などの処理を書く事があったので、メモしておく。 今回は行の上下移動。リストの各行に「上へ」「下へ」というボタンなりリンクなりアイコンなりを配置しておき、それをクリックすると対象の行が上下に移動するというもの。 test.html ... script type="text/javascript" src="/js/jquery/jquery-1.3.1.min.js">script> script type="text/javascript" src="/js/test.js">script> ... ul id="test-list"> li class="test-row"> input type="hidden" name="data" value="1:id1" /> span class="title">デー
Jinja2を導入すれば簡単に国際化できると思ったら大間違いだった。Jinja2と国際化フレームワークのBabelを使うことで、Djangoの国際化機能と同じようなことが実現できる、ということだったらしい。何度か「Kay Frameworkにしときゃ良かったか...」と思った。 苦労したけどどうにかこうにか国際化できたので、方法をメモっておく。ちなみにappengineでJinja2を使う方法については別の記事に書いたのでそちらも良かったらお読みください。 Babelの本サイト(ダウンロードとマニュアル)http://babel.edgewall.org/ Babelの使い方について参考にさせていただいた記事http://d.hatena.ne.jp/nullpobug/20100923/1285251361 下記のような方法をとりました。 BabelとJinja2をインストールBabel
見つけにくかったのでメモ。コードがハイライトされるというだけで、ソースを載せたくなるのはなぜだろう。 タグに設定されたid属性から数値で設定されたID値を取得する。jQueryを使うとリストの中のliタグや、テーブルの中のtdタグに設定されたIDを一括で取得することができる。 rex = RegExp("model_([0-9]+)"); var id_list = []; var id = 0; $("#sample-list li").each(function() { var item = $(this); if (item.attr("id").match(rex)) { id = RegExp.$1; } id_list.push(id); }); //id_listを処理 Javascriptで分からない事を検索すると、古い情報がたくさん出てきて目的の情報が見つからない事が多い
FoursquareのAPIのv2でモバイル版の認証画面が使えたりjsonpが使えたりするらしいので、移行してみた。OAuth認証処理が少し変わったので、それに合わせて作成した認証用クラスや処理を公開。 下記のような認証用クラスを作成した。 foursquare_oauth.py from google.appengine.api import urlfetch from google.appengine.ext import db from urllib import urlencode from urllib import quote as urlquote import logging from django.utils import simplejson as json class FsqOAuthToken(db.Model): """key_name is uid""" uid
jQuery Mobilehttp://jquerymobile.com/ いろいろはまったので、メモ。バージョンは 1.0 ALPHA 2。 page毎にHTMLを分けて作成するこれは好みだと思うのだけど、URL直指定でそれぞれのページを呼び出せたりするようにするなら、分けた方が簡単な気がした。 構成としては、下記のような形にしてる。 html> head> link rel="stylesheet" type="text/css" href="sample_base.css" /> script type="text/javascript" src="sample_base.js">script> head> body> div data-role="page" class="user-home-page"> link rel="stylesheet" type="text/css"
以前下記のURLでAppEngineでの全文検索についてあれこれ考える記事を書いたけど、実際に実装した例を載せてみる。http://d.hatena.ne.jp/piro_suke/20100721/1279643738 検証してないけどあまり多くのデータを検索対象にするには向いてないと思う。1ユーザーのデータとか、数人のプロジェクトのデータから検索するような事を想定。また、検索文字列が大きかったり、一度にインデックス化する件数を増やす場合はタスクキューを使う必要がありそう。以下は、プロジェクト別でツイートできるサービスで、そのプロジェクト内のツイートからキーワード検索を行なう例。 models.py from google.appengine.ext import db # pyshibazukeを呼び出すシリアライザ import projetter.serializer as ser
FoursquareのAPIを使って場所系のサービスでも作ってやろう、と思い立って作っている。 APIドキュメントのRate Limitingを読んだところ、認証済みの場合は認証ユーザー毎、認証していない場合はIPアドレス毎に1メソッドにつき1時間200アクセスまでと制限されているらしい。TwitterのAPIよりもGoogle App Engineで利用するのは大変じゃなさそう。 ドキュメントはこちら。http://groups.google.com/group/foursquare-api/web/api-documentation 認証処理はOAuthなのでTwitterの場合とほとんど同じ。僕はTwitterでAppEngine-OAuth-Libraryを使っていたのだけど、このライブラリのOAuthClientクラスを継承してFoursquare用のクライアントクラスを作成して
別の記事でも書いたけど、個人で開発しているWebアプリでは、だいたいjQuery UIを使用してる。 今回はその中でもよく利用しているdialogの使い方をまとめておく。dialog機能を使うと、割と簡単にエラーダイアログやフォーム表示用のサブウィンドウを作成することができる。http://jqueryui.com/demos/dialog/ 僕の使い方としては、あらかじめ使用するダイアログやサブウィンドウをHTML内に非表示で埋め込んでおき、必要な時にダイアログとして表示する、という方法をとっている。1つのファイルにまとまってると、本体のHTML、ダイアログ、サブウィンドウを区別なく編集できるので結構楽だと思う。 OKダイアログ(通知やエラー表示用)、確認ダイアログ、フォームダイアログをそれぞれ表示できるサンプルを書いておく。よく使うOKダイアログや確認ダイアログは関数化しておくと便利。
こちらのRuby版を参考にしました。http://d.hatena.ne.jp/tohtas/20100221/1266778938 サムネイル等で画像を縮小してから正方形にcropする。 image_api.py from google.appengine.api import images def resize_image(image_data, width, height): """画像のリサイズのみ""" image = images.Image(image_data) image.resize(width, height) return image.execute_transforms() def crop_image(image_data, width, height): """画像をリサイズしてcropする""" image = images.Image(image_data
Google App Engine には今のところ全文検索機能がないので、色々試してみた。検索処理についての知識は、Web+DB Pressの53号を読んだ程度。 やりたいことは、Twitterみたいな感じで各ユーザーが短い文章を登録するようなサービスで、その発言内容からキーワード検索したい。できれば、スペース区切りで複数のキーワードを指定して絞り込みができるようにしたい。appengineなので、インデックス作成や検索処理だけで割り当てがなくならない程度に効率的に。 下記の3つの方法を試してみた。接尾辞配列もどきn-gramもどき オーソドックスn-gram で、結果として、3番目のオーソドックスなn-gramが今のところうまく動いてるっぽい。失敗パターンにも色々学ぶところはあったので、それぞれメモをまとめておく。 接尾辞配列もどきまず最初に試したのがこれ。接尾辞配列というのは今回のサー
Google App Engineを使うようになって、リクエスト時間の節約のために重いページ(HTML)のロードは最初の1回だけにして、以降はページ遷移なしでAjaxでJSONのやりとりをしてビューを変更するような方法をとることが多くなった。 UIについても毎回デザインを考えるのも面倒だしロクなものができなかったので、jQueryUIとjQuery UI.Layout Pluginを利用するようになった。この2つを利用するだけでアプリケーション風のUIが実現できて、UI関連の悩みをほぼ解消してくれた。 jQueryUIはボタンやタブ、アコーディオンメニューなどのUIウィジェットを、jQueryUIのサイト上で作成したデザインテーマに合わせて表示してくれるので、統一感のあるデザインがてっとり早くできる。自分でカスタマイズした設定を再編集できるようにしてくれたらもっと便利なのだけど。http:
Webフォームから送信されたデータを保存後にメールでユーザーやら担当者やらに送信する処理が必要な事が多い。メール送信処理は結構重いので、リクエスト中に送信するのではなく、後でバッチ処理で送信する処理を作ってみた。 送信するメールを保存するモデルはこんな感じ # -*- coding: utf-8 -*- from datetime import datetime from django.db import models from django.core.mail import send_mail # Create your models here. class SendMail(models.Model): sender = models.CharField("送信元メールアドレス", max_length=255) recipients = models.TextField("送信先メー
AppEngineでGoogleユーザーアカウントを使用せずにセッションを使う方法を探したところ、gaeutilitiesというモジュールを発見した。http://gaeutilities.appspot.com/ このモジュールはセッションだけでなく、appengine用の便利機能が色々入ってるみたい。 使い方は簡単。こちらでダウンロードする。http://github.com/joerussbowman/gaeutilities/downloads ダウンロードして解答したディレクトリから、appengine_utilitiesを自分のプロジェクトにコピー。下記のように使う。 セッションにデータを格納する import appengine_utilities.sessions session = appengine_utilities.sessions.Session() sessio
EvernoteのAPIを使ったWebアプリをappengine上に作ろうとしてる。たまに既存のデータを全部消してフル同期する必要が発生しそうなので、なんとかこれを最小のコストで終らせたい。 ついでに汎用的な一括削除の仕組みができたら再利用できて嬉しいな、と思って、あれこれ考えて試作してみた。 調査したところ、 TaskQueueを使えば並列で処理が行なえて、しかも同時に実行した処理は1回分のCPU時間しか消費しないらしい memcacheのincr、decrを使えばタスクが残っているかどうかが判定できそうdb.deleteやdb.putを使うと、ループでエンティティからputやdeleteを実行するより速いらしいKey.from_pathでキーだけでdb.deleteした方が速いらしいということが分かった。 TaskQueueが要で、これにどうやって削除するエンティティを振り分けるかがポ
Google App Engine 楽しいですね。表題の件、僕のPATHの設定か何かが悪いのかもしれないけど、普通にappengineを配置して cd google_appengine ./dev_appserver.py プロジェクト名 すると下記のようなエラーが表示される。 ERROR 2010-03-01 17:18:14,354 appcfg.py:197] Could not find version file at /usr/lib/pymodules/python2.6/google/../VERSION ERROR 2010-03-01 17:18:14,354 appcfg.py:197] Could not find version file at /usr/lib/pymodules/python2.6/google/../VERSION INFO 2010-03-0
使いまわせそうな方法が見つかったのでメモ。 ユーザー毎にタグを作成できるような機能を作成していて、特定のユーザーのタグを一括で取得しようとする場合、普通にタグ毎にエンティティを作成していると、200件くらいのタグをuserでfilterして取得するだけでも結構時間がかかる。 class Tag(db.Model): """key_name is user_id/tagid""" user = db.ReferenceProperty(User) name = db.StringProperty() ... tag_list = Tag.all().filter("user = ", user).order("name") 色々調べてみたところ、検索に使用しないデータはシリアライズしてzlib圧縮してBlobPropertyに入れておくといいらしいことが分かった。考えてみるとタグはユーザー
Google App Engineで画像を扱いたい場合にPicasaが使えるかどうかを確認したかったので、favicon2png機能を作成してみた。 流れとしては、 ページのURLをリクエストパラメータとして受け取るPNG化したことのあるページならばデータストアからPicasa上の画像URLを取得して返却 未登録のURLならばfaviconのURLをfetchとBeautifulSoupを使って取得favicon画像をfetch images APIのresizeでPNGに変換 変換した画像をPicasaに登録 登録した画像のURLをデータストアに保存 モデルPicasaアルバムのIDを管理するモデルと、FaviconのURLを管理するモデルを作った Picasaアルバムモデルのkey_nameはアルバム名にする。用途に合わせて「favicon」とかつける。 from google.app
新しい開発環境を構築するにあたり、またApacheとmod_pythonで構築するのもアレだな、ということで流行のnginxを試してみた。 だいたいの情報は、 nginxホームhttp://nginx.net/ NginxJahttp://wiki.nginx.org/NginxJa nginx 一人 nginx 勉強会 第一回 nginx で Django を動かしてみるhttp://d.hatena.ne.jp/Voluntas/20071020/1192875482 NGINX + FastCGI + Djangohttp://dev.osso.nl/herman/blog/2009/07/28/nginx-fastcgi-django/ Tips for nginxhttp://labs.unoh.net/2009/08/tips_for_nginx.html あたりを見れば分かる
IPアドレスを増やさずにドメインベースで複数のドメインを運用しつつSSLを使えないかと調べたところ、Apacheだけでは無理だけどリバースプロキシを使えば何とかなりそうだったので、やってみた。 元々 Apache + mod_python + SSL でDjangoアプリを運用していたところに、別のドメインでDjangoアプリを追加する。 [フロント]Pound http://www.apsis.ch/poundポート80と443で待機し、リクエストをポート81に流すここでSSL処理を行なう。 [バック]Apache + mod_pythonポート81で待機ドメインベースで複数ドメインのバーチャルホストを設定 最初はフロントにlighttpdを使おうとしたが、設定が悪いのか、Djangoの問題なのか、HTTPS通信でPOST後にリダイレクトするとHTTP通信に戻ってしまう問題が解決できなか
本サーバのログを見ていたらCPU警告だらけになっていたので、チューニングして効果のあったものを記録していく。 参考にしたページGoogle App Engineを高速化する3つのtipshttp://mattn.kaoriya.net/software/lang/python/20080526182049.htm ディスク<帯域<CPUの順に制限がキツくなるGoogle App EngineのQuota構成から見るコストパフォーマンスの高いシステム構成http://coreblog.org/ats/now-we-are-free-from-qota-hell Google App Engineのmemcacheを試してみたhttp://taichino.com/programming/487 Google App Engineのmemcache APIがやばすぎるhttp://mattn.
他に方法が思いつかなかったので、親ウィンドウ側に関数を用意してそれをThickbox側から呼び出す方法をとった。 iframe版しか考えていないので、ajax版の使い方だとまた別の方法があると思う。 parent.html head> ... script type="text/javascript" src="jquery-1.3.1.min.js">script> link rel="stylesheet" href="thickbox.css" type="text/css" /> script type="text/javascript" src="thickbox-compressed.js">script> script type="text/javascript" src="parent.js">script> ... head> body> ... a href="/pat
日本語が化けて大変苦労したのでメモ。結論として、XML(またはHTML)を解析する前にunicode関数に通しておく、ということで良いのかな?相変わらず文字コード関連はよく分からない。 from urllib import urlopen from lxml import etree html = urlopen("http://b.hatena.ne.jp") charset = html.headers.getparam('charset') html_data = unicode(html.read(),charset) et = etree.fromstring(html_data, parser=etree.HTMLParser()) title_element = et.xpath("./head/title")[0] title = title_element.text.e
マイミクの日記を自分のつぶやきで埋めつくさないために作ってみた。ミニブログなんかのシステムを作成する時に、1記事毎に出力するのではなく、1日分の記事をまとめて1つの記事として出力する。 サンプルが見当らなかったので、思いついた方法で作る。 sample/blog/models.py from django.db import models from django.contrib.auth.models import User from django.utils.translation import ugettext_lazy as _ # Create your models here. class Article(models.Model): user = models.ForeignKey(User) contents = models.TextField(_("Contents"))
django1.0から、FileFieldとImageFieldのupload_to属性に関数を指定できるようになり、ファイルのアップロード先を動的に設定できるようになったようだ。 http://docs.djangoproject.com/en/dev/ref/models/fields/#django.db.models.FileField 関数の第一引数にはモデルオブジェクトが入り、第二引数にはファイル名が入る。 下記のようなモデルを作成することで、ユーザー名のフォルダに分けてファイルをアップロードすることができた。 models.py import os from django.db import models from django.conf import settings from django.contrib.auth.models import User def get_p
これもちょっと必要だったので作成したスクリプト。秀丸やgVimで開けないほど大きいファイルを分割する。 こうやって保存しておけば、一部でも使いまわせるだろう。 split_file.py in_file_name = "verybigfile.log" out_file_name_template = "splitted_%d.log" max_lines = 1000000 split_index = 1 line_index = 1 out_file = open(out_file_name_template % (split_index,), "w") in_file = open(in_file_name) line = in_file.readline() while line: if line_index > max_lines: print "Starting file: %
大した機能ではないが、せっかくスクリプトを作ったので保存しておく。せめて検索フォルダと検索文字列はコマンドオプションとして渡せるようにしておくべきだったか。 pygrep.py import re search_dir = "./検索フォルダ/" search_pattern = "検索文字列" file_name_list = os.listdir(search_dir) for file_name in file_name_list: f = open(os.path.join(search_dir, file_name)) line = f.readline() line_number = 1 while line: m = re.search(search_pattern, line) if m: print "Pattern Found: file:%s, line:%d, da
思いのほか苦労したのでメモ。 CentOSにPython2.5とPIL1.1.6の環境を作成してプログラムを動かしてみたところ、JPEG画像の処理に失敗し、下記のログが表示された。 decoder jpeg not available なんやかんやで下記のライブラリが必要だと分かったのでインストールした。 libjpeg-devel freetype2libjpeg-develはyumで、freetype2はソースからインストールした。 その後、PILを再インストールするのだが、ここの手順を調べるのに時間がかかった。とりあえず、下記の処理を実施すると動いた。 PILインストーラディレクトリのbuildディレクトリを削除python setup.py buildを実行python setup.py installを実行python selftest.pyを実行し、テストが全て通ることを確認
django-registrationhttp://code.google.com/p/django-registration/ django-registrationはユーザー登録や認証関連の処理を一通り行ってくれる便利なdjangoアプリケーションである。設置方法等については、下記のページに分かりやすい説明が記載されている。http://d.hatena.ne.jp/jYoshiori/20070930/1191180980http://takatoshi.g.hatena.ne.jp/nitsuji/20071021/1192953110 このアプリケーションに備わっている、プロファイル作成コールバック機能を使い、ユーザー登録時にこちらが独自に定義したユーザープロファイルオブジェクトを登録する処理を使用したので使用方法を記録しておく。 ここで言うプロファイルとは、djangoのユーザ
前回発見したjQuery Form Pluginを使って実際にファイルをアップロードするサンプルを作った。http://d.hatena.ne.jp/piro_suke/20080615/1213498024 ファイルをアップロードする場合のみ、iframeが使用される関係でサーバ側から返却するデータをtextareaタグで囲まないといけないことに気づかず、苦労した。 とりあえずこのサンプルがあればまた思い出して応用できるだろう。 アップロードフォームHTML ... script type="text/javascript" src="/static/javascripts/jquery/jquery-1.2.6.min.js">script> script type="text/javascript" src="/static/javascripts/jquery/jquery.for
次のページ
このページを最初にブックマークしてみませんか?
『piro-suke.hatenablog.com』の新着エントリーを見る
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く