-
Notifications
You must be signed in to change notification settings - Fork 0
/
__init__.py
121 lines (96 loc) · 3.24 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
import functools
import webapp2
import json
from google.appengine.ext import db
from google.appengine.api import users
def require_login(**options):
if users.get_current_user():
return None
redirect = options.get('redirect')
if redirect:
return webapp2.redirect(users.create_login_url(redirect))
resp = webapp2.Response()
resp.status = '400 Bad Request'
return resp
def login_required(func, **deco_kwargs):
@functools.wraps(func)
def decorated_view(*args, **kwargs):
return require_login(**deco_kwargs) or func(*args, **kwargs)
return decorated_view
def user_to_serializable(user):
return {
"nickname": user.nickname(),
"email": user.email(),
"user_id": user.user_id()
}
class ModelSerizable(object):
to_map = {
users.User: user_to_serializable
}
@staticmethod
def _build_property_name(list, base):
if issubclass(base, ModelSerizable):
list += base.list_property_names()
return list
@classmethod
def list_property_names(cls):
names = [k for k,v in cls.__dict__.items() if isinstance(v, db.Property)]
return reduce(cls._build_property_name, cls.__bases__, names)
@classmethod
def _build_serializable(cls, value, dict):
names = cls.list_property_names()
for name in names:
value = getattr(value, name)
to = ModelSerizable.to_map.get(value.__class__)
dict[name] = to and to(value) or value
return dict
def to_serializable(self):
return self._build_serializable(self, {"id": str(self.key()) })
class User(db.Model, ModelSerizable):
account = db.UserProperty(required=True)
@classmethod
def find_by_account(cls, account):
return cls.all().filter("account =", account).get()
@classmethod
def ensure_by_account(cls, account):
found = cls.find_by_account(account)
if found:
return found
created = cls(account=account)
created.put()
return created
class UserMapper(object):
def get_account(self):
return users.get_current_user()
def get(self, params):
if (1 != len(params)):
return users.create_login_url(self.url)
account = self.get_account()
key = params[0]
if (key == "me"):
return User.ensure_by_account(account)
try:
found = User.get(db.Key(key))
except db.BadKeyError:
return None
if not found or found.account != account:
return None
return found
class UserController(webapp2.RequestHandler):
url = '/r/([^/]+)'
@property
def mapper(self):
if not hasattr(self, '_mapper'):
self._mapper = UserMapper()
return self._mapper
@login_required
def get(self, *args):
found = self.mapper.get(args)
if not found:
self.response.status = 404
return
self.response.headers['Content-Type'] = 'text/json'
json.dump(found.to_serializable(), self.response.out)
return self.response
def to_application(handler_classes):
return webapp2.WSGIApplication([(p.url, p) for p in handler_classes])