‘GoogleAppEngene’ タグのついている投稿

DAYS 12 AuthSub API

2009年11月4日 水曜日

[ GAE Google App Engine ][ Phthon ][ Google Bigtable ][ AuthSub API ]
GoogleデータサービスAuthSub API利用サンプルアプリ
GAEから利用できるGoogleデータサービスを使ってみた。
本来であれば、アプリケーションに絡めて連動するような形にしたかったが、
連動のさせ方がよくわからず、とりあえず、 「 AuthSub API 」を使って
認証をし、各Googleデータサービスのデータ一覧をとってくるというアプリを作成した。
何度も繰り返すが、本来であれば、協調型プロジェクトタスク管理ツール「キャッチ&リリース(ベータ版)」

http://ctchandrls.appspot.com/の締切日をGoogleカレンダーに連動させたかったのだが、

どうにも動かせない。
できたのは、一覧をとってくることぐらいだったのだ。
Google Data サービスの使用」オンラインマニュアルを参考にしたが、
最終的には、自分のやり方になってしまったように思う。
もしかしたら、これが原因で、「書き込み・更新・削除」の処理ができないのかもしれない。
オンラインマニュアルでは、以下のAPIが提供されていると書かれているが、
Google Data Python モジュールのバージョンがあがっているらしく、
ダウンロードサイトでは他のAPIについても書かれている。
ただ、GAEで利用できるものとは違うのかもしれない。
* 認証
* Google Base
* カレンダー
* 連絡先
* ドキュメント
* Picasa ウェブ アルバム
* スプレッドシート
* YouTube
その中で、私の作ったサンプルアプリでは、
5つのサービスの一覧をとってこれるようにした。
*GoogoleDocs
*GoogleCalender
*Picasa Web アルバム
*YouTube
*GoogleSpreadSheets
利用する前に気をつける点
・いうまでもないが、各サービスの利用を開始していなければ、アクセスはできない。
・YouTubeのみ、「マイ動画」一覧ではなく、「再生回数の多い動画」一覧をとってきている。
なぜならば、「マイ動画」一覧のデータにアクセスするには、Developer Registrationが必要で、私は登録していないからである。
処理のプロセスとしては、2ステップある。
最初のページを表示する際に、
トークンをリクエストするリンクを作成する。
リンクをクリックすると
Googleアカウントの「アクセス要求」に移り、
「アクセスを許可」することで、トークンが手に入る。
次のページを表示する際に、
トークンをアップグレードし、データを取得し、
一覧を表示する。
main.pyの抜粋を以下に記す。

