Permalink
Browse files

Django-ising.

  • Loading branch information...
1 parent f3758c7 commit e2a50631084c5aa9ed45a2deddb8d5bc9d382c10 @mithro mithro committed Jul 9, 2011
Showing with 523 additions and 619 deletions.
  1. 0 __init__.py
  2. +0 −55 do_openid_login.py
  3. +0 −178 event_edit.py
  4. +0 −136 event_lists.py
  5. +0 −38 handler-admin.py
  6. +0 −54 handler.py
  7. +0 −44 index.py
  8. +14 −0 manage.py
  9. +0 −109 models.py
  10. +32 −5 settings.py
  11. +29 −0 urls.py
  12. 0 usergroup/__init__.py
  13. 0 { → usergroup}/config.py
  14. +177 −0 usergroup/event_edit.py
  15. +107 −0 usergroup/event_lists.py
  16. 0 { → usergroup}/event_publish.py
  17. 0 { → usergroup}/events.py
  18. 0 { → usergroup}/ical.py
  19. +22 −0 usergroup/index.py
  20. +120 −0 usergroup/models.py
  21. 0 { → usergroup}/offer_edit.py
  22. 0 { → usergroup}/offers.py
  23. 0 { → usergroup}/response.py
  24. 0 { → usergroup}/rss.py
  25. +5 −0 usergroup/settings.py
  26. 0 { → usergroup}/templates/base.html
  27. 0 { → usergroup}/templates/blank.html
  28. 0 { → usergroup}/templates/content-base.html
  29. 0 { → usergroup}/templates/content-template.html
  30. 0 { → usergroup}/templates/countdown.html
  31. 0 { → usergroup}/templates/editevent.html
  32. 0 { → usergroup}/templates/event.html
  33. 0 { → usergroup}/templates/events.html
  34. 0 { → usergroup}/templates/fragments/positive-multiple.html
  35. 0 { → usergroup}/templates/index.html
  36. 0 { → usergroup}/templates/login.html
  37. 0 { → usergroup}/templates/map.html
  38. 0 { → usergroup}/templates/markdown/Makefile
  39. 0 { → usergroup}/templates/markdown/slugmeeting.md
  40. 0 { → usergroup}/templates/offers.html
  41. 0 { → usergroup}/templates/offertalk.html
  42. 0 { → usergroup}/templates/refresh.html
  43. 0 { → usergroup}/templates/response-friends.html
  44. 0 { → usergroup}/templates/response-script.html
  45. 0 { → usergroup}/templates/response-show.html
  46. +16 −0 usergroup/tests.py
  47. +1 −0 usergroup/views.py
