Archive | 12月 2008

usersクラス

このクラスを使うとドメインに対するユーザー認証処理が行えるようになります。

デフォルトでは google アカウントに対しての処理になっています。

gmailやiGoogleなどを利用する際にgmail.comのメールアドレスとパスワードを入力するあれです。

from google.appengine.api import users

この文がライブラリの読み込みになります。

クラスメソッド
nickname() ニックネームを返す
email() メールアドレスを返す
クラス関数
create_login_url(dest_url) ログインURLを生成する
create_logout_url(dest_url) ログアウトURLを生成する
get_current_user() 現在のユーザー情報を返す
is_current_user_admin() 管理者アカウントでログインしているかを返す
広告

ディレクトリ指定

今回 cssファイルを置くためのディレクトリを作りました。

このディレクトリは固定のディレクトリとして app.yaml ファイルに登録します。

application: main
version: 1
runtime: python
api_version: 1
handlers:
- url: /css
static_dir: css
- url: /img
static_dir: img
- url: /.*
script: main.py

の最初の部分です。

最後の /.* で指定してある部分よりもあとに書いてしまうと処理されなくなるので注意してください。

同じく img ディレクトリも画像ファイルを置く目的で作ってあるので、cssのあとに書いてあります。

<img src="/img/image.gif">

のように画像を読み込むタグもimgディレクトリにあるファイルを読む処理になります。

テンプレートエンジン

GAEには Django というのが入ってます。これを使えば実際の表示と処理を分割することができます。

テンプレート側にも条件判断や繰り返しなどの簡単な制御を入れることができますので、変数の内容によって表示する、しないの切り替えなどもできます。

{% if logged %}
Login: {{ name }}<hr />
<a href="{{ url }}">Logout</a>
{% else %}
Not logged in.<hr />
<a href="{{ url }}">Login</a>
{% endif %}

{% %} で囲まれた文は Django の命令文

{{ }} で囲まれた文は変数を展開して表示します

{% if logged %} は条件判断文で、logged という変数が1のときとそれ以外のときで処理を変えています。

ここで扱っている変数は、 logged / name / url です。

これらの変数はプログラムの以下の場所で設定しています。

template_values = {
'url': url,
'name': name,
'logged': logged
}
path = os.path.join(os.path.dirname(__file__), 'main.html')
self.response.out.write(template.render(path, template_values))

まず、配列 template_values に

‘テンプレート内のラベル’: 変数名

として登録します。

その後、テンプレートのレンダリングの際に第1引数にテンプレートへのパス、第2引数に変数の配列リストを指定します。template.render(path,

template_values) の部分です。

テンプレートとusersクラスと固定ディレクトリ

何度も消したり公開したり、すいませんでした。

ソース中のコメントが文字化けしたのを直そうとして直らなかったのでコメントなしで公開しますorz

もう一度はてな記法のヘルプを読み返してみます。失礼しました。

以下のファイルは、demos\log へ。

app.yaml

application: main
version: 1
runtime: python
api_version: 1
handlers:
- url: /css
static_dir: css
- url: /img
static_dir: img
- url: /.*
script: main.py

main.py

import wsgiref.handlers
import os
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
class RootPage(webapp.RequestHandler):
def get(self):
if users.get_current_user():
url = users.create_logout_url(self.request.uri)
logged = 1;
name = users.get_current_user().nickname()
else:
url = users.create_login_url(self.request.uri)
logged = 0;
name = 'not logged in'
template_values = {
'url': url,
'name': name,
'logged': logged
}
path = os.path.join(os.path.dirname(__file__), 'main.html')
self.response.out.write(template.render(path, template_values))
def main():
application = webapp.WSGIApplication([
('/', RootPage)
], debug=True)
wsgiref.handlers.CGIHandler().run(application)
if __name__ == "__main__":
main()

main.html

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja-JP" lang="ja-JP">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="/css/main.css" />
</head>
<body>
{% if logged %}
Login: {{ name }}<hr />
<a href="{{ url }}">Logout</a>
{% else %}
Not logged in.<hr />
<a href="{{ url }}">Login</a>
{% endif %}
</body>
</html>

demos\log の中に css と img というフォルダを作って、 css フォルダの中に以下のファイルを。

main.css