<pre>~~~~~~省略~~~~~~~
class MainHandler(webapp.RequestHandler):
layout_file ='layout.html'
view_dir = '../views/'
layout = {
'title':'Googleデータアクセス',
'body_title':'Googleデータアクセス',
'heder_title':'',
'heder_content':'',
'header':'header.html',
'footer':'footer.html',
}
def get(self):
user = users.get_current_user()
if user:
self.layout['link'] = ("ようこそ、%s! (<a href="\">ログアウト</a>)" %
(user.nickname(), users.create_logout_url(self.request.uri)))
else:
self.layout['link'] = ("<a href="\">ログイン</a>." %
users.create_login_url(self.request.uri))
client = gdata.service.GDataService()
gdata.alt.appengine.run_on_appengine(client)
#
docs_gdataScope = 'http://docs.google.com/feeds/'
authsub_docs = atom.url.Url('http', settings.HOST_NAME, path='/docs')
gdurl_docs = client.GenerateAuthSubURL(authsub_docs,docs_gdataScope,secure=False, session=True)
cal_gdataScope = 'http://www.google.com/calendar/feeds'
authsub_cal = atom.url.Url('http', settings.HOST_NAME, path='/calender')
gdurl_cal = client.GenerateAuthSubURL(authsub_cal,cal_gdataScope,secure=False, session=True)
pic_gdataScope = 'http://picasaweb.google.com/data/'
authsub_pic = atom.url.Url('http', settings.HOST_NAME, path='/picasa')
gdurl_pic = client.GenerateAuthSubURL(authsub_pic,pic_gdataScope,secure=False, session=True)
yt_gdataScope = 'http://gdata.youtube.com'
authsub_yt = atom.url.Url('http', settings.HOST_NAME, path='/youtube')
gdurl_yt = client.GenerateAuthSubURL(authsub_yt,yt_gdataScope,secure=False, session=True)
ss_gdataScope = 'http://spreadsheets.google.com/feeds/'
authsub_ss = atom.url.Url('http', settings.HOST_NAME, path='/spreadsheets')
gdurl_ss = client.GenerateAuthSubURL(authsub_ss,ss_gdataScope,secure=False, session=True)
self.layout['content'] = self.view_dir + 'index.html'
params = {'gdurl_docs':gdurl_docs,'gdurl_cal':gdurl_cal,'gdurl_pic':gdurl_pic,'gdurl_yt':gdurl_yt,'gdurl_ss':gdurl_ss,'user':user,'layout':self.layout}
fpath = os.path.join(os.path.dirname(__file__),'layouts',self.layout_file)
html = template.render(fpath,params)
self.response.out.write(html)
class DocsHandler(webapp.RequestHandler):
layout_file ='layout.html'
view_dir = '../views/'
layout = {
'title':'GoogleDocumentデータアクセス',
'body_title':'GoogleDocumentデータアクセス',
'heder_title':'',
'heder_content':'',
'header':'header.html',
'footer':'footer.html',
}
def get(self):
user = users.get_current_user()
client = gdata.docs.service.DocsService()
gdata.alt.appengine.run_on_appengine(client)
session_token = None
# Find the AuthSub token and upgrade it to a session token.
auth_token = gdata.auth.extract_auth_sub_token_from_url(self.request.uri)
if auth_token:
# Upgrade the single-use AuthSub token to a multi-use session token.
session_token = client.upgrade_to_session_token(auth_token)
if session_token and users.get_current_user():
# If there is a current user, store the token in the datastore and
# associate it with the current user. Since we told the client to
# run_on_appengine, the add_token call will automatically store the
# session token if there is a current_user.
client.token_store.add_token(session_token)
elif session_token:
# Since there is no current user, we will put the session token
# in a property of the client. We will not store the token in the
# datastore, since we wouldn't know which user it belongs to.
# Since a new client object is created with each get call, we don't
# need to worry about the anonymous token being used by other users.
client.current_token = session_token
feed = client.GetDocumentListFeed()
self.layout['content'] = self.view_dir + 'gddocs.html'
params = {'feed':feed,'user':user,'layout':self.layout}
fpath = os.path.join(os.path.dirname(__file__),'layouts',self.layout_file)
html = template.render(fpath,params)
self.response.out.write(html)
~~~~~~省略~~~~~~~

以上。
私がつくったアプリ↓
協調型意思決定支援システム「○ 賛否両論 ×(ベータ版)」

http://sanpiryoron.appspot.com/

協調型プロジェクトタスク管理ツール「キャッチ&リリース(ベータ版)」

http://ctchandrls.appspot.com/

GoogleデータサービスAuthSub API利用サンプルアプリ

DAYS 11 日時に関して

2009年10月27日 火曜日

