Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 261 lines (219 sloc) 8.769 kB
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
1 from google.appengine.ext import db
2 from google.appengine.api import urlfetch, memcache, users, mail
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
3 from datetime import datetime, timedelta
6157814 @progrium refactoring to_sentence, moving to utils
progrium authored
4 from utils import human_username, local_today, to_sentence_list
096bb16 Added logging to event actions
Brent Tubbs authored
5 import logging
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
6 import pytz
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
7
105d85d @btubbs Adding room capacities
btubbs authored
8 ROOM_OPTIONS = (
9 ('Cave', 15),
10 ('Deck', 30),
11 ('Savanna', 120),
12 ('140b', 129),
13 ('Cubby 1', 2),
14 ('Cubby 2', 2),
15 ('Upstairs Office', 2),
16 ('Front Area', 20))
4d85afa @dustball Remove staffing requirement and make members more responsible
dustball authored
17 # GUESTS_PER_STAFF = 25
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
18 PENDING_LIFETIME = 30 # days
19
20 class Event(db.Model):
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
21 status = db.StringProperty(required=True, default='pending', choices=set(
22 ['pending', 'understaffed', 'approved', 'canceled', 'onhold', 'expired', 'deleted']))
23 member = db.UserProperty(auto_current_user_add=True)
24 name = db.StringProperty(required=True)
25 start_time = db.DateTimeProperty(required=True)
26 end_time = db.DateTimeProperty()
27 staff = db.ListProperty(users.User)
28 rooms = db.StringListProperty() #choices=set(ROOM_OPTIONS)
29
30 details = db.TextProperty()
31 url = db.StringProperty()
32 fee = db.StringProperty()
33 notes = db.TextProperty()
34 type = db.StringProperty(required=True)
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
35 estimated_size = db.StringProperty(required=True)
f49797a @dustball Reminders 2.0
dustball authored
36 reminded = db.BooleanProperty(default=False)
096bb16 Added logging to event actions
Brent Tubbs authored
37
a244c65 @dustball Bug fixes
dustball authored
38 contact_name = db.StringProperty()
39 contact_phone = db.StringProperty()
096bb16 Added logging to event actions
Brent Tubbs authored
40
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
41 expired = db.DateTimeProperty()
42 created = db.DateTimeProperty(auto_now_add=True)
43 updated = db.DateTimeProperty(auto_now=True)
44
45 @classmethod
c97598b @dustball Room Conflict Detection
dustball authored
46 def check_conflict(cls,proposed_start_time,proposed_end_time,proposed_rooms,optional_existing_event_id = 0):
47 possible_conflicts = cls.all() \
7a8b163 @dustball Optimization for speed
dustball authored
48 .filter('end_time >', proposed_start_time) \
c97598b @dustball Room Conflict Detection
dustball authored
49 .filter('status IN', ['approved', 'pending', 'onhold'])
50 conflicts = []
51 for e in possible_conflicts:
52 if e.key().id() != optional_existing_event_id:
7a8b163 @dustball Optimization for speed
dustball authored
53 if e.start_time < proposed_end_time:
c97598b @dustball Room Conflict Detection
dustball authored
54 for r in e.rooms:
55 if r in proposed_rooms:
56 if e not in conflicts:
57 conflicts.append(e)
58 return conflicts
59
60
61 @classmethod
d9711ef @billsaysthis moves nav links to partial, adds all_future view includes all statuses
billsaysthis authored
62 def get_all_future_list(cls):
63 return cls.all() \
64 .filter('start_time >', local_today()) \
f8ffd89 @billsaysthis refactor lists to use singe event partial, adds contact email link in…
billsaysthis authored
65 .filter('status IN', ['approved', 'canceled', 'pending', 'onhold']) \
d9711ef @billsaysthis moves nav links to partial, adds all_future view includes all statuses
billsaysthis authored
66 .order('start_time')
67
68 @classmethod
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
69 def get_approved_list(cls):
70 return cls.all() \
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
71 .filter('start_time >', local_today()) \
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
72 .filter('status IN', ['approved', 'canceled']) \
73 .order('start_time')
096bb16 Added logging to event actions
Brent Tubbs authored
74
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
75 @classmethod
76 def get_pending_list(cls):
77 return cls.all() \
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
78 .filter('start_time >', local_today()) \
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
79 .filter('status IN', ['pending', 'understaffed', 'onhold', 'expired']) \
80 .order('start_time')
81
4d85afa @dustball Remove staffing requirement and make members more responsible
dustball authored
82 def owner(self):
83 return human_username(self.member)
84
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
85 def stafflist(self):
6157814 @progrium refactoring to_sentence, moving to utils
progrium authored
86 return to_sentence_list(map(human_username, self.staff))
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
87
88 def roomlist(self):
6157814 @progrium refactoring to_sentence, moving to utils
progrium authored
89 return to_sentence_list(self.rooms)
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
90
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
91 def roomlist_as_phrase(self):
92 if len(self.rooms) > 0:
93 return "in " + self.roomlist()
94 else:
95 return ""
96
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
97 def is_staffed(self):
81a81e1 @progrium adding errors for form validation, full notifications, and minor edit…
progrium authored
98 return len(self.staff) >= self.staff_needed()
99
100 def staff_needed(self):
4d85afa @dustball Remove staffing requirement and make members more responsible
dustball authored
101 return 0
102 # if self.estimated_size.isdigit():
103 # return int(self.estimated_size) / GUESTS_PER_STAFF
104 # else:
105 # # invalid data; just return something reasonable
106 # return 2
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
107
63d7fd2 @mdhancher Add messages about understaffed and not-yet-approved events.
mdhancher authored
108 def is_approved(self):
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
109 """Has the events team approved the event? Note: This does not
110 necessarily imply that the event is in state 'approved'."""
6b85cdb @mdhancher Add messages about understaffed and not-yet-approved events.
mdhancher authored
111 return self.status in ('understaffed', 'approved', 'cancelled')
112
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
113 def is_canceled(self):
114 return self.status == 'canceled'
115
67cc528 @dustball Fixed a few bugs
dustball authored
116 def is_onhold(self):
117 return self.status == 'onhold'
118
a67ac50 @mdhancher Add a simple admin-only event delete and undelete.
mdhancher authored
119 def is_deleted(self):
120 return self.status == 'deleted'
121
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
122 def is_past(self):
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
123 return self.end_time < local_today()
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
124
125 def start_date(self):
126 return self.start_time.date()
096bb16 Added logging to event actions
Brent Tubbs authored
127
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
128 def approve(self):
096bb16 Added logging to event actions
Brent Tubbs authored
129 user = users.get_current_user()
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
130 if self.is_staffed():
131 self.expired = None
132 self.status = 'approved'
096bb16 Added logging to event actions
Brent Tubbs authored
133 logging.info('%s approved %s' % (user.nickname, self.name))
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
134 else:
135 self.status = 'understaffed'
096bb16 Added logging to event actions
Brent Tubbs authored
136 logging.info('%s approved %s but it is still understaffed' % (user.nickname, self.name))
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
137 self.put()
096bb16 Added logging to event actions
Brent Tubbs authored
138
5ef05d9 @dustball RSVP system
dustball authored
139 def rsvp(self):
140 user = users.get_current_user()
141 if user and not self.has_rsvped():
142 rsvp = Rsvp(event=self)
143 rsvp.put()
144
145 def has_rsvped(self):
146 user = users.get_current_user()
147 if not user:
148 return False
149 for existing_rsvp in self.rsvps:
150 if existing_rsvp.user == user:
151 return True
152 return False
153
154 # Works even for logged out users
155 def can_rsvp(self):
156 if self.has_rsvped():
157 return False
158 time_till_event = self.start_time.replace(tzinfo=pytz.timezone('US/Pacific')) - datetime.now(pytz.timezone('US/Pacific'))
159 hours = time_till_event.seconds/3600+time_till_event.days*24
160 return (hours > 48)
161
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
162 def cancel(self):
096bb16 Added logging to event actions
Brent Tubbs authored
163 user = users.get_current_user()
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
164 self.status = 'canceled'
165 self.put()
72849c2 @billsaysthis added unstaff event, including email notification if event becomes un…
billsaysthis authored
166 logging.info('%s canceled %s' % (user.nickname, self.name))
096bb16 Added logging to event actions
Brent Tubbs authored
167
f8ffd89 @billsaysthis refactor lists to use singe event partial, adds contact email link in…
billsaysthis authored
168 def on_hold(self):
169 user = users.get_current_user()
170 self.status = 'onhold'
171 self.put()
172 logging.info('%s put %s on hold' % (user.nickname, self.name))
173
a67ac50 @mdhancher Add a simple admin-only event delete and undelete.
mdhancher authored
174 def delete(self):
175 user = users.get_current_user()
176 self.status = 'deleted'
177 self.put()
178 logging.info('%s deleted %s' % (user.nickname, self.name))
179
180 def undelete(self):
181 user = users.get_current_user()
182 self.status = 'pending'
183 self.put()
184 logging.info('%s undeleted %s' % (user.nickname, self.name))
185
c270f5e @mdhancher Add a simple admin-only event delete and undelete.
mdhancher authored
186 def delete(self):
187 user = users.get_current_user()
188 self.status = 'deleted'
189 self.put()
190 logging.info('%s deleted %s' % (user.nickname, self.name))
191
192 def undelete(self):
193 user = users.get_current_user()
194 self.status = 'pending'
195 self.put()
196 logging.info('%s undeleted %s' % (user.nickname, self.name))
197
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
198 def expire(self):
096bb16 Added logging to event actions
Brent Tubbs authored
199 user = users.get_current_user()
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
200 self.expired = datetime.now()
201 self.status = 'expired'
202 self.put()
096bb16 Added logging to event actions
Brent Tubbs authored
203 logging.info('%s expired %s' % (user.nickname, self.name))
204
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
205 def add_staff(self, user):
206 self.staff.append(user)
207 if self.is_staffed() and self.status == 'understaffed':
208 self.status = 'approved'
209 self.put()
096bb16 Added logging to event actions
Brent Tubbs authored
210 logging.info('%s staffed %s' % (user.nickname, self.name))
211
72849c2 @billsaysthis added unstaff event, including email notification if event becomes un…
billsaysthis authored
212 def remove_staff(self, user):
213 self.staff.remove(user)
214 if not self.is_staffed() and self.status == 'approved':
215 self.status = 'understaffed'
216 self.put()
217 logging.info('%s staffed %s' % (user.nickname, self.name))
218
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
219 def to_dict(self, summarize=False):
220 d = dict()
221 if summarize:
76eb52b @jonhull Added rooms, end_time, and status to JSON
jonhull authored
222 props = ['member', 'start_time', 'name', 'type', 'estimated_size', 'end_time', 'rooms', 'status']
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
223 else:
224 props = Event.properties().keys()
225 for prop in props:
226 if prop == 'member':
227 d[prop] = getattr(self, prop).email()
228 elif prop == 'staff':
229 d[prop] = map(lambda x: x.email(), getattr(self, prop))
230 elif prop in ['start_time', 'end_time', 'created', 'expired', 'updated']:
231 if getattr(self, prop):
232 d[prop] = getattr(self, prop).replace(tzinfo=pytz.timezone('US/Pacific')).strftime('%Y-%m-%dT%H:%M:%S')
233 else:
234 d[prop] = getattr(self, prop)
235 d['id'] = self.key().id()
236 return d
237
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
238 class Feedback(db.Model):
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
239 user = db.UserProperty(auto_current_user_add=True)
240 event = db.ReferenceProperty(Event)
241 rating = db.IntegerProperty()
63e5c31 @progrium merging and cleaning up bill's additions
progrium authored
242 comment = db.StringProperty(multiline=True)
243 created = db.DateTimeProperty(auto_now_add=True)
2ad290e @billsaysthis add logging model and obscure list view
billsaysthis authored
244
5ef05d9 @dustball RSVP system
dustball authored
245 class Rsvp(db.Model):
246 user = db.UserProperty(auto_current_user_add=True)
247 event = db.ReferenceProperty(Event, collection_name='rsvps')
248 created = db.DateTimeProperty(auto_now_add=True)
249
2ad290e @billsaysthis add logging model and obscure list view
billsaysthis authored
250 class HDLog(db.Model):
251 event = db.ReferenceProperty(Event)
252 created = db.DateTimeProperty(auto_now_add=True)
253 user = db.UserProperty(auto_current_user_add=True)
b193624 much nicer event edit logs
jonathan authored
254 description = db.TextProperty()
2ad290e @billsaysthis add logging model and obscure list view
billsaysthis authored
255
256 @classmethod
257 def get_logs_list(cls):
258 return cls.all() \
259 .order('-created')
5ef05d9 @dustball RSVP system
dustball authored
260
Something went wrong with that request. Please try again.