Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100755 532 lines (482 sloc) 24.237 kb
8414350 @billsaysthis multiline for details and notes fields
billsaysthis authored
1 import cgi
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
2 from google.appengine.ext import webapp, db
3 from google.appengine.ext.webapp import util, template
47a7f7a @progrium basic form validation, added end time, start of notifications, some fixe...
progrium authored
4 from google.appengine.api import urlfetch, memcache, users, mail
5
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
6 from django.utils import simplejson
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
7 from django.template.defaultfilters import slugify
841fefb added meaningful descriptions to ical events.
Stig Hackvan authored
8 from icalendar import Calendar, Event as CalendarEvent
b4ea292 Handler to bug pending events
Brian Klug authored
9 import logging, urllib, os
7bdb866 Let all members staff events.
Brian Klug authored
10 from pprint import pprint
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
11 from datetime import datetime, timedelta
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
12
2ad290e @billsaysthis add logging model and obscure list view
billsaysthis authored
13 from models import Event, Feedback, HDLog, ROOM_OPTIONS, PENDING_LIFETIME
c97598b @dustball Room Conflict Detection
dustball authored
14 from utils import username, human_username, set_cookie, local_today, is_phone_valid, UserRights, dojo
81a81e1 @progrium adding errors for form validation, full notifications, and minor edits t...
progrium authored
15 from notices import *
7742592 @progrium start of maintaining form state on errors
progrium authored
16
9f06c39 @casey Added RSS for upcoming events.
casey authored
17 import PyRSS2Gen
841fefb added meaningful descriptions to ical events.
Stig Hackvan authored
18 import re
7787223 restored an inscrutible but necessary pytz tzinfo quirk to the start/end...
Stig Hackvan authored
19 import pytz
9f06c39 @casey Added RSS for upcoming events.
casey authored
20
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
21 webapp.template.register_template_library('templatefilters')
22
9f06c39 @casey Added RSS for upcoming events.
casey authored
23 def event_path(event):
24 return '/event/%s-%s' % (event.key().id(), slugify(event.name))
25
219203b @dustball Cache better
dustball authored
26 class DomainCacheCron(webapp.RequestHandler):
27 def post(self):
28 noop = dojo('/groups/events',force=True)
29
30
f49797a @dustball Reminders 2.0
dustball authored
31 class ReminderCron(webapp.RequestHandler):
32 def post(self):
33 self.response.out.write("REMINDERS")
34 today = local_today()
35 # remind everyone 3 days in advance they need to show up
36 events = Event.all() \
37 .filter('status IN', ['approved']) \
38 .filter('reminded =', False) \
39 .filter('start_time <', today + timedelta(days=3))
40 for event in events:
41 self.response.out.write(event.name)
42 # only mail them if they created the event 2+ days ago
43 if event.created < today - timedelta(days=2):
44 schedule_reminder_email(event)
45 event.reminded = True
46 event.put()
47
48
e2b9558 @btubbs Fixes issue 4. Changed to jqueryUI datepicker. Replaced jquery
btubbs authored
49 class ExpireCron(webapp.RequestHandler):
47a7f7a @progrium basic form validation, added end time, start of notifications, some fixe...
progrium authored
50 def post(self):
51 # Expire events marked to expire today
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
52 today = local_today()
47a7f7a @progrium basic form validation, added end time, start of notifications, some fixe...
progrium authored
53 events = Event.all() \
54 .filter('status IN', ['pending', 'understaffed']) \
55 .filter('expired >=', today) \
56 .filter('expired <', today + timedelta(days=1))
57 for event in events:
58 event.expire()
59 notify_owner_expired(event)
f49797a @dustball Reminders 2.0
dustball authored
60
f1997e4 @christopherb Made misc style fixes
christopherb authored
61
47a7f7a @progrium basic form validation, added end time, start of notifications, some fixe...
progrium authored
62 class ExpireReminderCron(webapp.RequestHandler):
63 def post(self):
64 # Find events expiring in 10 days to warn owner
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
65 ten_days = local_today() + timedelta(days=10)
47a7f7a @progrium basic form validation, added end time, start of notifications, some fixe...
progrium authored
66 events = Event.all() \
67 .filter('status IN', ['pending', 'understaffed']) \
68 .filter('expired >=', ten_days) \
69 .filter('expired <', ten_days + timedelta(days=1))
70 for event in events:
71 notify_owner_expiring(event)
72
841fefb added meaningful descriptions to ical events.
Stig Hackvan authored
73 class ExportHandler(webapp.RequestHandler):
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
74 def get(self, format):
9c331d0 @progrium refactoring the export handler a bit
progrium authored
75 content_type, body = getattr(self, 'export_%s' % format)()
76 self.response.headers['content-type'] = content_type
77 self.response.out.write(body)
78
79 def export_json(self):
80 events = Event.get_approved_list()
81 for k in self.request.GET:
82 if self.request.GET[k] and k in ['member']:
83 value = users.User(urllib.unquote(self.request.GET[k]))
84 else:
85 value = urllib.unquote(self.request.GET[k])
86 events = events.filter('%s =' % k, value)
87 events = map(lambda x: x.to_dict(summarize=True), events)
88 return 'application/json', simplejson.dumps(events)
89
90 def export_ics(self):
9f06c39 @casey Added RSS for upcoming events.
casey authored
91 events = Event.all().filter('status IN', ['approved', 'canceled']).order('start_time')
841fefb added meaningful descriptions to ical events.
Stig Hackvan authored
92 url_base = 'http://' + self.request.headers.get('host', 'events.hackerdojo.com')
9c331d0 @progrium refactoring the export handler a bit
progrium authored
93 cal = Calendar()
94 for event in events:
95 iev = CalendarEvent()
96 iev.add('summary', event.name if event.status == 'approved' else event.name + ' (%s)' % event.status.upper())
97 # make verbose description with empty fields where information is missing
98 ev_desc = '__Status: %s\n__Member: %s\n__Type: %s\n__Estimated size: %s\n__Info URL: %s\n__Fee: %s\n__Contact: %s, %s\n__Rooms: %s\n\n__Details: %s\n\n__Notes: %s' % (
99 event.status,
100 event.owner(),
101 event.type,
102 event.estimated_size,
103 event.url,
104 event.fee,
105 event.contact_name,
106 event.contact_phone,
107 event.roomlist(),
108 event.details,
109 event.notes)
110 # then delete the empty fields with a regex
111 ev_desc = re.sub(re.compile(r'^__.*?:[ ,]*$\n*',re.M),'',ev_desc)
112 ev_desc = re.sub(re.compile(r'^__',re.M),'',ev_desc)
113 ev_url = url_base + event_path(event)
114 iev.add('description', ev_desc + '\n--\n' + ev_url)
115 iev.add('url', ev_url)
116 if event.start_time:
117 iev.add('dtstart', event.start_time.replace(tzinfo=pytz.timezone('US/Pacific')))
118 if event.end_time:
119 iev.add('dtend', event.end_time.replace(tzinfo=pytz.timezone('US/Pacific')))
120 cal.add_component(iev)
121 return 'text/calendar', cal.as_string()
122
123 def export_rss(self):
124 url_base = 'http://' + self.request.headers.get('host', 'events.hackerdojo.com')
125 events = Event.all().filter('status IN', ['approved', 'canceled']).order('start_time')
126 rss = PyRSS2Gen.RSS2(
127 title = "Hacker Dojo Events Feed",
128 link = url_base,
129 description = "Upcoming events at the Hacker Dojo in Mountain View, CA",
130 lastBuildDate = datetime.now(),
131 items = [PyRSS2Gen.RSSItem(
132 title = event.name,
133 link = url_base + event_path(event),
134 description = event.details,
135 guid = url_base + event_path(event),
136 pubDate = event.updated,
137 ) for event in events]
138 )
139 return 'application/xml', rss.to_xml()
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
140
f1997e4 @christopherb Made misc style fixes
christopherb authored
141
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
142 class EditHandler(webapp.RequestHandler):
143 def get(self, id):
144 event = Event.get_by_id(int(id))
145 user = users.get_current_user()
736390e @dustball Bug fixes & UI
dustball authored
146 show_all_nav = user
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
147 access_rights = UserRights(user, event)
148 if access_rights.can_edit:
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
149 logout_url = users.create_logout_url('/')
150 rooms = ROOM_OPTIONS
151 hours = [1,2,3,4,5,6,7,8,9,10,11,12]
152 self.response.out.write(template.render('templates/edit.html', locals()))
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
153 else:
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
154 self.response.out.write("Access denied")
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
155
156 def post(self, id):
157 event = Event.get_by_id(int(id))
158 user = users.get_current_user()
159 access_rights = UserRights(user, event)
160 if access_rights.can_edit:
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
161 try:
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
162 start_time = datetime.strptime('%s %s:%s %s' % (
163 self.request.get('date'),
164 self.request.get('start_time_hour'),
165 self.request.get('start_time_minute'),
166 self.request.get('start_time_ampm')), '%m/%d/%Y %I:%M %p')
167 end_time = datetime.strptime('%s %s:%s %s' % (
168 self.request.get('date'),
169 self.request.get('end_time_hour'),
170 self.request.get('end_time_minute'),
171 self.request.get('end_time_ampm')), '%m/%d/%Y %I:%M %p')
20c252d @dustball Fix key/index bug
dustball authored
172 conflicts = Event.check_conflict(start_time,end_time,self.request.get_all('rooms'), int(id))
c97598b @dustball Room Conflict Detection
dustball authored
173 if conflicts:
174 raise ValueError('Room conflict detected')
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
175 if not self.request.get('estimated_size').isdigit():
176 raise ValueError('Estimated number of people must be a number')
177 if not int(self.request.get('estimated_size')) > 0:
178 raise ValueError('Estimated number of people must be greater then zero')
179 if ( self.request.get( 'contact_phone' ) and not is_phone_valid( self.request.get( 'contact_phone' ) ) ):
180 raise ValueError( 'Phone number does not appear to be valid' )
181 else:
b193624 much nicer event edit logs
jonathan authored
182 log_desc = "Event edited<br />"
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
183 previous_object = Event.get_by_id(int(id))
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
184 event.name = self.request.get('name')
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
185 if (previous_object.name != event.name):
a4f9ae7 changed my mind about the italics
jonathan authored
186 log_desc = log_desc + "<strong>Title:</strong> " + previous_object.name + " to " + event.name + "<br />"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
187 event.start_time = start_time
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
188 if (previous_object.start_time != event.start_time):
a4f9ae7 changed my mind about the italics
jonathan authored
189 log_desc = log_desc + "<strong>Start time:</strong> " + str(previous_object.start_time) + " to " + str(event.start_time) + "<br />"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
190 event.end_time = end_time
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
191 if (previous_object.end_time != event.end_time):
a4f9ae7 changed my mind about the italics
jonathan authored
192 log_desc = log_desc + "<strong>End time:</strong> " + str(previous_object.end_time) + " to " + str(event.end_time) + "<br />"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
193 event.estimated_size = cgi.escape(self.request.get('estimated_size'))
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
194 if (previous_object.estimated_size != event.estimated_size):
a4f9ae7 changed my mind about the italics
jonathan authored
195 log_desc = log_desc + "<strong>Est. size:</strong> " + previous_object.estimated_size + " to " + event.estimated_size + "<br />"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
196 event.contact_name = cgi.escape(self.request.get('contact_name'))
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
197 if (previous_object.contact_name != event.contact_name):
a4f9ae7 changed my mind about the italics
jonathan authored
198 log_desc = log_desc + "<strong>Contact:</strong> " + previous_object.contact_name + " to " + event.contact_name + "<br />"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
199 event.contact_phone = cgi.escape(self.request.get('contact_phone'))
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
200 if (previous_object.contact_phone != event.contact_phone):
a4f9ae7 changed my mind about the italics
jonathan authored
201 log_desc = log_desc + "<strong>Contact phone:</strong> " + previous_object.contact_phone + " to " + event.contact_phone + "<br />"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
202 event.details = cgi.escape(self.request.get('details'))
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
203 if (previous_object.details != event.details):
a4f9ae7 changed my mind about the italics
jonathan authored
204 log_desc = log_desc + "<strong>Details:</strong> " + previous_object.details + " to " + event.details + "<br />"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
205 event.url = cgi.escape(self.request.get('url'))
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
206 if (previous_object.url != event.url):
a4f9ae7 changed my mind about the italics
jonathan authored
207 log_desc = log_desc + "<strong>Url:</strong> " + previous_object.url + " to " + event.url + "<br />"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
208 event.fee = cgi.escape(self.request.get('fee'))
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
209 if (previous_object.fee != event.fee):
a4f9ae7 changed my mind about the italics
jonathan authored
210 log_desc = log_desc + "<strong>Fee:</strong> " + previous_object.fee + " to " + event.fee + "<br />"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
211 event.notes = cgi.escape(self.request.get('notes'))
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
212 if (previous_object.notes != event.notes):
a4f9ae7 changed my mind about the italics
jonathan authored
213 log_desc = log_desc + "<strong>Notes:</strong> " + previous_object.notes + " to " + event.notes + "<br />"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
214 event.rooms = self.request.get_all('rooms')
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
215 if (previous_object.rooms != event.rooms):
6199d1a issue 11 print this page for your record
jonathan authored
216 log_desc = log_desc + "<strong>Rooms changed</strong><br />"
f35ea58 patches requested to log
jonathan authored
217 log_desc = log_desc + "<strong>Old room:</strong> " + previous_object.roomlist() + "<br />"
218 log_desc = log_desc + "<strong>New room:</strong> " + event.roomlist() + "<br />"
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
219 event.put()
8aa7c21 patch edit screen.. changed datepicker formatting to be cohesive.. fixed...
jonathan authored
220 log = HDLog(event=event,description=log_desc)
2ad290e @billsaysthis add logging model and obscure list view
billsaysthis authored
221 log.put()
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
222 self.redirect(event_path(event))
2ad290e @billsaysthis add logging model and obscure list view
billsaysthis authored
223 except ValueError, e:
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
224 error = str(e)
225 self.response.out.write(template.render('templates/error.html', locals()))
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
226 else:
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
227 self.response.out.write("Access denied")
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
228
229
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
230 class EventHandler(webapp.RequestHandler):
231 def get(self, id):
5ef05d9 @dustball RSVP system
dustball authored
232
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
233 event = Event.get_by_id(int(id))
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
234 if self.request.path.endswith('json'):
235 self.response.headers['content-type'] = 'application/json'
236 self.response.out.write(simplejson.dumps(event.to_dict()))
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
237 else:
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
238 user = users.get_current_user()
239 if user:
766e87c @christopherb Added UserRights class.
christopherb authored
240 access_rights = UserRights(user, event)
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
241 logout_url = users.create_logout_url('/')
766e87c @christopherb Added UserRights class.
christopherb authored
242
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
243 else:
244 login_url = users.create_login_url('/')
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
245 event.details = db.Text(event.details.replace('\n','<br/>'))
736390e @dustball Bug fixes & UI
dustball authored
246 show_all_nav = user
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
247 event.notes = db.Text(event.notes.replace('\n','<br/>'))
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
248 self.response.out.write(template.render('templates/event.html', locals()))
e2b9558 @btubbs Fixes issue 4. Changed to jqueryUI datepicker. Replaced jquery
btubbs authored
249
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
250 def post(self, id):
251 event = Event.get_by_id(int(id))
252 user = users.get_current_user()
766e87c @christopherb Added UserRights class.
christopherb authored
253 access_rights = UserRights(user, event)
254
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
255 state = self.request.get('state')
256 if state:
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
257 desc = ''
766e87c @christopherb Added UserRights class.
christopherb authored
258 if state.lower() == 'approve' and access_rights.can_approve:
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
259 event.approve()
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
260 desc = 'Approved event'
5ef05d9 @dustball RSVP system
dustball authored
261 if state.lower() == 'rsvp' and user:
262 event.rsvp()
b84b533 @dustball Fix one more staff logic bomb
dustball authored
263 if state.lower() == 'staff' and access_rights.can_staff:
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
264 event.add_staff(user)
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
265 desc = 'Added self as staff'
766e87c @christopherb Added UserRights class.
christopherb authored
266 if state.lower() == 'unstaff' and access_rights.can_unstaff:
72849c2 @billsaysthis added unstaff event, including email notification if event becomes under...
billsaysthis authored
267 event.remove_staff(user)
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
268 desc = 'Removed self as staff'
f8ffd89 @billsaysthis refactor lists to use singe event partial, adds contact email link in he...
billsaysthis authored
269 if state.lower() == 'onhold' and access_rights.can_cancel:
270 event.on_hold()
271 desc = 'Put event on hold'
766e87c @christopherb Added UserRights class.
christopherb authored
272 if state.lower() == 'cancel' and access_rights.can_cancel:
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
273 event.cancel()
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
274 desc = 'Cancelled event'
766e87c @christopherb Added UserRights class.
christopherb authored
275 if state.lower() == 'delete' and access_rights.is_admin:
a67ac50 @mdhancher Add a simple admin-only event delete and undelete.
mdhancher authored
276 event.delete()
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
277 desc = 'Deleted event'
766e87c @christopherb Added UserRights class.
christopherb authored
278 if state.lower() == 'undelete' and access_rights.is_admin:
a67ac50 @mdhancher Add a simple admin-only event delete and undelete.
mdhancher authored
279 event.undelete()
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
280 desc = 'Undeleted event'
766e87c @christopherb Added UserRights class.
christopherb authored
281 if state.lower() == 'expire' and access_rights.is_admin:
47a7f7a @progrium basic form validation, added end time, start of notifications, some fixe...
progrium authored
282 event.expire()
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
283 desc = 'Expired event'
47a7f7a @progrium basic form validation, added end time, start of notifications, some fixe...
progrium authored
284 if event.status == 'approved':
285 notify_owner_approved(event)
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
286 if desc != '':
287 log = HDLog(event=event,description=desc)
288 log.put()
9f06c39 @casey Added RSS for upcoming events.
casey authored
289 self.redirect(event_path(event))
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
290
f1997e4 @christopherb Made misc style fixes
christopherb authored
291
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
292 class ApprovedHandler(webapp.RequestHandler):
293 def get(self):
294 user = users.get_current_user()
295 if user:
296 logout_url = users.create_logout_url('/')
297 else:
298 login_url = users.create_login_url('/')
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
299 today = local_today()
736390e @dustball Bug fixes & UI
dustball authored
300 show_all_nav = user
47a7f7a @progrium basic form validation, added end time, start of notifications, some fixe...
progrium authored
301 events = Event.get_approved_list()
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
302 tomorrow = today + timedelta(days=1)
d63161a Add widget mode
Brian Klug authored
303 whichbase = 'base.html'
304 if self.request.get('base'):
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
305 whichbase = self.request.get('base') + '.html'
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
306 self.response.out.write(template.render('templates/approved.html', locals()))
307
f1997e4 @christopherb Made misc style fixes
christopherb authored
308
a82b43e @billsaysthis add myevents, pastevents code, refined list display on event page
billsaysthis authored
309 class MyEventsHandler(webapp.RequestHandler):
310 @util.login_required
311 def get(self):
312 user = users.get_current_user()
313 if user:
314 logout_url = users.create_logout_url('/')
315 else:
316 login_url = users.create_login_url('/')
317 events = Event.all().filter('member = ', user).order('start_time')
736390e @dustball Bug fixes & UI
dustball authored
318 show_all_nav = user
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
319 today = local_today()
a82b43e @billsaysthis add myevents, pastevents code, refined list display on event page
billsaysthis authored
320 tomorrow = today + timedelta(days=1)
321 self.response.out.write(template.render('templates/myevents.html', locals()))
322
f1997e4 @christopherb Made misc style fixes
christopherb authored
323
a82b43e @billsaysthis add myevents, pastevents code, refined list display on event page
billsaysthis authored
324 class PastHandler(webapp.RequestHandler):
325 def get(self):
326 user = users.get_current_user()
327 if user:
328 logout_url = users.create_logout_url('/')
329 else:
330 login_url = users.create_login_url('/')
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
331 today = local_today()
736390e @dustball Bug fixes & UI
dustball authored
332 show_all_nav = user
d75579f @progrium minor updates here and there to bills contributions.
progrium authored
333 events = Event.all().filter('start_time < ', today).order('-start_time')
a82b43e @billsaysthis add myevents, pastevents code, refined list display on event page
billsaysthis authored
334 self.response.out.write(template.render('templates/past.html', locals()))
335
f1997e4 @christopherb Made misc style fixes
christopherb authored
336
b4ea292 Handler to bug pending events
Brian Klug authored
337 class CronBugOwnersHandler(webapp.RequestHandler):
338 def get(self):
339 events = Event.get_pending_list()
340 for e in events:
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
341 bug_owner_pending(e)
342
343
344 class AllFutureHandler(webapp.RequestHandler):
345 def get(self):
346 user = users.get_current_user()
347 if user:
348 logout_url = users.create_logout_url('/')
349 else:
350 login_url = users.create_login_url('/')
736390e @dustball Bug fixes & UI
dustball authored
351 show_all_nav = user
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
352 events = Event.get_all_future_list()
353 today = local_today()
354 tomorrow = today + timedelta(days=1)
355 self.response.out.write(template.render('templates/all_future.html', locals()))
b4ea292 Handler to bug pending events
Brian Klug authored
356
f1997e4 @christopherb Made misc style fixes
christopherb authored
357
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
358 class PendingHandler(webapp.RequestHandler):
359 def get(self):
360 user = users.get_current_user()
361 if user:
362 logout_url = users.create_logout_url('/')
363 else:
364 login_url = users.create_login_url('/')
47a7f7a @progrium basic form validation, added end time, start of notifications, some fixe...
progrium authored
365 events = Event.get_pending_list()
736390e @dustball Bug fixes & UI
dustball authored
366 show_all_nav = user
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
367 today = local_today()
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
368 tomorrow = today + timedelta(days=1)
369 self.response.out.write(template.render('templates/pending.html', locals()))
370
f1997e4 @christopherb Made misc style fixes
christopherb authored
371
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
372 class NewHandler(webapp.RequestHandler):
fcf7602 @progrium working approval process and ical view of approved events
progrium authored
373 @util.login_required
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
374 def get(self):
375 user = users.get_current_user()
4d85afa @dustball Remove staffing requirement and make members more responsible
dustball authored
376 human = human_username(user)
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
377 if user:
378 logout_url = users.create_logout_url('/')
379 else:
380 login_url = users.create_login_url('/')
381 rooms = ROOM_OPTIONS
cb7a9d1 pull in the rules live and memcache them for 1 day on new and confirm ac...
jonathan authored
382 rules = memcache.get("rules")
383 if(rules is None):
f35065d @dustball New wiki page
dustball authored
384 rules = urlfetch.fetch("http://wiki.hackerdojo.com/api_v2/op/GetPage/page/Event+Policies/_type/html", "GET").content
cb7a9d1 pull in the rules live and memcache them for 1 day on new and confirm ac...
jonathan authored
385 memcache.add("rules", rules, 86400)
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
386 self.response.out.write(template.render('templates/new.html', locals()))
e2b9558 @btubbs Fixes issue 4. Changed to jqueryUI datepicker. Replaced jquery
btubbs authored
387
f1997e4 @christopherb Made misc style fixes
christopherb authored
388
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
389 def post(self):
390 user = users.get_current_user()
7742592 @progrium start of maintaining form state on errors
progrium authored
391 try:
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
392 start_time = datetime.strptime('%s %s:%s %s' % (
7742592 @progrium start of maintaining form state on errors
progrium authored
393 self.request.get('date'),
394 self.request.get('start_time_hour'),
395 self.request.get('start_time_minute'),
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
396 self.request.get('start_time_ampm')), '%m/%d/%Y %I:%M %p')
397 end_time = datetime.strptime('%s %s:%s %s' % (
7742592 @progrium start of maintaining form state on errors
progrium authored
398 self.request.get('date'),
399 self.request.get('end_time_hour'),
400 self.request.get('end_time_minute'),
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
401 self.request.get('end_time_ampm')), '%m/%d/%Y %I:%M %p')
c97598b @dustball Room Conflict Detection
dustball authored
402 conflicts = Event.check_conflict(start_time,end_time,self.request.get_all('rooms'))
403 if conflicts:
404 raise ValueError('Room conflict detected')
8615877 Fix validation for event size
Brian Klug authored
405 if not self.request.get('estimated_size').isdigit():
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
406 raise ValueError('Estimated number of people must be a number')
8615877 Fix validation for event size
Brian Klug authored
407 if not int(self.request.get('estimated_size')) > 0:
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
408 raise ValueError('Estimated number of people must be greater then zero')
7742592 @progrium start of maintaining form state on errors
progrium authored
409 if (end_time-start_time).days < 0:
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
410 raise ValueError('End time must be after start time')
a244c65 @dustball Bug fixes
dustball authored
411 if ( self.request.get( 'contact_phone' ) and not is_phone_valid( self.request.get( 'contact_phone' ) ) ):
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
412 raise ValueError( 'Phone number does not appear to be valid' )
7742592 @progrium start of maintaining form state on errors
progrium authored
413 else:
414 event = Event(
ca3c6dd Escaped additional fields that could be used for XSS
Christopher Biettchert authored
415 name = cgi.escape(self.request.get('name')),
7742592 @progrium start of maintaining form state on errors
progrium authored
416 start_time = start_time,
417 end_time = end_time,
ca3c6dd Escaped additional fields that could be used for XSS
Christopher Biettchert authored
418 type = cgi.escape(self.request.get('type')),
419 estimated_size = cgi.escape(self.request.get('estimated_size')),
420 contact_name = cgi.escape(self.request.get('contact_name')),
421 contact_phone = cgi.escape(self.request.get('contact_phone')),
8414350 @billsaysthis multiline for details and notes fields
billsaysthis authored
422 details = cgi.escape(self.request.get('details')),
ca3c6dd Escaped additional fields that could be used for XSS
Christopher Biettchert authored
423 url = cgi.escape(self.request.get('url')),
424 fee = cgi.escape(self.request.get('fee')),
8414350 @billsaysthis multiline for details and notes fields
billsaysthis authored
425 notes = cgi.escape(self.request.get('notes')),
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
426 rooms = self.request.get_all('rooms'),
b879063 @mdhancher Respect the local timezone (Pacific), and tidy up related imports.
mdhancher authored
427 expired = local_today() + timedelta(days=PENDING_LIFETIME), # Set expected expiration date
7742592 @progrium start of maintaining form state on errors
progrium authored
428 )
429 event.put()
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
430 log = HDLog(event=event,description="Created new event")
431 log.put()
7742592 @progrium start of maintaining form state on errors
progrium authored
432 notify_owner_confirmation(event)
433 notify_new_event(event)
81a81e1 @progrium adding errors for form validation, full notifications, and minor edits t...
progrium authored
434 set_cookie(self.response.headers, 'formvalues', None)
87868cf issue 11 add a confirmation page
jonathan authored
435 #self.redirect('/event/%s-%s' % (event.key().id(), slugify(event.name)))
436 self.redirect('/confirm/%s-%s' % (event.key().id(), slugify(event.name)))
437
81a81e1 @progrium adding errors for form validation, full notifications, and minor edits t...
progrium authored
438 except Exception, e:
439 message = str(e)
440 if 'match format' in message:
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
441 message = 'Date is required.'
81a81e1 @progrium adding errors for form validation, full notifications, and minor edits t...
progrium authored
442 if message.startswith('Property'):
443 message = message[9:].replace('_', ' ').capitalize()
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
444 # This is NOT a reliable way to handle erorrs
445 #set_cookie(self.response.headers, 'formerror', message)
446 #set_cookie(self.response.headers, 'formvalues', dict(self.request.POST))
447 #self.redirect('/new')
448 error = message
449 self.response.out.write(template.render('templates/error.html', locals()))
87868cf issue 11 add a confirmation page
jonathan authored
450
451 class ConfirmationHandler(webapp.RequestHandler):
452 def get(self, id):
453 event = Event.get_by_id(int(id))
cb7a9d1 pull in the rules live and memcache them for 1 day on new and confirm ac...
jonathan authored
454 rules = memcache.get("rules")
455 if(rules is None):
f35065d @dustball New wiki page
dustball authored
456 rules = urlfetch.fetch("http://wiki.hackerdojo.com/api_v2/op/GetPage/page/Event+Policies/_type/html", "GET").content
cb7a9d1 pull in the rules live and memcache them for 1 day on new and confirm ac...
jonathan authored
457 memcache.add("rules", rules, 86400)
87868cf issue 11 add a confirmation page
jonathan authored
458 self.response.out.write(template.render('templates/confirmation.html', locals()))
459
2ad290e @billsaysthis add logging model and obscure list view
billsaysthis authored
460 class LogsHandler(webapp.RequestHandler):
461 @util.login_required
462 def get(self):
463 user = users.get_current_user()
464 logs = HDLog.get_logs_list()
465 if user:
466 logout_url = users.create_logout_url('/')
467 else:
468 login_url = users.create_login_url('/')
736390e @dustball Bug fixes & UI
dustball authored
469 show_all_nav = user
2ad290e @billsaysthis add logging model and obscure list view
billsaysthis authored
470 self.response.out.write(template.render('templates/logs.html', locals()))
471
d2c3dc7 @billsaysthis moved app-specific js to separate file
billsaysthis authored
472 class FeedbackHandler(webapp.RequestHandler):
473 @util.login_required
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
474 def get(self, id):
d2c3dc7 @billsaysthis moved app-specific js to separate file
billsaysthis authored
475 user = users.get_current_user()
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
476 event = Event.get_by_id(int(id))
d2c3dc7 @billsaysthis moved app-specific js to separate file
billsaysthis authored
477 if user:
478 logout_url = users.create_logout_url('/')
479 else:
480 login_url = users.create_login_url('/')
481 self.response.out.write(template.render('templates/feedback.html', locals()))
482
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
483 def post(self, id):
d2c3dc7 @billsaysthis moved app-specific js to separate file
billsaysthis authored
484 user = users.get_current_user()
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
485 event = Event.get_by_id(int(id))
8c52522 @billsaysthis small tweak to how feedbacks displayed in event page
billsaysthis authored
486 try:
487 if self.request.get('rating'):
488 feedback = Feedback(
489 event = event,
490 rating = int(self.request.get('rating')),
ca3c6dd Escaped additional fields that could be used for XSS
Christopher Biettchert authored
491 comment = cgi.escape(self.request.get('comment')))
8c52522 @billsaysthis small tweak to how feedbacks displayed in event page
billsaysthis authored
492 feedback.put()
0eb5a92 @billsaysthis basic logging for all user-initiated post methods in place
billsaysthis authored
493 log = HDLog(event=event,description="Posted feedback")
494 log.put()
8c52522 @billsaysthis small tweak to how feedbacks displayed in event page
billsaysthis authored
495 self.redirect('/event/%s-%s' % (event.key().id(), slugify(event.name)))
496 else:
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
497 raise ValueError('Please select a rating')
8c52522 @billsaysthis small tweak to how feedbacks displayed in event page
billsaysthis authored
498 except Exception:
499 set_cookie(self.response.headers, 'formvalues', dict(self.request.POST))
7ebb2cd @christopherb Cleaned up the style of the files some. Mostly standardizing on single q...
christopherb authored
500 self.redirect('/feedback/new/' + id)
d2c3dc7 @billsaysthis moved app-specific js to separate file
billsaysthis authored
501
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
502 def main():
503 application = webapp.WSGIApplication([
504 ('/', ApprovedHandler),
4c7da5d @billsaysthis added func to ensure word 'in' only shown when rooms are assigned
billsaysthis authored
505 ('/all_future', AllFutureHandler),
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
506 ('/pending', PendingHandler),
841fefb added meaningful descriptions to ical events.
Stig Hackvan authored
507 ('/past', PastHandler),
b4ea292 Handler to bug pending events
Brian Klug authored
508 ('/cronbugowners', CronBugOwnersHandler),
a82b43e @billsaysthis add myevents, pastevents code, refined list display on event page
billsaysthis authored
509 ('/myevents', MyEventsHandler),
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
510 ('/new', NewHandler),
87868cf issue 11 add a confirmation page
jonathan authored
511 ('/confirm/(\d+).*', ConfirmationHandler),
ca8c7f2 @dustball Let edit events and refactor error handling
dustball authored
512 ('/edit/(\d+).*', EditHandler),
841fefb added meaningful descriptions to ical events.
Stig Hackvan authored
513 # single event views
47a7f7a @progrium basic form validation, added end time, start of notifications, some fixe...
progrium authored
514 ('/event/(\d+).*', EventHandler),
2e08a66 @progrium cleaning things up and adding json representations for jon
progrium authored
515 ('/event/(\d+)\.json', EventHandler),
841fefb added meaningful descriptions to ical events.
Stig Hackvan authored
516 # various export methods -- events.{json,rss,ics}
517 ('/events\.(.+)', ExportHandler),
518 #
519 # CRON tasks
47a7f7a @progrium basic form validation, added end time, start of notifications, some fixe...
progrium authored
520 ('/expire', ExpireCron),
34d98f0 @billsaysthis moved feedback stuff to separate py file, small tweak to email notificat...
billsaysthis authored
521 ('/expiring', ExpireReminderCron),
219203b @dustball Cache better
dustball authored
522 ('/domaincache', DomainCacheCron),
f49797a @dustball Reminders 2.0
dustball authored
523 ('/reminder', ReminderCron),
841fefb added meaningful descriptions to ical events.
Stig Hackvan authored
524 #
2ad290e @billsaysthis add logging model and obscure list view
billsaysthis authored
525 ('/logs', LogsHandler),
d2c3dc7 @billsaysthis moved app-specific js to separate file
billsaysthis authored
526 ('/feedback/new/(\d+).*', FeedbackHandler) ],debug=True)
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
527 util.run_wsgi_app(application)
528
f1997e4 @christopherb Made misc style fixes
christopherb authored
529
9b632dd @progrium initial commit -- basic form, rough listing
progrium authored
530 if __name__ == '__main__':
531 main()
Something went wrong with that request. Please try again.