[ GAE Google App Engine ][ Phthon ][ Google Bigtable ]
日時のデータに関していくつか。
・タイムゾーンについて
db.modelの日時に関するプロパティで
「auto_now_add=True」「auto_now=True」を設定すると
すべて世界協定時刻(UTC)が保存される。
「キャッチ&リリース(ベータ版)」では、「締切」を入力するようになっているため、
日本時間の締切を入力するのが当り前であるが、
更新日時、登録日時は世界協定時刻(UTC)なのである。
この違いの解決方法としては、
データはすべて世界協定時刻(UTC)で保存し、
表示するときに、日本であれば、日本標準時(JST; GMT+09:00)表示に
変換するというのが正しいやり方のようだ。
ちなみに、入力した日時は、世界協定時刻(UTC)に変換しなければならない。
参考:はしっこの、そのへん「Google App Engine再び」
今回のシステムでは、変換は行っていない。
なぜなら、今後、世界規模でプロジェクトを実行することは容易に想定できるからである。それであれば、日時の基準を世界にひとつにした方がよい。
このシステムはWebである以上、日本時間が基準とはいえないのだから。
(日本語で作ってはありますが・・・)
日本にいる人間は、「現在の時間 プラス 9時間」という前提で、締切を決めたり、
作業を行えばよいのである。人間側で対応すべき問題である。
データの登録、更新処理の全ての処理に
この変換をいれるのが大変だから、と理由では断じてない!
・日時の整合性について
「締切日が現在より、未来であること」
「開始日と、完了日がひっくりかえらないこと」
といったチェック機能を入れようとしたが、やめた。
チェックは人間がする。そして、間違いに気づいたら人間が直す。
・日時の表示の変更について
HTMLページで、DateTimeデータを表示させると
「 2009-10-14 14:00:18.156817 」
のようにわけのわからない数字が、最後に入ってしまう。
表示形式の指定方法を変更するには、以下のようにする。
変更前「 2009-10-14 14:00:18.156817 」
{{ data.add_date}} と指定
変更後「 2009-10-14 14:00:18 」
{{ data.add_date|date:”Y-m-d H:m:s” }} と指定
私がつくったアプリ↓
協調型意思決定支援システム「○ 賛否両論 ×(ベータ版)」

http://sanpiryoron.appspot.com/

協調型プロジェクトタスク管理ツール「キャッチ&リリース(ベータ版)」

http://ctchandrls.appspot.com/

DAYS 10 俺はなんてアフォーム(FORM)なんだ!

2009年10月26日 月曜日

データの追加、編集処理、HTMLでいうFormの画面で、いくつか分かったことがあるので以下に記す。
前回の「○ 賛否両論 ×(ベータ版)」では、
唯一のデータ編集画面「ユーザー情報の編集」で、
編集のHTMLのFORM画面に、更新前のデータを表示させることができなかった。
表示させても、submitするとデータが追加されてしまい更新処理ができてなかった。
泣く泣く、Djangoを使わず処理した。
DjangoがGAEバージョンなので、あきらめていた。
だが、今回、試行錯誤した結果、Django使って、更新処理を行う方法が分かった。
本来、分かって当たり前なのかもしれないが、
やっと・・・
やっとわかった!
こんなかんじ↓↓↓

# モデルクラス
class UserData(db.Model):
user = db.UserProperty(required=True,auto_current_user=True)
name = db.StringProperty(required=True,verbose_name='※名前')
presentation = db.TextProperty(verbose_name='自己紹介')
del_flg = db.IntegerProperty(default=0,verbose_name='削除フラグ')
add_date = db.DateTimeProperty(auto_now_add=True,verbose_name='作成日時')
update_date = db.DateTimeProperty(auto_now=True,verbose_name='更新日時')
def __unicode__(self):
return self.name
# DjangoFormを使うためのフォームクラス
class UsrForm(djangoforms.ModelForm):
class Meta:
model = UserData
exclude = ['user','del_flg']
# ハンドラー
class UsrEditHandler(webapp.RequestHandler):
~~~(省略)~~~
def post(self):
user = users.get_current_user()
if user:
q = db.GqlQuery("SELECT * FROM UserData WHERE del_flg = 0 AND user = :1", user)
q = q.get()
<span style="color: #ff0000;">ここ!</span>
form = UsrForm(<span style="color: #ff0000;">instance=q</span>,data=self.request.POST)
if form.is_valid():
data = form.save()
data.put()
self.redirect('/user')
~~~(省略)~~~

