Created
October 28, 2008 12:36
-
-
Save taka2/20363 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
import cgi | |
import os | |
import time | |
import string | |
import datetime | |
import urllib | |
from google.appengine.api import users | |
from google.appengine.ext import webapp | |
from google.appengine.ext.webapp.util import run_wsgi_app | |
from google.appengine.ext import db | |
from google.appengine.ext.webapp import template | |
# JSTを表すクラス | |
class JST(datetime.tzinfo): | |
def utcoffset(self, dt): | |
return datetime.timedelta(hours=9) | |
def dst(self, dt): | |
return datetime.timedelta(0) | |
def tzname(self, dt): | |
return "JST" | |
# 家計簿モデル | |
class FamilyBudget(db.Model): | |
author = db.UserProperty() | |
kamoku = db.StringProperty() | |
kingaku = db.FloatProperty() | |
targetDate = db.DateProperty() | |
content = db.StringProperty(multiline=True) | |
date = db.DateTimeProperty(auto_now_add=True) | |
# 科目モデル | |
class Kamoku(db.Model): | |
author = db.UserProperty() | |
kamoku = db.StringProperty() | |
kamokuName = db.StringProperty() | |
date = db.DateTimeProperty(auto_now_add=True) | |
# 家計簿の一覧アクション | |
class Index(webapp.RequestHandler): | |
def get(self): | |
user = authorization(self, users.get_current_user()) | |
nowDatetime = datetime.datetime.now(JST()) | |
family_budgets = get_family_budget_by_year_month(user, nowDatetime.year, nowDatetime.month) | |
# 当月の収入と支出の合計を算出する | |
income = get_sum_of_income(family_budgets) | |
outgo = get_sum_of_outgo(family_budgets) | |
kamoku_query = Kamoku.gql("WHERE author = :1 ORDER BY kamoku", user) | |
kamoku_list = kamoku_query.fetch(1000) | |
# Translate kamoku name | |
new_family_budgets = [] | |
i = 0 | |
for family_budget in family_budgets: | |
kamokuName = get_kamokuName_by_kamoku(user, family_budget.kamoku) | |
hash = {} | |
hash["id"] = family_budget.key().id() | |
hash["kamokuName"] = kamokuName | |
hash["author"] = family_budget.author | |
hash["kamoku"] = family_budget.kamoku | |
hash["kingaku"] = family_budget.kingaku | |
hash["content"] = family_budget.content[0:5] | |
hash["targetDate"] = family_budget.targetDate.strftime("%m/%d") | |
new_family_budgets.append(hash) | |
i = i + 1 | |
# 表示は10件まで | |
if i >= 10: | |
break | |
template_values = { | |
'family_budgets': new_family_budgets, | |
'kamoku_list': kamoku_list, | |
'user': user, | |
'today': nowDatetime.strftime("%Y/%m/%d"), | |
'thisMonth': nowDatetime.strftime("%Y/%m"), | |
'income': income, | |
'outgo': outgo, | |
'total': income - outgo | |
} | |
path = os.path.join(os.path.dirname(__file__), 'index.html') | |
self.response.out.write(template.render(path, template_values)) | |
# 家計簿の一覧Csv形式ダウンロードアクション | |
class CsvDownload(webapp.RequestHandler): | |
def get(self): | |
user = authorization(self, users.get_current_user()) | |
splittedYearMonth = string.split(self.request.get('year_month'), "/") | |
year = int(splittedYearMonth[0]) | |
month = int(splittedYearMonth[1]) | |
family_budgets = get_family_budget_by_year_month(user, year, month) | |
self.response.headers.add_header('content-type', 'text/csv') | |
self.response.headers.add_header('content-disposition', 'attachment', filename='list.csv') | |
self.response.out.write("No,Author,Kamoku,KamokuName,Kingaku,TargetDate,Memo,Date\n") | |
for family_budget in family_budgets: | |
kamokuName = get_kamokuName_by_kamoku(user, family_budget.kamoku) | |
lineData = "" | |
lineData = lineData + "\"" + str(family_budget.key().id()) + "\"" | |
lineData = lineData + ",\"" + str(family_budget.author) + "\"" | |
lineData = lineData + ",\"" + family_budget.kamoku + "\"" | |
lineData = lineData + ",\"" + kamokuName + "\"" | |
lineData = lineData + ",\"" + str(family_budget.kingaku) + "\"" | |
lineData = lineData + ",\"" + str(family_budget.targetDate) + "\"" | |
lineData = lineData + ",\"" + family_budget.content + "\"" | |
lineData = lineData + ",\"" + str(family_budget.date) + "\"" | |
lineData = lineData + "\n" | |
self.response.out.write(lineData) | |
# 科目ごとの支出をグラフで表示 | |
class PieChart(webapp.RequestHandler): | |
def get(self): | |
user = authorization(self, users.get_current_user()) | |
splittedYearMonth = string.split(self.request.get('year_month'), "/") | |
year = int(splittedYearMonth[0]) | |
month = int(splittedYearMonth[1]) | |
family_budgets = get_family_budget_by_year_month(user, year, month) | |
expense_per_kamoku = get_sum_of_outgo_per_kamoku(family_budgets) | |
sum = 0 | |
for data in expense_per_kamoku: | |
sum = sum + expense_per_kamoku[data] | |
chd = "" | |
chl = "" | |
for data in expense_per_kamoku: | |
key = get_kamokuName_by_kamoku(user, data) | |
value = expense_per_kamoku[data] | |
if chd != "": | |
chd = chd + "," | |
if chl != "": | |
chl = chl + "|" | |
chd = chd + str(int((value / sum) * 100)) | |
chl = chl + urllib.quote(key.encode("utf-8")) | |
self.redirect('http://chart.apis.google.com/chart?chs=400x150&chd=t:' + chd + '&cht=p3&chl=' + chl) | |
# 家計簿の登録アクション | |
class Regist(webapp.RequestHandler): | |
def post(self): | |
user = authorization(self, users.get_current_user()) | |
family_budget = FamilyBudget() | |
family_budget.author = user | |
family_budget.kamoku = self.request.get('kamoku') | |
family_budget.kingaku = float(self.request.get('kingaku')) | |
splittedDate = string.split(self.request.get('date'), "/") | |
family_budget.targetDate = datetime.date(int(splittedDate[0]), int(splittedDate[1]), int(splittedDate[2])) | |
family_budget.content = self.request.get('memo') | |
key = family_budget.put() | |
self.redirect('/') | |
# 家計簿の削除アクション | |
class Delete(webapp.RequestHandler): | |
def post(self): | |
user = authorization(self, users.get_current_user()) | |
family_budget = FamilyBudget.get_by_id(int(self.request.get('id'))) | |
family_budget.delete() | |
self.redirect('/') | |
# 科目の一覧アクション | |
class IndexKamoku(webapp.RequestHandler): | |
def get(self): | |
user = authorization(self, users.get_current_user()) | |
kamoku_query = Kamoku.gql("WHERE author = :1 ORDER BY kamoku", user) | |
kamoku_list = kamoku_query.fetch(1000) | |
template_values = { | |
'kamoku_list': kamoku_list, | |
'user': user | |
} | |
path = os.path.join(os.path.dirname(__file__), 'kamoku_list.html') | |
self.response.out.write(template.render(path, template_values)) | |
# 科目の登録アクション | |
class RegistKamoku(webapp.RequestHandler): | |
def post(self): | |
user = authorization(self, users.get_current_user()) | |
kamoku = Kamoku() | |
kamoku.author = user | |
kamoku.kamoku = self.request.get('kamoku') | |
kamoku.kamokuName = self.request.get('kamokuName') | |
kamoku.put() | |
self.redirect('/index_kamoku') | |
# 科目の削除アクション | |
class DeleteKamoku(webapp.RequestHandler): | |
def post(self): | |
user = authorization(self, users.get_current_user()) | |
kamoku_query = Kamoku.gql("WHERE author = :1 AND kamoku = :2", user, self.request.get('kamoku')) | |
kamoku_list = kamoku_query.fetch(1) | |
kamoku_list[0].delete() | |
self.redirect('/index_kamoku') | |
# ログイン済みかどうかと、メールアドレスのチェック | |
def authorization(requestHandler, user): | |
if not user: | |
url = users.create_login_url(requestHandler.request.uri) | |
requestHandler.redirect(url) | |
else: | |
if user.email() == "Takahiro.Shigemoto@gmail.com": | |
return user | |
else: | |
url = users.create_login_url("http://www.yahoo.co.jp/") | |
requestHandler.redirect(url) | |
# 科目コードから科目名を翻訳する | |
def get_kamokuName_by_kamoku(user, kamoku): | |
kamoku_query = Kamoku.gql("WHERE author = :1 AND kamoku = :2", user, kamoku) | |
kamoku_list = kamoku_query.fetch(1) | |
if len(kamoku_list) == 0: | |
return "" | |
else: | |
return kamoku_list[0].kamokuName | |
# 年月より家計簿データを取得する | |
def get_family_budget_by_year_month(user, year, month): | |
dateFrom = datetime.datetime(year, month, 1) | |
if month == 12: | |
dateTo = datetime.datetime(year + 1, 1, 1) | |
else: | |
dateTo = datetime.datetime(year, month + 1, 1) | |
family_budget_query = FamilyBudget.gql("WHERE author = :1 AND targetDate >= :2 AND targetDate <= :3 ORDER BY targetDate DESC", user, dateFrom, dateTo) | |
family_budgets = family_budget_query.fetch(1000) | |
return family_budgets | |
# 家計簿データより支出合計を取得する | |
def get_sum_of_outgo(family_budgets): | |
sum = 0 | |
for family_budget in family_budgets: | |
if len(family_budget.kamoku) == 2: | |
sum = sum + family_budget.kingaku | |
return sum | |
# 家計簿データより科目ごとの支出合計を取得する | |
def get_sum_of_outgo_per_kamoku(family_budgets): | |
result = {} | |
for family_budget in family_budgets: | |
if len(family_budget.kamoku) == 2: | |
if result.has_key(family_budget.kamoku): | |
result[family_budget.kamoku] = result[family_budget.kamoku] + family_budget.kingaku | |
else: | |
result[family_budget.kamoku] = family_budget.kingaku | |
return result | |
# 家計簿データより収入合計を取得する | |
def get_sum_of_income(family_budgets): | |
sum = 0 | |
for family_budget in family_budgets: | |
if len(family_budget.kamoku) == 3: | |
sum = sum + family_budget.kingaku | |
return sum | |
# URLとアクションクラスのマッピング | |
application = webapp.WSGIApplication( | |
[('/', Index), | |
('/csv_download', CsvDownload), | |
('/pie_chart', PieChart), | |
('/regist', Regist), | |
('/delete', Delete), | |
('/index_kamoku', IndexKamoku), | |
('/regist_kamoku', RegistKamoku), | |
('/delete_kamoku', DeleteKamoku)], | |
debug=True) | |
# Webアプリケーションの初期化 | |
def main(): | |
run_wsgi_app(application) | |
if __name__ == "__main__": | |
main() | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment