2011年4月22日金曜日

CRUD

CRUDが高級すぎてなんだか良く分からなかった。
最近、すこしわかってきた。要するにSQLFORMを1functionで済ませようという発想です。
データ一覧のテーブルのTHEADなどは呼ぶときに、messageや戻りアドレスはsettingsです。
その辺りはhttp://www.web2py.com/book/default/chapter/07#CRUDに詳しいのですが、実際に使うと驚くほどに簡単。


一番に理解を超えていたのが

def data(): return dict(form=crud())

とかくと、以下のURLがexposeされるという説明でした。
http://.../[app]/[controller]/data/tables
http://.../[app]/[controller]/data/create/[tablename]
http://.../[app]/[controller]/data/read/[tablename]/[id]
http://.../[app]/[controller]/data/update/[tablename]/[id]
http://.../[app]/[controller]/data/delete/[tablename]/[id]
http://.../[app]/[controller]/data/select/[tablename]
http://.../[app]/[controller]/data/search/[tablename]

これでViewはまったくいじらずに機能が実現します。

djangoにも同じようなのがありますが、結構に面倒くさかった。

そこで自分のアプリにも使ってみた。アドミだけが使うDBのメンテナンスだが、マスタースケジュールを作成、リスト、更新する

def list_schedule():
    db.schedule.id.represent=lambda id:  A('edit:',id,_href=URL('update_schedule',args=(id)))
    return dict(records=crud.select(db.schedule, db.schedule.id>0)) 
このfunctionはscheduleテーブルから全レコードを表示しています。表示されたIDの部分にhrefが隠れていて次の関数update_scheduleを呼びます。
 def update_schedule():
    return dict(form=crud.update(db.schedule, request.args(0),next=URL('list_schedule'))) 
scheduleを更新するフォームを表示して、更新したらlist_scheduleに戻ります。
 def create_schedule():
    form = crud.create(db.schedule, next=URL('create_schedule'),
           message=T("record created"))
    db.schedule.id.represent=lambda id:  A('edit:',id,_href=URL('update_schedule',args=(id)))
    return dict(form=form, records=crud.select(db.schedule, db.schedule.id>0,))
全てのscheduleと新規作成のフォームを表示しています。
ようするにappadminと同じなんですが、柔軟性と開発スピードではappadminとSQLFORMの間にあるということでしょうか。
htmlは何も書かなくて大丈夫です。

2011年4月9日土曜日

plugin_wiki SQLFORM カストマイズ crud.createで実行

plugin_wikiは強力です。
web2pyはphpと同じようにhtmlのなかにpythonコードを埋め込むことができます。
これはdjangoではできなかったことです。だからとんでもない(私にとっては)離れ業ができます。
SQLFORMもweb2pyの強力な武器ですが、この2つをつかって大方のデータベースがらみのページを作れます。
それをひとつ紹介します。

データベースの定義 db.py

db.define_table('plan',
    Field('hisname','string'),
    Field('date_start','date'),
    Field('date_end','date'),
    Field('mystyle','string',label ='私のスタイル'),
    Field('hisstyle','string',label='相手のスタイル'),
    Field('issue','text',label='起こりそうなコミュニケーション上の問題、上手にしたいこと'),
    Field('situation','text',label='どんな場面で対応性を発揮しますか。'),
    Field('action','text',label='その場面で対応性を発揮するにはどのように振る舞いますか'),
)
plugin_wikiのページ