そのほかには、
データ更新画面で入力ミスをした時のパラメータ受け渡しを完全に忘れていた。
たとえば、
「 http://ctchandrls.appspot.com/—-/—?id=XXXXX 」
のように、GETで「id」パラメータを渡している時は、
入力ミスをして、更新画面に戻った時にも、「id」パラメータを渡しておかないと
エラーになってしまう。
テストしたときに気づけばいいのだが、
入力ミスのテストは、少ししかやってないし、
やる気もあまりなく、公開直前に気付いた。
以上。
私がつくったアプリ↓
協調型意思決定支援システム「○ 賛否両論 ×(ベータ版)」

http://sanpiryoron.appspot.com/

協調型プロジェクトタスク管理ツール「キャッチ&リリース(ベータ版)」

http://ctchandrls.appspot.com/

DAYS 9 タスク管理ツール 「キャッチ&リリース(ベータ版)」

2009年10月25日 日曜日

新たにアプリケーションを作成した。
協調型プロジェクトタスク管理ツール「キャッチ&リリース(ベータ版)」

http://ctchandrls.appspot.com/

前回作成したアプリは、GAEでの初めてのアプリで、
GAE、Python、Bigtableの勉強と
Google Visualization APIと連携して、
かっこよくグラフだしたいなぁというような想いで作った。
でも、グラフは表示するようになってはいない。
今回のアプリは、タスク管理ツールなので
カレンダーAPI(Google Calendar APIs and Tools)と連携できたらいいなぁと想いで作った。
結局、Google Calendarとも連携はできなかった。
次回作は、Googoleドキュメント(Google Documents List Data API)との連携を考えている。
前回のアプリ作成での教訓は、
「できるようにやれ!」である。
こっちがいくら頭で考えていたことがあっても、
GAEには制約があり、その通りはならないこともある。
そういう時は、自分の考えを変えることである。
「できるようにやる」で運用と使用する側で対応するということである。
「システムより人間の方が能力が高い」ということと性善説を前提にしたシステムである。
ウォータフォール型のシステム開発では考えられない作る側が作りやすく仕様を変えてしまうやり方だ。
以下に、当初考えていたが変更した点を列挙する。
いわゆる、できないリストなので、注意されたし!
・プロジェクトチームというグループを作り、そのメンバーだけが、
「責任者」のselectボックスに表示させたかったが、
作り方がよくわからず、セレクトボックスには、ユーザー登録した全てのユーザーが表示される。
・ユーザーデータとして、「技術レベル」「対人スキル」「報酬ランク」を入れて
マネージャだけがそのデータを閲覧できるようにしたかったが、
権限、ロール、アクセス制御など大変そうなのでやめた。
・タスクのリレー、つまり、タスクをメンバー内でやりとりしたり、
タスク作業時間を計算しようとしたが、やめた。
タスクの報告・連絡・相談のやりとりは、
プロジェクト責任者とタスク責任者の間のみで可能。
・プロジェクトの進捗度を、
(全てのタスクの進捗度の和)÷(タスク数)で自動的に表示させようと思ったが、
タスクごとの負荷が違うので、やめた。
以上。

おにごっこレーダー

2009年10月12日 月曜日

GAEやGoogleMAPやAndroid使って、
こんなのあったらいいなぁと思っていたら、
iPhoneではもうあった!!!

「鬼ごっこレーダー」子供の頃にiPhoneがあったら絶対やってみたいと思ったであろうハイテク鬼ごっこのアプリ

Androidと
GoogleMapとのAPIがあれば
簡単にできそう。
Googleの出遅れてる感は否めないね。
個人的には、「おにごっこ」より、
「だるまさんがころんだ」の方が面白いと思う。
カメラも連動して、止まっている時に、画像を送信する。
あとでWebで全員の動きが見れるとおもしろいと思うのだが・・・・。
固定地点に、いろいろなところから集まってくる方が
待ち合わせにも使えるし、映像的にも面白いものになるのではないか???
いやー、でも、現代っ子はこんな鬼ごっこやってるとしたら、
ジェネレーションギャップは、
もう埋まるわけないよね。