View
0 __init__.py
No changes.
View
55 do_openid_login.py
@@ -1,55 +0,0 @@
-#!/usr/bin/python
-#
-# -*- coding: utf-8 -*-
-# vim: set ts=4 sw=4 et sts=4 ai:
-
-"""OpenID login page"""
-
-import config
-config.setup()
-
-# Python imports
-
-# AppEngine Imports
-from google.appengine.ext import webapp
-from google.appengine.ext.webapp import template
-
-# Our App imports
-from google.appengine.api import users
-from google.appengine.ext import webapp
-from google.appengine.ext.webapp.util import run_wsgi_app
-
-class MainHandler(webapp.RequestHandler):
- """Handles logins via AppEngine's integrated openid support."""
-
- def handle_openid(self, continue_url=None, openid_url=None):
- """If openid provided, being the dance; else return the login form."""
- if openid_url:
- self.redirect(users.create_login_url(continue_url, None,
- openid_url))
- else:
- self.response.out.write(template.render(
- 'templates/login.html', {'continue': continue_url}))
-
- def get(self):
- """Serve the login form."""
- continue_url = self.request.get('continue')
- openid_url = self.request.get('openid_identifier')
- self.handle_openid(continue_url, openid_url)
-
- def post(self):
- """Should have an endpoint now; start the dance"""
- continue_url = self.request.get('continue')
- openid_url = self.request.get('openid_identifier')
- self.handle_openid(continue_url, openid_url)
-
-application = webapp.WSGIApplication([
- ('.*', MainHandler),
-], debug=True)
-
-def main():
- run_wsgi_app(application)
-
-if __name__ == '__main__':
- main()
-
View
178 event_edit.py
@@ -1,178 +0,0 @@
-#!/usr/bin/python
-#
-# -*- coding: utf-8 -*-
-# vim: set ts=4 sw=4 et sts=4 ai:
-
-"""Module for creating and editing Event objects."""
-
-import config
-config.setup()
-
-# Python Imports
-import os
-import os.path
-import simplejson
-import traceback
-import cStringIO as StringIO
-from datetime import datetime
-
-# AppEngine Imports
-from google.appengine.ext import webapp
-from django import template
-
-# Third Party imports
-from dateutil import rrule
-from datetime_tz import datetime_tz
-import markdown
-import logging
-
-# Our App imports
-import models
-import offers
-from utils.render import render as r
-
-
-# We don't want to wrap this line as we use a grep to extract the details
-# pylint: disable-msg=C0301
-extensions = ['abbr', 'footnotes', 'def_list', 'fenced_code', 'tables', 'subscript', 'superscript', 'slugheader', 'anyurl']
-
-
-def lastfridays():
- """Return 5 last Fridays of the month."""
- return list(x.date() for x in rrule.rrule(
- rrule.MONTHLY, interval=1, count=10, byweekday=(rrule.FR(-1)),
- dtstart=datetime.now()))
-
-
-def get_templates():
- """Get all the markdown templates."""
- ret = []
-
- directory = "templates/markdown"
- for filename in os.listdir(directory):
- if not filename.endswith('.md'):
- continue
-
- fullpath = os.path.join(directory, filename)
- name = filename.replace('.md', '')
- ret.append((name, file(fullpath).read()))
- return ret
-
-
-class AddOffer(webapp.RequestHandler):
- """Adds an offer to an event"""
-
- def post(self, key):
- if not key:
- self.redirect('/events')
- return
- event = models.Event.get(key)
- offerkey = self.request.get('id')
- offer = models.TalkOffer.get(offerkey)
-
- talk = models.LightningTalk(event=event, offer=offer)
- talk.put()
-
- self.response.headers['Content-Type'] = 'application/javascript'
- output = simplejson.dumps({'key': str(talk.key())})
- logging.debug('output: %s', output)
- self.response.out.write(output);
-
-class RemOffer(webapp.RequestHandler):
- """Removes an offer from an event."""
-
- def post(self, key):
- if not key:
- self.redirect('/events')
- return
- talkkey = self.request.get('id')
- talk = models.LightningTalk.get(talkkey)
- talk.delete()
- self.response.headers['Content-Type'] = 'application/javascript'
- output = simplejson.dumps({'deleted': str(True)})
-
-
-
-class EditEvent(webapp.RequestHandler):
- """Handler for creating and editing Event objects."""
-
- def get(self, key=None):
- # We use locals() which confuses pylint.
- # pylint: disable-msg=W0612
- if key:
- try:
- key = long(key)
- event = models.Event.get_by_id(key)
- assert event
- # pylint: disable-msg=W0702
- except (AssertionError, ValueError):
- self.redirect('/events')
- return
- else:
- event = None
-
- template_values = {}
-
- if event:
- template_values['agenda'] = offers.get_event_agenda(event)
- else:
- template_values['agenda'] = None
-
- template_values['event'] = event
- template_values['fridays'] = lastfridays()
- template_values['templates'] = get_templates()
- template_values['self'] = self
- template_values['offers'] = models.TalkOffer.all().fetch(limit=100)
-
- self.response.out.write(r(
- 'templates/editevent.html', template_values
- ))
-
- def post(self, key=None):
- event_name = self.request.get('name')
- if key:
- try:
- key = long(key)
- event = models.Event.get_by_id(key)
- event.name = event_name
- # pylint: disable-msg=W0702
- except (AssertionError, ValueError):
- self.redirect('/events')
- return
- else:
- #name is a required field; must populate now. Rest comes later.
- event = models.Event(name=event_name, text='', html='',
- start=datetime.now(), end=datetime.now())
-
- inputtext = self.request.get('input')
-
- start_date = datetime_tz.smartparse(self.request.get('start'))
- end_date = datetime_tz.smartparse(self.request.get('end'))
-
- event.input = inputtext
- event.start = start_date.asdatetime()
- event.end = end_date.asdatetime()
-
- event.put()
-
- # We can't do this template subsitution until we have saved the event.
- try:
- plaintext = str(template.Template(inputtext).render(
- template.Context({
- 'event': event,
- 'req': self.request,
- 'agenda': offers.get_event_agenda(event)
- }), ))
- html = markdown.markdown(plaintext, extensions).encode('utf-8')
- event.plaintext = plaintext
- event.html = html
- except Exception:
- sio = StringIO.StringIO()
- traceback.print_exc(file=sio)
- event.plaintext = sio.getvalue()
-
- logging.debug("e.a %s, e.n %s", event.announcement, event.name)
-
- event.put()
-
- self.redirect('%s/edit' % event.get_url())
View
136 event_lists.py
@@ -1,136 +0,0 @@
-#!/usr/bin/python
-#
-# -*- coding: utf-8 -*-
-# vim: set ts=4 sw=4 et sts=4 ai:
-
-# We have functions with loads of arguments.
-# pylint: disable-msg=R0913
-
-"""Helper module for obtaining lists of events"""
-
-import config
-config.setup()
-
-from google.appengine.ext import db
-from aeoid import users as openid
-
-import datetime
-import models
-
-def fix_responses(user):
- fedid = user.federated_identity()
- if fedid:
- openid_user_key = openid.UserInfo.get_by_identity_url(fedid)
- if openid_user_key:
- query = ("Select * from Response "
- "WHERE created_by = :1")
- resps = db.GqlQuery(query, openid_user_key)
- for resp in resps:
- resp.gcreated_by = user
- resp.put()
-
-def get_event_responses(event, user):
- response = None
- guests = []
- if user:
- fix_responses(user)
- responses = event.responses.filter("gcreated_by = ",
- user).order("created_on")
- for resp in responses:
- if not resp.guest:
- response = resp
- else:
- guests.append(resp)
- return response, guests
-
-
-def get_eventlist_responses(event_list, user):
- events = []
- for event in event_list:
- response, guests = get_event_responses(event, user)
- events.append( (event, response, guests) )
-
- return events
-
-
-def get_future_events(
- year=None, month=None, day=None, published_only=True, user=None,
- count=100):
- now = datetime.datetime.now()
-
- year = year or now.year
- month = month or now.month
- day = day or now.day
-
- query = ("SELECT * from Event "
- "WHERE start > DATETIME(:1, :2, :3, 23, 59, 59) ")
- if published_only:
- query += "AND published = True "
- query += "ORDER BY start"
-
- future_events = db.GqlQuery(query, year, month, day).fetch(count)
-
- return EventList(get_eventlist_responses(
- future_events, user), "Coming soon")
-
-def get_current_events(
- year=None, month=None, day=None, published_only=True, user=None,
- count=5):
- now = datetime.datetime.now()
-
- year = year or now.year
- month = month or now.month
- day = day or now.day
-
- query = ("SELECT * from Event "
- "WHERE end >= DATETIME(:1, :2, :3, 00, 00, 00) "
- "AND end <= DATETIME(:1, :2, :3, 23, 59, 59) ")
- if published_only:
- query += "AND published = True "
- query += "ORDER BY end"
-
- current_events = db.GqlQuery(query, year, month, day).fetch(count)
-
- return EventList(get_eventlist_responses(
- current_events, user), "Happening today")
-
-def get_next_event(year=None, month=None, day=None, hour=None, minute=None,
- second=None):
- now = datetime.datetime.now()
-
- year = year or now.year
- month = month or now.month
- day = day or now.day
- hour = hour or now.hour
- minute = minute or now.minute
- second = second or now.second
-
- next_event = db.GqlQuery(
- "SELECT * from Event " +
- "WHERE start >= DATETIME(:1, :2, :3, :4, :5, :6) " +
- "ORDER BY start", year, month, day, hour, minute, second).get()
-
- return next_event
-
-def get_event_lists(year=None, month=None, day=None, hour=None, minute=None,
- second=None, published_only=True, user=None):
-
- event_lists = []
- event_lists.append(
- get_current_events(year, month, day, published_only, user))
- event_lists.append(
- get_future_events(year, month, day, published_only, user))
-
- return event_lists
-
-
-class EventList(object):
- """A named list of events.
-
- Arguments:
- events: list of events
- name: a name """
-
- def __init__(self, events, name):
- self.events = events
- self.name = name
View
38 handler-admin.py
@@ -1,38 +0,0 @@
-#!/usr/bin/python
-#
-# -*- coding: utf-8 -*-
-# vim: set ts=4 sw=4 et sts=4 ai:
-
-"""Default handler for admin pages."""
-
-import os
-import config
-config.setup(os.environ.get('HTTP_HOST', None))
-
-# AppEngine imports
-from google.appengine.ext import webapp
-from google.appengine.ext.webapp.util import run_wsgi_app
-
-# OpenID middleware
-import aeoid.middleware
-
-# Import the actual handlers
-import event_edit
-import event_publish
-
-application = webapp.WSGIApplication(
- [('/event/add', event_edit.EditEvent),
- ('/event/(.*)/edit', event_edit.EditEvent),
- ('/event/(.*)/addoffer', event_edit.AddOffer),
- ('/event/(.*)/remoffer', event_edit.RemOffer),
- ('/event/(.*)/publish', event_publish.PublishEvent),
- ('/event/(.*)/email', event_publish.SendEmailAboutEvent),
- ],
- debug=True)
-
-def main():
- run_wsgi_app(application)
-
-
-if __name__ == "__main__":
- main()
View
54 handler.py
@@ -1,54 +0,0 @@
-#!/usr/bin/python
-#
-# -*- coding: utf-8 -*-
-# vim: set ts=4 sw=4 et sts=4 ai:
-
-"""Default handler."""
-
-import os
-import config
-config.setup(os.environ.get('HTTP_HOST', None))
-
-# AppEngine imports
-from google.appengine.ext import webapp
-from google.appengine.ext.webapp.util import run_wsgi_app
-
-# Import the actual handlers
-import index
-import response
-import events
-import offer_edit
-import offers
-import ical
-import rss
-
-application = webapp.WSGIApplication(
- [('/', index.Index),
- ('/event/next', events.Next),
- ('/ical[/]?(?P<key>[^\.]*)(?:.ics)?', ical.iCal),
- ('/event[/]?(?P<key>[^\.]*)(?:.ics)', ical.iCal),
- ('/event/ical', ical.iCal),
- ('/rss', rss.RSSHandler),
- ('/\d*/.*feed.*', rss.RSSHandler),
- ('/full/.*feed.*', rss.RSSHandler),
- ('/event/.*feed.*', rss.RSSHandler),
- ('/event/(.*)/response/show', response.ShowResponsePage),
- ('/event/(.*)/response/update', response.UpdateResponsePage),
- ('/events[/]?(?P<year>[^/]*)[/]?(?P<month>[^/]*)[/]?(?P<day>[^/]*)[/]?',
- events.Events),
- ('/event/(.*)', events.Event),
- ('/offer/(.*)/edit', offer_edit.EditOffer),
- ('/talks', offer_edit.EditOffer),
- ('/offer/add', offer_edit.EditOffer),
- ('/offers', offers.Offers),
- ('/refresh', index.Refresh),
- ('/(.*)', index.StaticTemplate),
- ],
- debug=True)
-
-def main():
- run_wsgi_app(application)
-
-
-if __name__ == "__main__":
- main()
View
44 index.py
@@ -1,44 +0,0 @@
-#!/usr/bin/python
-#
-# -*- coding: utf-8 -*-
-# vim: set ts=4 sw=4 et sts=4 ai:
-
-"""Simple pages."""
-
-# Python imports
-import os
-
-# AppEngine Imports
-from google.appengine.ext import webapp
-
-# Our App imports
-import events
-from utils.render import render as r
-
-
-class Index(events.Events):
- """Handler for index page."""
- published_only = True
- template = "templates/index.html"
-
-
-class Refresh(webapp.RequestHandler):
- """Handler for a page which causes the parent to refresh.
-
- Redirect to this page when an iFrame needs the containing page to reload,
- such as after a success login attempt.
- """
- def get(self):
- self.response.headers['Content-Type'] = 'text/html'
- self.response.out.write(r('templates/refresh.html', locals()))
-
-
-class StaticTemplate(webapp.RequestHandler):
- """Handler which shows a map of how to get to slug."""
- def get(self, filename):
- template = 'templates/%s.html' % filename
- if os.path.exists(template):
- self.response.headers['Content-Type'] = 'text/html'
- self.response.out.write(r(template, locals()))
- else:
- self.redirect('/')
View
14 manage.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+from django.core.management import execute_manager
+import imp
+try:
+ imp.find_module('settings') # Assumed to be in the same directory.
+except ImportError:
+ import sys
+ sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n" % __file__)
+ sys.exit(1)
+
+import settings
+
+if __name__ == "__main__":
+ execute_manager(settings)
View
109 models.py
@@ -1,109 +0,0 @@
-#!/usr/bin/python
-#
-# -*- coding: utf-8 -*-
-# vim: set ts=4 sw=4 et sts=4 ai:
-
-"""Module contains the models of objects used in the application."""
-
-import config
-config.setup()
-
-from google.appengine.ext import db
-from google.appengine.api import users
-from aeoid import users as openid
-
-class Announcement(db.Model):
- """An announcement for an event."""
- created_by = db.UserProperty(
- auto_current_user_add=True)
- created_on = db.DateTimeProperty(
- auto_now_add=True, required=True)
-
- name = db.StringProperty(required=True)
- plaintext = db.TextProperty()
- html = db.BlobProperty()
-
- published_by = db.UserProperty(
- auto_current_user_add=True, required=True)
- published_on = db.DateTimeProperty(
- auto_now_add=True, required=True)
-
-
-class Event(db.Model):
- """An event."""
-
- def get_url(self):
- """Return the canonical url for an event."""
- return "/event/%s" % self.key().id()
-
- created_by = db.UserProperty(
- auto_current_user_add=True, required=True)
- created_on = db.DateTimeProperty(
- auto_now_add=True, required=True)
-
- name = db.StringProperty(required=True)
- input = db.TextProperty()
- plaintext = db.TextProperty()
- html = db.BlobProperty()
-
- published = db.BooleanProperty(default=False)
- announcement = db.ReferenceProperty(Announcement)
-
- emailed = db.BooleanProperty(default=False)
-
- start = db.DateTimeProperty(required=True)
- end = db.DateTimeProperty(required=True)
-
-
-class TalkOffer(db.Model):
- """An lightning talk to be given at an event."""
-
- def get_url(self):
- """Return the canonical url for an event."""
- return "/offer/%s/edit" % self.key().id()
-
- created_by = db.UserProperty(
- auto_current_user_add=True, required=True)
- created_on = db.DateTimeProperty(
- auto_now_add=True, required=True)
-
- displayname = db.StringProperty()
- contactinfo = db.StringProperty()
- title = db.StringProperty(required=True)
- active = db.BooleanProperty(required=True,default=True)
- text = db.TextProperty()
- minutes = db.IntegerProperty()
- consent = db.BooleanProperty()
-
-
-class LightningTalk(db.Model):
- created_by = db.UserProperty(
- auto_current_user_add=True, required=True)
- created_on = db.DateTimeProperty(
- auto_now_add=True, required=True)
-
- weight = db.IntegerProperty(default=100, required=True)
- offer = db.ReferenceProperty(TalkOffer, required=True,
- collection_name='events')
- event = db.ReferenceProperty(Event, required=True,
- collection_name='agenda')
-
-class Response(db.Model):
- """An RSVP to attend an event."""
- created_by = openid.UserProperty()
- gcreated_by = db.UserProperty()
- created_on = db.DateTimeProperty(
- auto_now_add=True, required=True)
-
- event = db.ReferenceProperty(Event, collection_name="responses")
-
- attending = db.BooleanProperty(required=True, default=True)
-
- # Should the response be hidden from everyone?
- #hide = db.BoolenProperty(required=False, default=False)
-
- # If this is a guest, then we store their details here, otherwise we just
- # use the creater's details.
- guest = db.BooleanProperty(required=True, default=False)
- guest_name = db.StringProperty()
- guest_email = db.EmailProperty()
View
37 settings.py 100644 → 100755
@@ -1,5 +1,32 @@
-"""Django settings."""
-# pylint: disable-msg=C0103
-DEBUG = False
-DEFAULT_FROM_EMAIL = 'webmaster@slug.org.au'
-TEMPLATE_DIRS = ()
+from djangoappengine.settings_base import *
+
+import os
+
+SECRET_KEY = '=my-secret-key'
+
+INSTALLED_APPS = (
+ 'djangoappengine',
+ 'djangotoolbox',
+ 'django.contrib.auth',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'usergroup',
+)
+
+MIDDLEWARE_CLASSES = (
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+)
+
+TEMPLATE_CONTEXT_PROCESSORS = (
+ 'django.contrib.auth.context_processors.auth',
+ 'django.core.context_processors.request',
+)
+
+LOGIN_REDIRECT_URL = '/usergroup/'
+
+ADMIN_MEDIA_PREFIX = '/media/admin/'
+MEDIA_ROOT = os.path.join(os.path.dirname(__file__), 'media')
+TEMPLATE_DIRS = (os.path.join(os.path.dirname(__file__), 'templates'),)
+
+ROOT_URLCONF = 'urls'
View
29 urls.py
@@ -0,0 +1,29 @@
+from django.conf.urls.defaults import patterns, include, url
+from django.contrib.auth.forms import AuthenticationForm
+
+# Uncomment the next two lines to enable the admin:
+# from django.contrib import admin
+# admin.autodiscover()
+
+urlpatterns = patterns('',
+ (r'^$', 'django.views.generic.simple.redirect_to', {'url': '/usergroup/',}),
+ (r'^usergroup/', include('usergroup.urls')),
+
+ # auth specific urls
+ (r'^accounts/create_user/$', 'usergroup.views.create_new_user'),
+ (r'^accounts/login/$', 'django.contrib.auth.views.login',
+ {'authentication_form': AuthenticationForm,
+ 'template_name': 'usergroup/login.html',}),
+ (r'^accounts/logout/$', 'django.contrib.auth.views.logout',
+ {'next_page': '/usergroup/',}),
+
+ # Examples:
+ # url(r'^$', 'slug.views.home', name='home'),
+ # url(r'^slug/', include('slug.foo.urls')),
+
+ # Uncomment the admin/doc line below to enable admin documentation:
+ # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
+
+ # Uncomment the next line to enable the admin:
+ # url(r'^admin/', include(admin.site.urls)),
+)
View
0 usergroup/__init__.py
No changes.
View
0 config.py → usergroup/config.py
File renamed without changes.
View
177 usergroup/event_edit.py
@@ -0,0 +1,177 @@
+#!/usr/bin/python
+#
+# -*- coding: utf-8 -*-
+# vim: set ts=4 sw=4 et sts=4 ai:
+
+"""Module for creating and editing Event objects."""
+
+# Python Imports
+import os
+import os.path
+import simplejson
+import traceback
+import cStringIO as StringIO
+from datetime import datetime
+
+# Django Imports
+
+# Third Party imports
+from dateutil import rrule
+from datetime_tz import datetime_tz
+import markdown
+import logging
+
+# Our App imports
+from usergroup import models
+from usergroup import offers
+
+
+# We don't want to wrap this line as we use a grep to extract the details
+# pylint: disable-msg=C0301
+extensions = ['abbr', 'footnotes', 'def_list', 'fenced_code', 'tables', 'subscript', 'superscript', 'slugheader', 'anyurl']
+
+
+def lastfridays():
+ """Return 5 last Fridays of the month."""
+ return list(x.date() for x in rrule.rrule(
+ rrule.MONTHLY, interval=1, count=10, byweekday=(rrule.FR(-1)),
+ dtstart=datetime.now()))
+
+
+def get_templates():
+ """Get all the markdown templates."""
+ ret = []
+
+ directory = "templates/markdown"
+ for filename in os.listdir(directory):
+ if not filename.endswith('.md'):
+ continue
+
+ fullpath = os.path.join(directory, filename)
+ name = filename.replace('.md', '')
+ ret.append((name, file(fullpath).read()))
+ return ret
+
+
+@require_POST
+def handler_add_offer(request):
+ """Adds an offer to an event"""
+
+ # /events/<key>/addoffer?id=<offerid> (POST)
+ try:
+ unused_events, key, unused_addoffer = request.path_info.split('/')
+ except IndexError:
+ return shortcuts.redirect('/events')
+
+ event = shortcuts.get_object_or_404(models.Event, pk=key)
+
+ offer = shortcuts.get_object_or_404(
+ models.TalkOffer, pk=request.POST.get('id', -1))
+
+ talk = models.LightningTalk(event=event, offer=offer)
+ talk.save()
+
+ response = http.HttpResponse()
+ response['Content-Type'] = 'application/javascript'
+ response.write(simplejson.dumps({'key': str(talk.key())}))
+
+
+@require_POST
+def handler_remove_offer(request):
+ """Removes an offer from an event."""
+
+ # /events/<key>/removeoffer?id=<offerid> (POST)
+ try:
+ unused_events, key, unused_addoffer = request.path_info.split('/')
+ except IndexError:
+ return shortcuts.redirect('/events')
+
+ event = shortcuts.get_object_or_404(models.Event, pk=key)
+
+ talk = shortcuts.get_object_or_404(
+ models.LightningTalk, pk=request.POST.get('id', -1))
+
+ assert talk.event == event
+
+ talk.delete()
+
+ response = http.HttpResponse()
+ response['Content-Type'] = 'application/javascript'
+ response.write(simplejson.dumps({'deleted': str(True)}))
+
+
+@require_http_methods(["GET", "POST"])
+def handler_edit_event(request):
+ """Handler for creating and editing Event objects."""
+
+ # /events/<key> (POST/Get)
+ # /events/add (POST/Get)
+ try:
+ unused_events, key = request.path_info.split('/')
+ except IndexError:
+ return shortcuts.redirect('/events')
+
+ if key == 'add':
+ event = models.Event()
+ else:
+ event = shortcuts.get_object_or_404(models.Event, pk=key)
+
+ if request.method == 'GET':
+ return handler_edit_event_post(request, event)
+ elif request.method == 'POST':
+ return handler_edit_eveit_get(request, event)
+
+
+@require_GET
+def handler_edit_event_get(request, key):
+
+ template_values = {}
+ if event:
+ template_values['agenda'] = offers.get_event_agenda(event)
+ else:
+ template_values['agenda'] = None
+
+ template_values['event'] = event
+ template_values['fridays'] = lastfridays()
+ template_values['templates'] = get_templates()
+ template_values['self'] = self
+ template_values['offers'] = models.TalkOffer.objects.all()[:100]
+
+ response.out.write(r(
+ 'templates/editevent.html', template_values
+ ))
+
+
+@require_POST
+def handler_edit_event_post(request, event):
+
+ start_date = datetime_tz.smartparse(request.REQUEST['start'])
+ end_date = datetime_tz.smartparse(request.REQUEST['end'])
+
+ event.input = request.REQUEST['input']
+ event.start = start_date.asdatetime()
+ event.end = end_date.asdatetime()
+
+ event.save()
+
+ # We can't do this template subsitution until we have saved the event.
+ try:
+ plaintext = str(template.Template(inputtext).render(
+ template.Context({
+ 'event': event,
+ 'req': request,
+ 'agenda': offers.get_event_agenda(event)
+ }), ))
+ html = markdown.markdown(plaintext, extensions).encode('utf-8')
+ event.plaintext = plaintext
+ event.html = html
+ except Exception:
+ sio = StringIO.StringIO()
+ traceback.print_exc(file=sio)
+ event.plaintext = sio.getvalue()
+
+ logging.debug("e.a %s, e.n %s", event.announcement, event.name)
+
+ event.save()
+
+ return django.shortcuts.redirect('%s/edit' % event.get_url())
View
107 usergroup/event_lists.py
@@ -0,0 +1,107 @@
+#!/usr/bin/python
+#
+# -*- coding: utf-8 -*-
+# vim: set ts=4 sw=4 et sts=4 ai:
+
+# We have functions with loads of arguments.
+# pylint: disable-msg=R0913
+
+"""Helper module for obtaining lists of events"""
+
+from usergroup import models
+
+
+def get_date(**kw):
+ date = datetime.datetime.now()
+ date.replace(**kw)
+ return date
+
+
+def get_event_responses(event, user):
+ response = None
+ guests = []
+ if user:
+ responses = models.Response.objects.all()
+ responses.filter(event__extact=event)
+ responses.filter(created_by__extact=user)
+ for resp in responses:
+ if not resp.guest:
+ response = resp
+ else:
+ guests.append(resp)
+ return response, guests
+
+
+def get_eventlist_responses(event_list, user):
+ events = []
+ for event in event_list:
+ response, guests = get_event_responses(event, user)
+ events.append((event, response, guests))
+
+ return events
+
+
+def get_future_events(published_only=True, user=None, count=100, **kw):
+
+ events = models.Event.objects.all()
+ events.filter(start__gte=get_date(**kw))
+ if published_only:
+ events.filter(published__exact=True)
+ events.order_by('start')
+
+ future_events = events[0:count]
+
+ return EventList(get_eventlist_responses(
+ future_events, user), "Coming soon")
+
+
+def get_current_events(published_only=True, user=None, count=5, **kw):
+
+ date = get_date(**kw)
+
+ events = models.Event.objects.all()
+ events.filter(start__gte=date.replace(hour=0, minute=0, second=0))
+ events.filter(start__lte=date.replace(hour=23, minute=59, second=59))
+ if published_only:
+ events.filter(published__exact=True)
+ events.order_by('end')
+
+ current_events = events[0:count]
+
+ return EventList(get_eventlist_responses(
+ current_events, user), "Happening today")
+
+
+def get_next_event(**kw):
+
+ date = get_date(**kw)
+
+ events = models.Event.objects.all()
+ events.filter(start__gte=get_date(**kw))
+ events.filter(published__exact=True)
+ events.order_by('start')
+
+ return events[0:1]
+
+
+def get_event_lists(published_only=True, user=None):
+
+ event_lists = []
+ event_lists.append(
+ get_current_events(year, month, day, published_only, user))
+ event_lists.append(
+ get_future_events(year, month, day, published_only, user))
+
+ return event_lists
+
+
+class EventList(object):
+ """A named list of events.
+
+ Arguments:
+ events: list of events
+ name: a name """
+
+ def __init__(self, events, name):
+ self.events = events
+ self.name = name
View
0 event_publish.py → usergroup/event_publish.py
File renamed without changes.
View
0 events.py → usergroup/events.py
File renamed without changes.
View
0 ical.py → usergroup/ical.py
File renamed without changes.
View
22 usergroup/index.py
@@ -0,0 +1,22 @@
+#!/usr/bin/python
+#
+# -*- coding: utf-8 -*-
+# vim: set ts=4 sw=4 et sts=4 ai:
+
+"""Simple pages."""
+
+# Python imports
+import os
+
+# AppEngine Imports
+from google.appengine.ext import webapp
+
+# Our App imports
+import events
+from utils.render import render as r
+
+
+class Index(events.Events):
+ """Handler for index page."""
+ published_only = True
+ template = "templates/index.html"
View
120 usergroup/models.py
@@ -0,0 +1,120 @@
+#!/usr/bin/python
+#
+# -*- coding: utf-8 -*-
+# vim: set ts=4 sw=4 et sts=4 ai:
+
+"""Module contains the models of objects used in the application."""
+
+#import config
+#config.setup()
+
+from django.db import models
+from django.contrib.auth.models import User
+
+
+def get_current_user():
+ pass
+
+
+class Announcement(models.Model):
+ """An announcement for an event."""
+
+ def __unicode__(self):
+ return u'%s' % self.name
+
+ created_by = models.ForeignKey(User)
+ created_on = models.DateTimeField(
+ auto_now_add=True)
+
+ name = models.CharField(max_length=250, blank=False)
+ plaintext = models.TextField()
+ html = models.TextField()
+
+ published_by = models.ForeignKey(
+ User, default=get_current_user, blank=False)
+ published_on = models.DateTimeField(
+ auto_now_add=True, blank=False)
+
+
+class Event(models.Model):
+ """An event."""
+
+ def get_url(self):
+ """Return the canonical url for an event."""
+ return "/event/%s" % self.key().id()
+
+ def __unicode__(self):
+ return u'%s' % self.name
+
+ created_by = models.ForeignKey(
+ User, default=get_current_user, blank=False)
+ created_on = models.DateTimeField(
+ auto_now_add=True, blank=False)
+
+ name = models.CharField(max_length=250, blank=False)
+ input = models.TextField()
+ plaintext = models.TextField()
+ html = models.TextField()
+
+ published = models.BooleanField(default=False)
+ announcement = models.ForeignKey(Announcement)
+
+ emailed = models.BooleanField(default=False)
+
+ start = models.DateTimeField(blank=False)
+ end = models.DateTimeField(blank=False)
+
+
+class TalkOffer(models.Model):
+ """An lightning talk to be given at an event."""
+
+ def get_url(self):
+ """Return the canonical url for an event."""
+ return "/offer/%s/edit" % self.key().id()
+
+ created_by = models.ForeignKey(
+ User, default=get_current_user, blank=False)
+ created_on = models.DateTimeField(
+ auto_now_add=True, blank=False)
+
+ displayname = models.TextField()
+ contactinfo = models.TextField()
+ title = models.CharField(max_length=250, blank=False)
+ active = models.BooleanField(blank=False,default=True)
+ text = models.TextField()
+ minutes = models.IntegerField()
+ consent = models.BooleanField()
+
+
+class LightningTalk(models.Model):
+ created_by = models.ForeignKey(
+ User, default=get_current_user, blank=False)
+ created_on = models.DateTimeField(
+ auto_now_add=True, blank=False)
+
+ weight = models.IntegerField(default=100, blank=False)
+ offer = models.ForeignKey(TalkOffer, blank=False,
+ related_name='events')
+ event = models.ForeignKey(Event, blank=False,
+ related_name='agenda')
+
+
+class Response(models.Model):
+ """An RSVP to attend an event."""
+ created_by = models.ForeignKey(
+ User, default=get_current_user, blank=False)
+ created_on = models.DateTimeField(
+ auto_now_add=True, blank=False)
+
+ event = models.ForeignKey(Event, related_name="responses")
+
+ attending = models.BooleanField(blank=False, default=True)
+
+ # Should the response be hidden from everyone?
+ #hide = models.BoolenProperty(blank=False, default=False)
+
+ # If this is a guest, then we store their details here, otherwise we just
+ # use the creater's details.
+ guest = models.BooleanField(blank=False, default=False)
+ guest_name = models.TextField()
+ guest_email = models.EmailField()
View
0 offer_edit.py → usergroup/offer_edit.py
File renamed without changes.
View
0 offers.py → usergroup/offers.py
File renamed without changes.
View
0 response.py → usergroup/response.py
File renamed without changes.
View
0 rss.py → usergroup/rss.py
File renamed without changes.
View
5 usergroup/settings.py
@@ -0,0 +1,5 @@
+"""Django settings."""
+# pylint: disable-msg=C0103
+DEBUG = False
+DEFAULT_FROM_EMAIL = 'webmaster@slug.org.au'
+TEMPLATE_DIRS = ()
View
0 templates/base.html → usergroup/templates/base.html
File renamed without changes.
View
0 templates/blank.html → usergroup/templates/blank.html
File renamed without changes.
View
0 templates/content-base.html → usergroup/templates/content-base.html
File renamed without changes.
View
0 templates/content-template.html → usergroup/templates/content-template.html
File renamed without changes.
View
0 templates/countdown.html → usergroup/templates/countdown.html
File renamed without changes.
View
0 templates/editevent.html → usergroup/templates/editevent.html
File renamed without changes.
View
0 templates/event.html → usergroup/templates/event.html
File renamed without changes.
View
0 templates/events.html → usergroup/templates/events.html
File renamed without changes.
View
0 templates/fragments/positive-multiple.html → ...emplates/fragments/positive-multiple.html
File renamed without changes.
View
0 templates/index.html → usergroup/templates/index.html
File renamed without changes.
View
0 templates/login.html → usergroup/templates/login.html
File renamed without changes.
View
0 templates/map.html → usergroup/templates/map.html
File renamed without changes.
View
0 templates/markdown/Makefile → usergroup/templates/markdown/Makefile
File renamed without changes.
View
0 templates/markdown/slugmeeting.md → usergroup/templates/markdown/slugmeeting.md
File renamed without changes.
View
0 templates/offers.html → usergroup/templates/offers.html
File renamed without changes.
View
0 templates/offertalk.html → usergroup/templates/offertalk.html
File renamed without changes.
View
0 templates/refresh.html → usergroup/templates/refresh.html
File renamed without changes.
View
0 templates/response-friends.html → usergroup/templates/response-friends.html
File renamed without changes.
View
0 templates/response-script.html → usergroup/templates/response-script.html
File renamed without changes.
View
0 templates/response-show.html → usergroup/templates/response-show.html
File renamed without changes.
View
16 usergroup/tests.py
@@ -0,0 +1,16 @@
+"""
+This file demonstrates writing tests using the unittest module. These will pass
+when you run "manage.py test".
+
+Replace this with more appropriate tests for your application.
+"""
+
+from django.test import TestCase
+
+
+class SimpleTest(TestCase):
+ def test_basic_addition(self):
+ """
+ Tests that 1 + 1 always equals 2.
+ """
+ self.assertEqual(1 + 1, 2)
View
1 usergroup/views.py
@@ -0,0 +1 @@
+# Create your views here.

0 comments on commit e2a5063

Please sign in to comment.