body {
background-color: #888888;
color: #ffffff;
}

img フォルダはまだ何も入れません。

そして、

dev_appserver.py demos\log

として、サーバーを起動してアクセスしてみてください。

webappフレームワーク

それだけじゃつまんないので、もう少し進んでwebappフレームワークの実験。

app.yaml

application: main
version: 1
runtime: python
api_version: 1
handlers:
- url: /.*
script: main.py

main.py

import wsgiref.handlers
from google.appengine.ext import webapp
class RootPage(webapp.RequestHandler):
def get(self):
self.response.out.write('''
			Now->RootPage<br />
			<a href="./page1">Page1</a><br />
			<a href="./page2">Page2</a><br />
		''')
class Page1(webapp.RequestHandler):
def get(self):
self.response.out.write('''
			<a href="./">RootPage</a><br />
			Now->Page1<br />
			<a href="./page2">Page2</a><br />
		''')
class Page2(webapp.RequestHandler):
def get(self):
self.response.out.write('''
			<a href="./">RootPage</a><br />
			<a href="./page1">Page1</a><br />
			Now->Page2<br />
		''')
def main():
application = webapp.WSGIApplication([
('/', RootPage),
('/page1', Page1),
('/page2', Page2)
], debug=True)
wsgiref.handlers.CGIHandler().run(application)
if __name__ == "__main__":
main()

実行すると、画面にリンクが3つ表示されます。

それぞれのリンクをクリックすると画面が切り替わります。

webapp.WSGIApplicationのパラメータとしてパス名と関数名を渡すとその動作をしてくれるのでその辺は他の言語より楽だなー。

ただ、app.yamlの書式をもうちょっと調べれば、ファイルの分割も含めてわかりやすくなるはず。

その3 – appserver/webappフレームワーク

python環境で実行するのも飽きてきたので、SDKにあるデバッグ用サーバーを使って実験してみました。

コマンドプロンプトから

dev_appserver.py [オプション] <アプリケーションのルートフォルダ名>

と入力すれば、サーバーが起動します。

アプリケーションのルートフォルダには正しい書式の app.yaml / app.yml がないとダメ

デフォルトで起動した場合は

http://localhost:8080/

とブラウザからアクセスすれば見ることができます。

オプションの一覧

–help, -h ヘルプの表示 (デフォルトなし)
–debug, -d デバッグログを使う false
–clear_datastore, -c 起動時にデータストアに保存されているデータをクリア false
–address=ADDRESS, -a ADDRESS サーバーに割り当てるアドレスの指定 localhost
–port=PORT, -p PORT サーバーのポートを指定 8080
–datastore_path=PATH データストアのstub ファイルを保存するパスの指定 SDKのルートディレクトリ
–history_path=PATH データストアの履歴を保存するパスの指定 SDKのルートディレクトリ
–require_indexes index.yamlに定義されていないクエリを禁止する false
–smtp_host=HOSTNAME テストメールを送信するSMTPアドレス。登録されていない場合はSMTPでのメール送信はできない localhost
–smtp_port=PORT SMTPポート指定 25
–smtp_user=USER SMTP接続ユーザー名。この項目が空でない場合SMTP認証をします ”(文字なし)
–smtp_password=PASSWORD SMTP接続パスワード ”(文字なし)
–enable_sendmail SMTPの設定が設定されていなくてもメール送信をするか false
–show_mail_body メール本文をログに記録するか false
–auth_domain このアプリケーションの実行時、認証につかうドメイン gmail.com
–debug_imports モジュールインポートの際に検索したパスやエラーなどをデバッグログに出力するかどうか false

サーバーを使ってメッセージ表示を試しに動かしてみたら、ちゃんと動いたので、ここまではよし。

携帯サイトの本

http://www.ideaxidea.com/archives/2008/12/post_979.html

の読者プレゼントというのが気になって記事を見ていたんですが、

http://dspt.blog59.fc2.com/blog-entry-47.html

を読んでみて、おもしろそうだなと思ったのであとで立ち読みしてみようと思います。

必要そうなら買うということで。

こういう本って、一度見逃してそのまま手に入らないとか結構あったし、今は必要なくてもあとで持っててよかったなんてことになることが多いです。

%d人のブロガーが「いいね」をつけました。