app.yaml
application: アプリ名 version: 1 runtime: python api_version: 1 handlers: - url: /main script: get_timeline.py - url: /send script: send_tweet.py - url: /db/delete script: db_delete.py - url: .* script: default.py
cron.yaml
cron: - description: Get Timeline job url: /main schedule: every 10 minutes - description: Send Tweet job url: /send schedule: every 15 minutes - description: DB Delete job url: /db/delete schedule: every 60 minutes
get_timeline.py
# -*- coding: utf-8 -*- import sys, os, re, urllib, urllib2 import simplejson import tweepy from datetime import * from google.appengine.ext import webapp from google.appengine.ext.webapp.util import run_wsgi_app from google.appengine.ext import db #OAuth CONSUMER_KEY = 'CONSUMER_KEY' #自分で取得した値を入れる CONSUMER_SECRET = 'CONSUMER_SECRET' #自分で取得した値を入れる ACCESS_TOKEN = 'ACCESS_TOKEN' #自分で取得した値を入れる ACCESS_TOKEN_SECRET = 'ACCESS_TOKEN_SECRET' #自分で取得した値を入れる #データモデルの定義 class TimelineData(db.Model): icon_url = db.StringProperty() #アイコン画像URL scr_name = db.StringProperty() #スクリーン名 usr_name = db.StringProperty() #ユーザ名 tweet = db.StringProperty(multiline=True) #ツイート status_id = db.StringProperty() #ステータスID reply_id = db.StringProperty() #リプライID created_at = db.StringProperty() #ツイートされた日時 ds_created = db.DateTimeProperty() #DataStoreに登録された日時 sent = db.IntegerProperty() #送信済みフラグ schema_ver = db.IntegerProperty() #スキーマ・バージョン # メイン処理 class GetTimeline(webapp.RequestHandler): def get(self): #HomeTimelineの取得 auth = tweepy.OAuthHandler(CONSUMER_KEY, CONSUMER_SECRET) auth.set_access_token(ACCESS_TOKEN, ACCESS_TOKEN_SECRET) api = tweepy.API(auth) home_timeline = api.home_timeline(count=50) #TimeLineの並び順を逆順に変更 home_timeline.reverse() for tw in home_timeline: try: #同じステータスIDが登録されているかCheck registed_check_query = TimelineData().all().order('-ds_created').filter('status_id =', str(tw.id).encode("UTF-8")).get() print registed_check_query #登録がなければ、登録 if None == registed_check_query: #データストアに登録 td = TimelineData() td.icon_url = tw.user.profile_image_url #アイコン画像URL td.scr_name = tw.user.screen_name #スクリーン名 td.usr_name = tw.user.name #ユーザ名 td.tweet = tw.text #ツイート td.status_id = str(tw.id).encode("UTF-8") #ステータスID td.reply_id = str(tw.in_reply_to_status_id).encode("UTF-8") #リプライID td.created_at = str(tw.created_at).encode("UTF-8") #ツイートされた日時 td.ds_created = datetime.utcnow() + timedelta(hours=9) #DataStoreに登録された日時 td.sent = 0 #送信済みフラグ、0は未送信 td.schema_ver = 2 #スキーマ・バージョン td.put() print "▼Check Status" print td.icon_url.encode("UTF-8") print td.scr_name.encode("UTF-8") print td.usr_name.encode("UTF-8") print td.tweet.encode("UTF-8") print td.status_id.encode("UTF-8") print td.reply_id.encode("UTF-8") print td.created_at.encode("UTF-8") print str(td.ds_created).encode("UTF-8") print str(td.sent).encode("UTF-8") print str(td.schema_ver).encode("UTF-8") print "△Save DataStore\n" else: print "△Skip DataStore\n" except: print "△NG DataHandling\n" application = webapp.WSGIApplication( [ ('/main', GetTimeline), ], debug=True) def main(): run_wsgi_app(application) if __name__ == "__main__": main()
send_tweet.py
# -*- coding: utf-8 -*- import sys, os, re, urllib, urllib2 from google.appengine.ext import webapp from google.appengine.ext.webapp.util import run_wsgi_app from google.appengine.ext import db import base64 from google.appengine.api import mail from dateutil import parser from dateutil import relativedelta #データモデルの定義 class TimelineData(db.Model): icon_url = db.StringProperty() #アイコン画像URL scr_name = db.StringProperty() #スクリーン名 usr_name = db.StringProperty() #ユーザ名 tweet = db.StringProperty(multiline=True) #ツイート status_id = db.StringProperty() #ステータスID reply_id = db.StringProperty() #リプライID created_at = db.StringProperty() #ツイートされた日時 ds_created = db.DateTimeProperty() #DataStoreに登録された日時 sent = db.IntegerProperty() #送信済みフラグ schema_ver = db.IntegerProperty() #スキーマ・バージョン #メイン処理 class SendTweet(webapp.RequestHandler): def get(self): not_send = TimelineData().all().order('ds_created').filter('sent =', 0).fetch(limit=200) #print not_send count = 0 #ツイート数 start = "" #最初のツイート body = "" #ツイートの要約 #"http://twitter.com/#!/" if not_send: for ns in not_send: #時刻を変換 d = parser.parse(ns.created_at) jst = d + relativedelta.relativedelta(hours=+9) #print jst try: body += '' + "\n" body += '' + "\n" body += '' + "\n" body += '' + "\n" body += '' body += '' + ns.scr_name.encode("UTF-8") + ' (' + ns.usr_name.encode("UTF-8") + ')' + '' + "\n" body += '' + str(jst).encode("UTF-8") + '' + ns.tweet.encode("UTF-8") + '' + "\n" body += 'http://mobile.twitter.com/' + ns.scr_name.encode("UTF-8") + '/status/' + ns.status_id.encode("UTF-8") + '' + "\n" if 'None' != ns.reply_id: body += '' body += '
' + "\n" body += "\n" count += 1 if count == 1 : #start = ns.created_at.encode("UTF-8") start = str(jst).encode("UTF-8") ns.sent = 1 #送信済みフラグの変更 ns.put() print str(ns.sent).encode("UTF-8") except: print count print ns.sent #print body subject = start + " から " + str(count).encode("UTF-8") + "件"; print subject fromAddr = "from: メールアドレス"; toAddr = "to: メールアドレス"; html_h = "\n\n" html_f = "" + "\n" html_body = "" html_body += html_h html_body += body html_body += html_f #print html_body mail.send_mail(fromAddr, toAddr, subject, body=" ", html=html_body) else: print "No Data" application = webapp.WSGIApplication( [ ('/send', SendTweet), ], debug=True) def main(): run_wsgi_app(application) if __name__ == "__main__": main()
db_delete.py
# -*- coding: utf-8 -*- import sys, os, re, urllib, urllib2 from google.appengine.ext import webapp from google.appengine.ext.webapp.util import run_wsgi_app from google.appengine.ext import db #データモデルの定義 class TimelineData(db.Model): icon_url = db.StringProperty() #アイコン画像URL scr_name = db.StringProperty() #スクリーン名 usr_name = db.StringProperty() #ユーザ名 tweet = db.StringProperty(multiline=True) #ツイート status_id = db.StringProperty() #ステータスID reply_id = db.StringProperty() #リプライID created_at = db.StringProperty() #ツイートされた日時 ds_created = db.DateTimeProperty() #DataStoreに登録された日時 sent = db.IntegerProperty() #送信済みフラグ schema_ver = db.IntegerProperty() #スキーマ・バージョン #メイン処理 class DeleteDS(webapp.RequestHandler): def get(self): # DataStoreの削除 deleteCheck = TimelineData.all().filter('sent =', 1).fetch(limit=500) if deleteCheck : for dc in deleteCheck: try: db.delete(dc) print "deleted" except: print "no delete" else: print "no delete data" application = webapp.WSGIApplication( [ ('/db/delete', DeleteDS), ], debug=True) def main(): run_wsgi_app(application) if __name__ == "__main__": main()
default.py
print "Content-Type: text/plain" print "" print "TwitMail"
まだまだ見直す必要があるコードですが、参考になれば。