``
{{#form = SQLFORM(db.plan)}}これは駄目です。
{{form = crud.create(db.plan)}}
        <h1>対応性向上計画</h1>
        {{=form.custom.begin}}
<table width=550>
    <tr>
        <td width=350>   計画の開始日と終了日</td><td width=200>どなたに対しての計画ですか</td>
        </tr>
    <tr>
        <td>{{=form.custom.widget.date_start}}{{=form.custom.widget.date_end}} </td>
        <td> {{=form.custom.widget.hisname}}</td>
    </tr>
</table><br/><br/>
<div>私のスタイル  {{=form.custom.widget.mystyle}}</div>
<div>この人のスタイル{{=form.custom.widget.hisstyle}}</div><br/>
考えられるコミュニケーション上の問題あるいは上達したいことはなにですか。<div class='plan'>  {{=form.custom.widget.issue}}</div>
どんな場面で対応性を発揮しますか。<div class='plan'>  {{=form.custom.widget.situation}}</div>
どんな言動をとりますか。<div class='plan'>  {{=form.custom.widget.action}}</div>
<p>{{=form.custom.submit}}</p>
{{=form.custom.end}}
``:template

画面 :テキストエリアが不細工ですが、これはcssで直すつもり。このサイトはsoialstyleclub.appspot.comでご覧になれます。因にこれはGoogle Application Enginesです。

2011年4月8日金曜日

plugin_wiki メニュー日本語

plugin_wikiは文字通り、リモートサイトでそのままページを編集できるすぐれものです。どこかですでに紹介しましたが、vimeo,youtube,slideshareなどの動画を表示できます。
pythonコードをそのまま組み込めます。なによりviewテンプレートがリモートで作成できます。
順調に開発を進めて来たのですが、メニューで躓きました。
meta_menuを使えば、menu.pyを上書きしてくれます。だからページを追加してもランチャー(私はGAEで開発しています)でアップロードしなくてもページ本体とそれを参照するメニューも更新できます。
問題はメニューのアイテムで日本語を表示するとアイテムとして認識してくれないのです。
たとえば
ホーム page:index
   スタイルの説明 page:explain

本来はメニューバーに「ホーム」が表示されて、そのサブメニューに「スタイルの説明」がぶらさがる筈ですがすべて無視されます。
そこでトリックを使いました。

.ホーム page:index

   .スタイルの説明 page:explain

という具合です。半角のピリオッドを冒頭に置くこととホームの下で1行開けることです。

本体にはもちろんお願いしました。

2011年4月5日火曜日

web2pyのスライドショー

ソーシャル・スタイル・クラブというサイトを開発していますが、そのほとんどをplugin_wikiで開発しました。
マニュアルにはありませんが、:templateというwidgetがあります。
このwidgetを使うとviewでできることは何でもできます。

このサイトはスタイルの学習サイトですから、コースの導入部でスライドショーをどうしても使いたかったのです。
Macのkeynoteでプレゼンテーションを作って、slideshare.comにアップロード。embedのスクリプトが表示されますからこれをtemplateタグの中にペーストして完成です。
このページにもペーストすると、以下のようになります。
因にslideshareのサイトは下のSlide1をクリックしてください。
Slide1
View more presentations from yutakakawate

2011年4月4日月曜日

Djangoグループを超えた


メッセージの数がDjangoユーザーグループを超えたそうです。
オリジナルのメッセージを転記します。


Massimo Di Pierro  
プロフィールを表示  
 詳細オプション 4月4日, 午前8:53
I mined some data from:
http://groups.google.com/group/web2py/about
http://groups.google.com/group/django-users/about
This web2py users group had 56,283 messages posted since 1/1/2009. The
Django-users list had 51,119 over the same time period.
Here is a plot showing the messages/month in the two users groups
http://i.imgur.com/GHcce.png
As you can see the surpass is significative and consistent since Oct
2009.
Now we know why some people are upset about web2py ;-)
Congratulations to all of you! 
Massimo

2011年3月9日水曜日

web2py, plugin_wikiのeditor権限

Plugin_wikiははとても便利
サイトのページをサーバー上で直接に編集できる。
通常のページだけでなくメニューやフッターも作れます。
Python codeや{{...}}タグも使えます。ページは様々なWidgetがあってYouTubeやGoogleのchartやmapを埋め込めます。これはvimeoにも載っているのですが。What is going on with web2py?
その使い方はOnline bookに詳しいのですが、ログインしてもPageがなかなか現れませんでした。下の図のPagesというタブです。

確かこのブログで紹介しましたが、editorというgroupのメンバーがログインすると現れます。だがこれは結構に面倒です。よくBookを読んだらmail.setting.senderとログインしたユーザーのメールアドレスが同じならeditorの権限を得ることが書いてあります。
それを記録しておきます。


from gluon.tools import *
mail = Mail()                                  # mailer
auth = Auth(globals(),db)                      # authentication/authorization
crud = Crud(globals(),db)                      # for CRUD helpers using auth
service = Service(globals())                   # for json, xml, jsonrpc, xmlrpc, amfrpc
plugins = PluginManager()

mail.settings.server = 'gae'  # your SMTP server
mail.settings.sender = 'xxxxxxxx@gmail.com'         # your email
mail.settings.login = 'xxxxxxxx@gmail.com:<password>'      # your credentials or None
if auth.user:
    plugins.wiki.editor = auth.user.email == mail.settings.sender

私は一人でページを作っているのでこれで十分です。

2011年3月3日木曜日

web2py , openID,google,Facebookでログイン

非常に強力なwebのフレームです。特にGoogle App Enginesへdeployするには優れています。
Djangoからweb2pyにスイッチしたのはそのためです。

そのusers groupは非常に活発で開発者(Massimo Di Pierro)が直接に回答していること、メンバーに開発者の学生が多いことなどで非常に役に立っています。オンラインドキュメントはよく編集されていて優れています。ドキュメントで分からないこと全部このユーザーグループで検索すればほぼことは足ります。質問しなくても検索すれば大方の問題は解決します。残念ながら英語しかありませんが。

掲題のログインの問題にもどって。

web2pyは完璧な認証システムが備わっています。
さらにjanrain(user management platform for the social web)とのインタフェースがクラス(RPXaccount)として用意されているのでこれをネイティブなログインフォームに代入すればopenID,Google,openIDなどのアカウントでログインできます(janrainは商用サービスですがbasicはfreeです)。
janrainのEngageというプロダクトに好みの名前のドメインを登録するとapi_keyがもらえますから、これをRPXaccountのパラメータにして初期化してネイティブなログインフォームに代入するだけです。

 auth.settings.actions_disabled=['register','change_password','request_reset_password']
auth.settings.login_form = RPXAccount(request, api_key='もらったapi_key',domain='ドメイン',
    url = "http://localhost:8000/%s/default/user/login" % request.application)
最後の行はweb2pyのログインURLです。

これでGoogleやFacebookのアカウントをもった訪問者はログインできます。同時に訪問者の名前やメールアドレスがこちらのサイトのuserテーブルに保存されます。

しかしこのままだと今まで自分のサイトに登録した訪問者がログインできません。
そのためにExtendedLoginFormというクラスが用意されています。
argsにトークンを入れてログインフォームをスイッチできるようにしたものです。
ところがこれがduplicate keywordsになってうまく動きませんでした。
この問題はweb2pyのユーザーグルプに投稿されて解決策がhow to use ExtendedLoginForm ?に掲載されていました。
詳細は省きますが、その結果は次の画面のようになります。
web2pyには幾つかのGoogleなどのログインメソッドが用意されています。まだこれは試していません。janrainは単一のゲートウエイになっているので便利です。








画面の上半分はよそのアカウントでログイン、下半分の会員登録は自分のサイトに登録します。あるいはログインします。

Wweb2py、GAEで公開まで

私は机上のMacで研修のためのアプリケーションを開発しています。
そこでの経験をまとめておくと良いのではとおもって投稿します。 



localhost:8000 => localhost:8080 => Google App Enginesと言う具合に段階を上げています。
ポートの8000はweb2py.py、8080はGAEのシミュレータでgoogle提供のSDKです。ここで開発デバッグ、試験してGoogle App Enginesで公開にアップロードして公開します。


web2py.pyでは完全なデバッグ環境があってDjangoより格段に進歩した環境が提供されます。
トレースバックのコールシーケンスの各段階の変数のスナップショットは当然ですが、adminの画面からviewやcontollerを直接呼び出せま
す。ですから分からないことがあると、k=kという文を入れてトラップさせて自分のプログラムだけでなくweb2pyの中のうごきをトレースバックして
います(本当はもっとスマートな方法があるかもしれませんが)。
非常に便利ですが、この段階では私はデータベースにsqliteを使っていますからアプリケーション間でデータの共有ができません。ログインしても別の
アプリケーションではuserテーブルの値が別々のデータベースになるので、認証関係の設定の確認ができません。これが難点です。しかしsqliteは
SQlite Databaseブラウザーがあるのでこれで個別のデータの確認を簡単にとれます。
データベースはシミュレータで共有できるようになります。アプリケーションで共有するテーブルをそれぞれで定義しておけばOKです。userテーブルも
共有できますから、認証の確認は確実です。
データベースのブラウジングはhttp://localhost:8080/_ah/adminで作成、閲覧して編集削除することができます。
registrationではメールによるverificationをしたいのですが、私のMacのサーバーからメールを発信する方法を知りません(ど
なたかご存知でしたら教えてください)。
いまはauth_userを/_ah/adminで開いて該当するエントリのregistration keyを取り出して、http://
localhost:8080/members/default/user/verify_email/1b0cd09d-1e4c-407a-
ae8a-536ecedd80c5とやっています。
シミュレータで一通りのデータベースアクセスをします。ここでindexテーブルを全部作っておかないとGAEが動作しません。
シミュレータで試験するのはデータが共有されておこる不都合をチェックするくらいでしょうか。
最後にGAEです。
実はGoogleAppEnginesはバージョンがあってDefaultのバージョンはhttps:xxx.appspot.comで公開されます が、それ以外のバージョンは頭にバージョン番号をつけてアクセスします。https:2.xxx.appspot.comという具合です。ここでも公開までのステップが用意されています。まぁアルファバージョン、ベータバージョンということでしょう。

バージョンはapp.yamlで指定します。appspot.comでログインすると自分のGAEのアプリケーションの空間に入れます。アプリケーションのリストがありますから、該当のアプリケーションを選択してそこのversionsでデフォールトのバージョンを設定できます。

デフォールトのアプリケーションとは、私のこのアプリケーションではmaselstyle.appspot.comで呼び出されるアプリケーションです。以前のバージョンや試験中のバージョンは、それがバージョン4とすると、4.masel-style.appspot.comです。
デフォールトは利用者がアクセスしますから、デフォールト以外で試験して、OKならば、そのバージョンをデフォールトにします。これはプログラムコード

プログラムコードのバージョンとは別にデータベースの値をnamespaceでコントロールできます。
アプリケーションのdb.pyで指定します。
if request.env.web2py_runtime_gae:            # if running on Google
App Engine
    db = DAL('gae://mynamespace')             # connect to Google BigTable
mynamespaceはその名のとおり名前空間ですからデータベースの構造は同じでも違う値を持つことになります。

2011年2月12日土曜日

Google App Engine、アプリケーションでデータベース共有

Web2pyでは、GAEに向けた開発では3つのモードがあります。
  1. GAEの本番、いわゆるProduction
  2. GAEのサンドボックス
  3. web2pyの実行
web2pyの開発環境は至れり尽くせりでViewやControllerを直接実行したり、編集したり、トラップしたときのトレースも不自由なくできます。
わたしはデータベースは面倒なのでsqliteを使っています。SQLite Database Bowser(http://sqlitebrowser.sourceforge.net)などはほとんど必要としません。
全部 この開発環境で開発からデバッグができます。
しかし問題がない訳ではありません。

それは
複数のアプリケーションの間のシェアです。マニュアルにはいろいろ書いてありますが、(http://www.web2py.com/book/default/chapter/04?search=cooperation#Cooperation)私にとっては、一向に要領を得ません。アプリケーションの間でセッションを共有しようとしたいのですが、結局はデータベースが共有できればよいのです。

SQLiteを使うとファイルシステムにストレージができます。web2pyではアプリケーションの下のディレクトリ、databasesです。
シンボリックリンクを使ってシェアしようとしたのですが、うまく行きません。

ところがこの問題はGAEのサンドボックスではないのでした。
GAEのサンドボックス、dev_appserver.pyはGoogleのデータベース、Big Tableをシミュレートしてくれます。
こちらはファイルシステムが使えません。アプリケーションのdb.pyに次のようなラインがあります。ここでmynamespaceがデータベースの名前空間を指定しているようです。
あるアプリケーションで定義したテーブルを別のアプリケーションのdb.pyで定義しておいて、その名前空間が同じならば、そのテーブルを共有できます。

if request.env.web2py_runtime_gae:            # if running on Google App Engine
    db = DAL('gae://mynamespace')             # connect to Google BigTable
    session.connect(request, response, db=db, masterapp=None)
 # and store sessions and tickets there
    ### or use the following lines to store sessions in Memcache
    # from gluon.contrib.memdb import MEMDB
    # from google.appengine.api.memcache import Client
    # session.connect(request, response, db = MEMDB(Client()))
else:                                         # else use a normal relational database
    db = DAL('sqlite://storage.sqlite')       # if not, use SQLite or other DB

データベースを覗くには、このURLでOKです。
 http://localhost:8080/_ah/admin

要するにまとめると、
web2py ---> dev_appserver.py ---> appcfg.pyでアップロードすればよいということでした。

もうひとつ便利なこと。
web2pyはlocalhost:8000でリッスン、サンドボックスは8080でリッスンします。だからブラウザの上で8000を8080とするだけで同じファンクションを2つの環境で試験できます。これは便利でした。


2011年1月28日金曜日

GAEでソーシャル・スタイル、web2pyで開発

アプリケーションをGAEで稼働させました。
URLは
https://masel-style.appspot.com

日本語になり切らない部分(中国語が残っている)もありますが、試しに訪問してみてください。
実はDjangoのregistrationが私にとっては、ひどくややこしくて苦労したのですが、web2pyではいとも簡単にできました。パスワード忘れや会員登録のメールアドレスの実在確認とか結構に面倒くさかったのが、すんなりでした。

アプリケーションはソーシャル・スタイルの学習をWebでやってしまおうという実験室です。
まだ無料ですから、今のうちに。

スタイル調査のサンプルの出力です。

web2py日本語

問題:login, password, emailなどのweb2pyで表示する基本的なフレーズを日本語にしたい。

内容:
基本的にTに渡された文字列は翻訳の対象になって、
各国語の利用ができるようにLanguageファイルが用意されている。
開発コンソールの「language」に各国語がリストされている。残念ながら日本語、ja.pyがない。ja.pyファイルはオリジナル文字列(Tで囲まれた文字列)と翻訳が対になったファイルである。
解決策:
そこでファイルja.pyを作成して、Languagesの下にある「update all languages」をクリックすれば、すべてのTで囲まれた文字列が出てくる想定であった。


想定違いの問題:
、Loginとかregisterのオリジナル文字列がこのファイルに現れない。どういう事の次第か、開発したアプリケーションのTの文字列が出現する。
たとえばコントローラーのdefault/indexで最後に、
return dict(message=T('ソーシャル・スタイル・クラブにようこそ'))
とやるとTの括弧内が言語ファイルに出てくる。ところがweb2pyのパッケージのAuthenticationにある筈のLogin,registerが出ないのである。
解決策:
中国語の言語ファイルを見るとloginなどが中国語になっている。
そこでこのファイルをja.pyに複写して、これを日本語に変換してOKになりました。

この投稿は
http://www.vimeo.com/7520812
が参考になりました。

このビデオのなかのdb.pyの次の2行も気になります。

2011年1月25日火曜日

Deploy 再び

開発中のシステムはソーシャルスタイルの診断システムをスタイルの学習システムです。
スタイル診断までをアカウントの登録、ログイン、質問紙の回答とかの一通りのアプリケーションを開発して、web2pyの開発環境で試験、コマンドライン、python2.5 web2py.pyでサーバーをスタートして滞りなく来ました。
そこでGAEにアップロード、deployしたのですが、internal errorの頻発でticketも閲覧できない。Googleのコンソールからデータベースのチケットを見ても何のことやら皆目分からない。
そこで何処かに書いてあったのはindex.yamlのこと。このファイルはこのアプリケーションが実行したデータベースアクセスを記録して、deployと同時にGAEのデータベースにインデックスを作成するということ。
探したができていない。

inde.yamlはdev_appserverを走らせないと作らない。dev_appserverはGAEの実行環境のサンドボックス(sandbox)であり、データベースをファイルシステムでシミュレートする。

ようするにweb2pyでサーバーを走らせたときはsqliteでデータベースを走らせる。dev_appserverはGAEのデータストレージを仮装してくれるというわけ。

dev_appserverはデバグ用のコンソールがあって
localhost:8080/_ah_adminで開きました。

dev_appserverで、実行してインデックスを作ったら

appcfg.py update_indexes web2py

でインデックスだけアップロードしてくれます。

役にたったURLは
開発については
http://code.google.com/intl/ja/appengine/docs/python/tools/devserver.html

アップロードと管理については
http://code.google.com/intl/ja/appengine/docs/python/tools/uploadinganapp.html
です。


結論
web2py.pyで開発して試験しても、dev_appserverで一通りのデータベースアクセスをしないとGAEでは動かないということ。

2011年1月2日日曜日

Google App Engine web2py アプリケーション

web2pyはアプリケーションをGoogle App Engine で動かせるように仕掛けが用意されているがなかなかうまく行かなかったのだが、Version 1.91.5 (2010-12-28 22:12:09)で簡単に動かせたのでログしておきます。私はマックで実行しましたが、Windowsもソースで実行すれば問題ないのではと推測します。


dev_appengine.pyやappcfg.pyを直接にいじる必要がなくなりました。


まず、環境を作ります。
http://wiki.web2py.com/Deploying_web2py_on_Google_App_Engine_GAE_からの引用です。

  1. http://code.google.com/appengine/downloads.htmlからpythonのSDK(Google App Engine SDK for Python)をダウンロードして/projectに解凍します。
  2. http://www.web2py.com/examples/static/web2py_src.zipからweb2pyのソース版をダウンロードして、/web2py に解凍します。
  3. ディレクトリは /project/google_engine と /project/web2py になります。web2pyの下にはpythonのソースプログラムがずらりと並びます。このなかにweb2py.pyがあります(windows版やMac版とはここが違います)。
  4. ディレクトリをweb2pyに移動して python2.5 web2py.py します。わたしはマックを使っているので、こんな具合になりました。


ローカルなサーバーが起動して、次の画面が表示されますから、Choose Passwordに適当な管理者パスワードを設定します。このパスワードはサーバーが起動するたびに要求されます。

start serverボタンをクリックするとブラウザーにweb2pyのローカルなホームページが表示されます。
(default.py をすこしいじったのでメッセージはよけいな文字が出ています。)
Readmeの4行目click here for the administrative interfaceをクリックします。
先ほどの管理者パスワードの要求に応えると管理者画面が表示されます。
この画面でアプリケーションの開発をします。
画面の左下にDeploy on Google App Engineがあります。このdeployボタンをクリックします。
appcfg.pyのパスとdeployするアプリケーションを設定して、あとはGAE Emailと GAE Passwordを入力します。
このメールアドレスとパスワードをなんど入れてもinvalid mail addressになっていたのですが、なんとこの二つのフィールドにメールアドレスを入れると正しくアップロードできます。これがこのブログの味噌です。今のバージョンでたまたまなのでいずれ正しいパスワードが必要になるのかもしれません。
web2pyのユーザーグループで発見したものです。Deploying application on GAE using the deploy buttonでユーザーグループを検索してください。

それからapp.yamlを更新するのを忘れないようにしてください。
データベースがらみの試験は別の機会に。