Gray sky, Blue sea.

programing, book, photo

楽天カードの会員規約改定

お知らせメール来てた。

第4条(個人情報の提供・利用)
○当社と個人情報の提供に関する契約を締結した当社の提携会社等が、下記の目的により個人情報を利用する場合。
【1.楽天スーパーポイントサービス等の提供のため。2.下記提携会社のインターネット付随サービス業における、新商品情報のお知らせ、関連するアフターサービス、市場調査・商品開発及び宣伝物・印刷物のダイレクトメールの送付、電子メールの送信、電話等による勧誘等の営業案内のため】

なんかよくわかんないけど、これからは会員情報使って電話の勧誘もガンガンするよ!ってことか。

勘弁してほしい。

gae - 一番簡単なtask queueのサンプル

とりあえずログだけ出力してみる。

import logging
from datetime import datetime
from google.appengine.api import taskqueue

class Test(webapp.RequestHandler):
    def post(self):
        logging.info("#### task execute : " + str(datetime.now()))

class AddTask(webapp.RequestHandler):
    def get(self):
        taskqueue.add(url='/test')

application = webapp.WSGIApplication(
                                     [('/task', AddTask),
                                      ('/test', Test)],
                                     debug=True)

def main():
    run_wsgi_app(application) 

ブラウザから/taskを開くことでAddTaskのgetが呼び出される。

taskqueue.addのパタメータurlにて、タスクキューへ登録するclassのurlを指定。

ローカル環境では、タスクは手動で実行しないと動かない。SDKコンソール → Task Queues → defaultを選択し、「Run」ボタンを押すと登録されたtaskが実行される。

f:id:h_maz:20120310231425p:plain

デフォルトだとpostで送信されるが、Taskを作って色々設定すればgetでリクエスト送信することも可能。実行時刻の指定とかもできる。詳しくはTask クラス - Google App Engine - Google Codeを参照。

 

amazon product advertising apiの10ページ制限がきつくて憤死しそうになる。

ItemSearchは2011年の10月中頃から10件×10ページ=100件までしか取得できなくなった。

変更前は400ページ(計4000件)まで取得できたことを考えるとあまりに無慈悲。代わりに検索の条件が複雑にできるからそれで対応してね!とかだったら納得できるけど、そんな感じもなし。たまには鞭だけじゃなく飴もください...

とりあえずソートを使って20ページまでは取得できるようにした。

  1. まず総ページ数を取得 → 21ページ以上なら諦める
  2. 20ページ以下なら、検索条件Sortで"titlerank"と"-titlerank"を指定して、2回レスポンス取得
  3. 返ってきたitem要素を両方リストとかに突っ込んで処理。
うーん。美しくない。

 

 

gae - ndb.StructurdPropertyでJava Beanチックなエンティティ作成

 データストアの非同期処理用に追加された(?)ndb.Modelはメンバに構造体っぽいのを保存できる。

(main.py)

from google.appengine.ext import ndb 

class Bean(ndb.Model):
    id = ndb.IntegerProperty()
    dt = ndb.DateProperty(auto_now=True)

class Hoge(ndb.Model):
    name = ndb.StringProperty()
    bean = ndb.StructuredProperty(Bean)

class Test(webapp.RequestHandler):
    def get(self):
        # 中身
        b = Bean()
        b.id = 456 
        # 親
        h = Hoge()
        h.name = "hige"
        h.bean = b 
        h.put()

        # ndbではall()は使えない。query()を使用。
        #hoges = Hoge.all()
        hoges = Hoge.query()
        template_values = { 
            'hoges' : hoges,
        }   
        path = os.path.join(os.path.dirname(__file__), 'test.html')
        self.response.out.write(template.render(path, template_values))

djangoのタグでは、hoge.bean.id、というように"."でつないで参照。

(test.html)

<html>
    <head>
        <meta charset="utf-8">
    </head>
    <body>
        {% if hoges %}
            {% for item in hoges %}
            {{ item.name }}, {{ item.bean.id }}, {{ item.bean.dt }} <br>
            {% endfor %}
        {% endif %}
    </body>
</html>

gaeのdatastore-viewerではこんな感じで表示される。↓

f:id:h_maz:20120310172309p:plain 

classが格納されるというよりは、classのメンバが展開されて格納されたような感じ。

gaeでTemplateSyntaxError: 'if' statement improperly formatted

django1.2以降のif表現を使用しているが、使用中のdjangoのバージョンが1.1以前だった。

gaeで使用するdjangoのバージョンを1.1に変えるには、pyファイルの先頭で

from google.appengine.dist import use_library
use_library('django', '1.1')

とすればよいが、テンプレートタグの書き方が一部1.2から変更されているため

ローカル環境で1.2とかを使用 → デプロイ時には1.1を使用

とかやっていて、うっかり1.2の書き方のままデプロイしてしまっていた。

ver1.1

{% ifequal p.name pubname %}AAA{% endifequal %}

ver1.2以降

{% if p.name == pubname %}AAA{% endif %}

1.2以降のほうがわかりやすくて良い。

 

※参考

django1.2リリースノート

gae - mail.send_mailでhtmlメールを送信する

google.appengine.api.mail.send_mailを呼び出す際に、キーワード引数'html'を追加する。

Google App Engine: how to send html using send_mail

#Your html body
    mail_html_body = 'Hello!'

    # read data from request
    mail_to = str(self.request.POST.get('to'))
    mail_from = str(self.request.POST.get('from'))
    mail_subject = str(self.request.POST.get('subject'))
    mail_body = str(self.request.POST.get('body'))

    mail.send_mail(mail_from, 
                   mail_to,
                   mail_subject, 
                   mail_body,
                   html = mail_html_body ) #your html body

gae - cron.yamlで、実行時間帯を指定する。

日本語ドキュメントには書いてなかった。

Scheduled Tasks With Cron for Python - Google App Engine - Google Code

例1: 毎日10時から14時まで、2分毎に実行したい

    - description: new daily summary job
      url: /test
      schedule: every 2 minutes from 10:00 to 14:00

というように、 from .. to .. で指定する。

指定可能な時間は、00:00 〜 23:59。

例2: 毎日00:01, 06:01, 12:01, 18:01に実行したい

schedule: every 6 hours from 00:01 to 00:00

とすればよい。