利用者属性の登録
次に、OpenIDで認証した人がニックネームと時差を登録できるようにする。
モデル
- model/__init__.py
import boto import jsonpickle class UserProperty(object): def __init__(self, openid = None, nickname = None, time_diff = 0): self.openid = openid self.nickname = nickname self.time_diff = time_diff class UserPropertySDB(object): def __init__(self): sdb = boto.connect_sdb() self.domain = sdb.create_domain('UserProperty') def get_item(self, key): item = self.domain.get_item(key) if item: item = jsonpickle.decode(item['userproperty']) return item def put_item(self, up): item = self.domain.get_item(up.openid) if item is None: item = self.domain.new_item(up.openid) item['userproperty'] = jsonpickle.encode(up) item.save()
フォーム準備
- これはPylonsでは定石
lib/helpers.py
from routes import url_for from formbuild.helpers import field from formbuild import start_with_layout as form_start, end_with_layout as form_end from webhelpers.html.tags import *
- フォーム作成に必要なモジュールを取り込んでおく。
clock.py
import logging from pylons import request, response, session, tmpl_context as c from pylons.controllers.util import abort, redirect_to from myclock.lib.base import BaseController, render import datetime from authkit.authorize.pylons_adaptors import authorize from authkit.permissions import RemoteUser from routes.util import url_for from myclock.lib import helpers as h log = logging.getLogger(__name__) from myclock.model import UserProperty, UserPropertySDB import formencode from pylons.decorators.rest import restrict from pylons.decorators import validate class TimeDiffForm(formencode.Schema): allow_extra_fields = True filter_extra_fields = True nickname = formencode.validators.String(not_empty = True) time_diff = formencode.validators.Int(not_empty = True) class ClockController(BaseController): def __init__(self): BaseController.__init__(self) self.ups = UserPropertySDB() @authorize(RemoteUser()) def now(self): item = self.ups.get_item(request.environ['REMOTE_USER']) if item: name = item.nickname time_diff = item.time_diff else: name = request.environ['REMOTE_USER'] time_diff = 0 time = datetime.datetime.now() time = str(time + datetime.timedelta(0, 0, 0, 0, 0, time_diff)) c.content = "Welcome, %s. Current time is %s (diff is %s)" % (name, time, str(time_diff)) return render('/derived/clock/now.html') @authorize(RemoteUser()) def customize(self): return render('/derived/clock/customize.html') @restrict('POST') @validate(schema = TimeDiffForm(), form = 'time_diff') @authorize(RemoteUser()) def save(self): up = UserProperty(request.environ['REMOTE_USER'], self.form_result['nickname'], int(self.form_result['time_diff'])) self.ups.put_item(up) redirect_to('now') def signout(self): redirect_to('now')
- TimeDiffForm...フォーム内容チェックのためのデコレータ。
- nicknameとtime_diffの型チェックおよび必須チェック
- ClockController
- __init__で、SimpleDBとの接続を確立→sqlalchemyみたいにSession()に取り込むのが理想。
- now()ではSimpleDBから属性を取り込み、表示。データがない場合はOpenIDとゼロがそれぞれ入る。
- customize()は登録フォーム表示
- save()はフォームのサブミット先。
templates/derived/clock/now.html
<%inherit file="/base/index.html"/> ${c.content} <br/> You can <a href="${h.url_for(action = 'customize')}">customize</a>. <br/> <a href="${h.url_for(action = 'signout')}">Signout</a>
- 時差計算をした時刻を表示するように改造。
- 属性変更画面へのリンクを追加。
templates/derived/clock/customize.html
<%inherit file="/base/index.html"/> <%namespace file = "fields.html" name = "fields" import = "*"/> ${h.form_start(h.url_for(action = 'save'), method = 'post')} ${fields.body()} ${h.field(field = h.submit(value = "Save", name = "submit"))} ${h.form_end()}
- 属性登録画面。フォームの項目は次のファイル。
templates/derived/clock/fields.html
${h.field( "Nickame", h.text(name = 'nickname'), required = False, )} ${h.field( "Time Diff", h.text(name = 'time_diff'), required = False, )}