-
Notifications
You must be signed in to change notification settings - Fork 0
/
address_data.py
133 lines (108 loc) · 3.82 KB
/
address_data.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
122
123
124
125
126
127
128
129
130
131
132
133
"""
@author: Harry J.E Day <[email protected]>
@date: 27/08/17
@copyright: Harry J.E Day 2017.
@summary: very simple email book data structures
"""
from google.appengine.ext import ndb
class AddressEntry(ndb.Model):
name = ndb.StringProperty(required=True)
email = ndb.StringProperty(required=True)
def to_json_dict(self):
"""
converts the email entry into a json serializable dict
:return: a dictionary representing this model instance
:rtype: dict
"""
return {
"id" : self.key.urlsafe(),
"name": self.name,
"email": self.email
}
@staticmethod
def get_all_addresses(limit, paginated=False, cursor_key=None):
"""
get all addresses in the email book
:param limit: the limit on the number to return
:param paginated: if we should return a key for pagination
:param cursor_key: the key of the cursor if we are on a later page
:return: json serialisable dict representing all the emailes
"""
if paginated and cursor_key:
cursor = ndb.Cursor(urlsafe=cursor_key)
else:
cursor = ndb.Cursor()
results, next_cursor, is_more = AddressEntry.query().fetch_page(limit, start_cursor=cursor)
jdict = {
"entries" : [entry.to_json_dict() for entry in results],
"is_more" : is_more
}
if paginated:
jdict["next"] = cursor.urlsafe()
return jdict
@staticmethod
def json_to_model(jdict, put=True):
"""
Converts a dictionary to the model
:param jdict: json serialisable dictionary to put
:param put: if we should store it or not
:return: tuple of bool (succes) and the model object or error message
"""
if not ("name" in jdict and "email" in jdict):
return False, "missing fields"
model = AddressEntry(
id=jdict["email"], # use the email for id, it makes conflict checking much simpler
name=jdict["name"],
email=jdict["email"]
)
if put:
model.put()
return True, model
@staticmethod
@ndb.transactional(xg=True)
def update_model(key, jdict, put=True):
"""
Converts a dictionary to the model
:param key: the key to retrive
:param jdict: json serialisable dictionary to put
:param put: if we should store it or not
:return: tuple of bool (succes) and the model object or error code
"""
key = ndb.Key(urlsafe=key)
model = key.get()
if model is None:
return False, 404
if "email" in jdict:
model.email = jdict["email"]
# note this operation changes the entity's key
model.key.delete()
model.key = ndb.Key(AddressEntry, model.email)
if "name" in jdict:
model.name = jdict["name"]
if put:
model.put()
return True, model
@staticmethod
@ndb.transactional(xg=True)
def check_and_add(email, name):
"""
Checks an entry, adds it to the db if there are no matches. Otherwise returns error handling json
:param email: the email to add
:param name: the name
:return: success, json
"""
key = ndb.Key(AddressEntry, email)
model = key.get()
# we only have a problem if a model for the given email exists AND the name is different
if not model is None:
if model.name != name:
jdict = model.to_json_dict()
jdict["requested_name"] = name
return False, jdict
model = AddressEntry(
id=email,
email=email,
name=name
)
model.put()
return True, model.to_json_dict()