Permalink
Newer
Older
100755 301 lines (264 sloc) 11.9 KB
2
from google.appengine.ext import webapp, db
3
from google.appengine.ext.webapp import util, template
4
from google.appengine.api import urlfetch, memcache, users, mail
5
6
from django.utils import simplejson
7
from django.template.defaultfilters import slugify
8
from icalendar import Calendar
9
import logging, urllib, os
10
from pprint import pprint
11
from datetime import datetime, timedelta
13
from models import Event, Feedback, ROOM_OPTIONS, PENDING_LIFETIME
@dustball
Sep 9, 2010
14
from utils import username, human_username, set_cookie, local_today, is_phone_valid, UserRights, dojo
@dustball
Sep 9, 2010
17
class DomainCacheCron(webapp.RequestHandler):
18
def post(self):
19
noop = dojo('/groups/events',force=True)
20
21
@dustball
Sep 9, 2010
22
class ReminderCron(webapp.RequestHandler):
23
def post(self):
24
self.response.out.write("REMINDERS")
25
today = local_today()
26
# remind everyone 3 days in advance they need to show up
27
events = Event.all() \
28
.filter('status IN', ['approved']) \
29
.filter('reminded =', False) \
30
.filter('start_time <', today + timedelta(days=3))
31
for event in events:
32
self.response.out.write(event.name)
33
# only mail them if they created the event 2+ days ago
34
if event.created < today - timedelta(days=2):
35
schedule_reminder_email(event)
36
event.reminded = True
37
event.put()
38
39
40
class ExpireCron(webapp.RequestHandler):
41
def post(self):
42
# Expire events marked to expire today
44
events = Event.all() \
45
.filter('status IN', ['pending', 'understaffed']) \
46
.filter('expired >=', today) \
47
.filter('expired <', today + timedelta(days=1))
48
for event in events:
49
event.expire()
50
notify_owner_expired(event)
@dustball
Sep 9, 2010
51
52
53
class ExpireReminderCron(webapp.RequestHandler):
54
def post(self):
55
# Find events expiring in 10 days to warn owner
56
ten_days = local_today() + timedelta(days=10)
57
events = Event.all() \
58
.filter('status IN', ['pending', 'understaffed']) \
59
.filter('expired >=', ten_days) \
60
.filter('expired <', ten_days + timedelta(days=1))
61
for event in events:
62
notify_owner_expiring(event)
63
64
65
class EventsHandler(webapp.RequestHandler):
66
def get(self, format):
67
if format == 'ics':
68
events = Event.all().filter('status IN', ['approved', 'canceled']).order('start_time')
69
cal = Calendar()
70
for event in events:
71
cal.add_component(event.to_ical())
72
self.response.headers['content-type'] = 'text/calendar'
73
self.response.out.write(cal.as_string())
74
elif format == 'json':
75
self.response.headers['content-type'] = 'application/json'
76
events = map(lambda x: x.to_dict(summarize=True), Event.get_approved_list())
77
self.response.out.write(simplejson.dumps(events))
79
80
class EventHandler(webapp.RequestHandler):
81
def get(self, id):
82
event = Event.get_by_id(int(id))
83
if self.request.path.endswith('json'):
84
self.response.headers['content-type'] = 'application/json'
85
self.response.out.write(simplejson.dumps(event.to_dict()))
87
user = users.get_current_user()
88
if user:
89
access_rights = UserRights(user, event)
90
logout_url = users.create_logout_url('/')
92
else:
93
login_url = users.create_login_url('/')
94
event.details = db.Text(event.details.replace('\n','<br/>'))
95
event.notes = db.Text(event.notes.replace('\n','<br/>'))
96
self.response.out.write(template.render('templates/event.html', locals()))
98
def post(self, id):
99
event = Event.get_by_id(int(id))
100
user = users.get_current_user()
101
access_rights = UserRights(user, event)
102
103
state = self.request.get('state')
104
if state:
105
if state.lower() == 'approve' and access_rights.can_approve:
107
if state.lower() == 'staff' and access_rights.can_staff:
109
if state.lower() == 'unstaff' and access_rights.can_unstaff:
111
if state.lower() == 'cancel' and access_rights.can_cancel:
113
if state.lower() == 'delete' and access_rights.is_admin:
115
if state.lower() == 'undelete' and access_rights.is_admin:
117
if state.lower() == 'expire' and access_rights.is_admin:
118
event.expire()
119
if event.status == 'approved':
120
notify_owner_approved(event)
121
self.redirect('/event/%s-%s' % (event.key().id(), slugify(event.name)))
123
124
class ApprovedHandler(webapp.RequestHandler):
125
def get(self):
126
user = users.get_current_user()
127
if user:
128
logout_url = users.create_logout_url('/')
129
else:
130
login_url = users.create_login_url('/')
132
events = Event.get_approved_list()
133
tomorrow = today + timedelta(days=1)
Jun 9, 2010
134
whichbase = 'base.html'
135
if self.request.get('base'):
136
whichbase = self.request.get('base') + '.html'
137
self.response.out.write(template.render('templates/approved.html', locals()))
138
139
140
class MyEventsHandler(webapp.RequestHandler):
141
@util.login_required
142
def get(self):
143
user = users.get_current_user()
144
if user:
145
logout_url = users.create_logout_url('/')
146
else:
147
login_url = users.create_login_url('/')
148
events = Event.all().filter('member = ', user).order('start_time')
150
tomorrow = today + timedelta(days=1)
151
self.response.out.write(template.render('templates/myevents.html', locals()))
152
153
154
class PastHandler(webapp.RequestHandler):
155
def get(self):
156
user = users.get_current_user()
157
if user:
158
logout_url = users.create_logout_url('/')
159
else:
160
login_url = users.create_login_url('/')
162
events = Event.all().filter('start_time < ', today).order('-start_time')
163
self.response.out.write(template.render('templates/past.html', locals()))
164
165
166
class CronBugOwnersHandler(webapp.RequestHandler):
167
def get(self):
168
events = Event.get_pending_list()
169
for e in events:
170
bug_owner_pending(e)
171
172
173
class PendingHandler(webapp.RequestHandler):
174
def get(self):
175
user = users.get_current_user()
176
if user:
177
logout_url = users.create_logout_url('/')
178
else:
179
login_url = users.create_login_url('/')
180
events = Event.get_pending_list()
182
tomorrow = today + timedelta(days=1)
183
self.response.out.write(template.render('templates/pending.html', locals()))
184
185
186
class NewHandler(webapp.RequestHandler):
188
def get(self):
189
user = users.get_current_user()
190
human = human_username(user)
191
if user:
192
logout_url = users.create_logout_url('/')
193
else:
194
login_url = users.create_login_url('/')
195
rooms = ROOM_OPTIONS
196
self.response.out.write(template.render('templates/new.html', locals()))
198
199
def post(self):
200
user = users.get_current_user()
202
start_time = datetime.strptime('%s %s:%s %s' % (
203
self.request.get('date'),
204
self.request.get('start_time_hour'),
205
self.request.get('start_time_minute'),
206
self.request.get('start_time_ampm')), '%m/%d/%Y %I:%M %p')
207
end_time = datetime.strptime('%s %s:%s %s' % (
208
self.request.get('date'),
209
self.request.get('end_time_hour'),
210
self.request.get('end_time_minute'),
211
self.request.get('end_time_ampm')), '%m/%d/%Y %I:%M %p')
212
if not self.request.get('estimated_size').isdigit():
213
raise ValueError('Estimated number of people must be a number')
214
if not int(self.request.get('estimated_size')) > 0:
215
raise ValueError('Estimated number of people must be greater then zero')
216
if (end_time-start_time).days < 0:
217
raise ValueError('End time must be after start time')
218
if ( not is_phone_valid( self.request.get( 'contact_phone' ) ) ):
219
raise ValueError( 'Phone number does not appear to be valid' )
220
else:
221
event = Event(
222
name = cgi.escape(self.request.get('name')),
223
start_time = start_time,
224
end_time = end_time,
225
type = cgi.escape(self.request.get('type')),
226
estimated_size = cgi.escape(self.request.get('estimated_size')),
227
contact_name = cgi.escape(self.request.get('contact_name')),
228
contact_phone = cgi.escape(self.request.get('contact_phone')),
229
details = cgi.escape(self.request.get('details')),
230
url = cgi.escape(self.request.get('url')),
231
fee = cgi.escape(self.request.get('fee')),
232
notes = cgi.escape(self.request.get('notes')),
233
rooms = self.request.get_all('rooms'),
234
expired = local_today() + timedelta(days=PENDING_LIFETIME), # Set expected expiration date
235
)
236
event.put()
237
notify_owner_confirmation(event)
238
notify_new_event(event)
239
set_cookie(self.response.headers, 'formvalues', None)
240
self.redirect('/event/%s-%s' % (event.key().id(), slugify(event.name)))
241
except Exception, e:
242
message = str(e)
243
if 'match format' in message:
245
if message.startswith('Property'):
246
message = message[9:].replace('_', ' ').capitalize()
247
set_cookie(self.response.headers, 'formerror', message)
248
set_cookie(self.response.headers, 'formvalues', dict(self.request.POST))
249
self.redirect('/new')
251
252
class FeedbackHandler(webapp.RequestHandler):
253
@util.login_required
255
user = users.get_current_user()
256
event = Event.get_by_id(int(id))
257
if user:
258
logout_url = users.create_logout_url('/')
259
else:
260
login_url = users.create_login_url('/')
261
self.response.out.write(template.render('templates/feedback.html', locals()))
262
264
user = users.get_current_user()
265
event = Event.get_by_id(int(id))
266
try:
267
if self.request.get('rating'):
268
feedback = Feedback(
269
event = event,
270
rating = int(self.request.get('rating')),
271
comment = cgi.escape(self.request.get('comment')))
272
feedback.put()
273
self.redirect('/event/%s-%s' % (event.key().id(), slugify(event.name)))
274
else:
275
raise ValueError('Please select a rating')
276
except Exception:
277
set_cookie(self.response.headers, 'formvalues', dict(self.request.POST))
278
self.redirect('/feedback/new/' + id)
280
def main():
281
application = webapp.WSGIApplication([
282
('/', ApprovedHandler),
283
('/events\.(.+)', EventsHandler),
284
('/past', PastHandler),
285
('/pending', PendingHandler),
286
('/cronbugowners', CronBugOwnersHandler),
287
('/myevents', MyEventsHandler),
288
('/new', NewHandler),
289
('/event/(\d+).*', EventHandler),
290
('/event/(\d+)\.json', EventHandler),
292
('/expiring', ExpireReminderCron),
@dustball
Sep 9, 2010
293
('/domaincache', DomainCacheCron),
@dustball
Sep 9, 2010
294
('/reminder', ReminderCron),
295
('/feedback/new/(\d+).*', FeedbackHandler) ],debug=True)
296
util.run_wsgi_app(application)
297
298
299
if __name__ == '__main__':
300
main()