annotate gpp/gcalendar/models.py @ 505:a5d11471d031

Refactor the logic in the rate limiter decorator. Check to see if the request was ajax, as the ajax view always returns 200. Have to decode the JSON response to see if an error occurred or not.
author Brian Neal <bgneal@gmail.com>
date Sat, 03 Dec 2011 19:13:38 +0000
parents 9a4bffdf37c3
children 368d731af479
rev   line source
gremmie@1 1 """
gremmie@1 2 Models for the gcalendar application.
bgneal@456 3
gremmie@1 4 """
bgneal@458 5 import datetime
bgneal@458 6
gremmie@1 7 from django.db import models
gremmie@1 8 from django.db.models import Q
gremmie@1 9 from django.contrib.auth.models import User
bgneal@124 10
bgneal@128 11 from core.markup import site_markup
bgneal@228 12 import forums.tools
bgneal@458 13 from gcalendar.oauth import serialize_token, deserialize_token
gremmie@1 14
gremmie@1 15
bgneal@228 16 GIG_FORUM_SLUG = "gigs"
bgneal@228 17
gremmie@1 18 class PendingEventManager(models.Manager):
gremmie@1 19 """A manager for pending events."""
gremmie@1 20
gremmie@1 21 def get_query_set(self):
gremmie@1 22 """Returns a queryset of events that have been approved to update
gremmie@1 23 the Google calendar."""
gremmie@1 24 return super(PendingEventManager, self).get_query_set().filter(
bgneal@456 25 Q(status=Event.NEW_APRV) |
bgneal@456 26 Q(status=Event.EDIT_APRV) |
gremmie@1 27 Q(status=Event.DEL_APRV)
gremmie@1 28 )
gremmie@1 29
gremmie@1 30
gremmie@1 31 class Event(models.Model):
gremmie@1 32 """Model to represent calendar events."""
gremmie@1 33
gremmie@1 34 # Event status codes:
gremmie@1 35 (NEW, NEW_APRV, EDIT_REQ, EDIT_APRV, DEL_REQ, DEL_APRV, ON_CAL) = range(7)
gremmie@1 36
gremmie@1 37 STATUS_CHOICES = (
gremmie@1 38 (NEW, 'New'),
gremmie@1 39 (NEW_APRV, 'New Approved'),
gremmie@1 40 (EDIT_REQ, 'Edit Request'),
gremmie@1 41 (EDIT_APRV, 'Edit Approved'),
gremmie@1 42 (DEL_REQ, 'Delete Request'),
gremmie@1 43 (DEL_APRV, 'Delete Approved'),
gremmie@1 44 (ON_CAL, 'On Calendar'),
gremmie@1 45 )
gremmie@1 46
gremmie@1 47 user = models.ForeignKey(User)
gremmie@1 48 what = models.CharField(max_length=255)
gremmie@1 49 start_date = models.DateField()
gremmie@1 50 start_time = models.TimeField(null=True, blank=True)
gremmie@1 51 end_date = models.DateField()
gremmie@1 52 end_time = models.TimeField(null=True, blank=True)
gremmie@1 53 time_zone = models.CharField(max_length=64, blank=True)
gremmie@1 54 all_day = models.BooleanField(default=False)
gremmie@1 55 where = models.CharField(max_length=255, blank=True)
gremmie@1 56 description = models.TextField(blank=True)
gremmie@1 57 html = models.TextField(blank=True)
gremmie@1 58 date_submitted = models.DateTimeField(auto_now_add=True)
gremmie@1 59 google_id = models.CharField(max_length=255, blank=True)
bgneal@228 60 google_url = models.URLField(verify_exists=False, max_length=255,
bgneal@228 61 blank=True)
bgneal@228 62 status = models.SmallIntegerField(choices=STATUS_CHOICES, default=NEW,
bgneal@228 63 db_index=True)
bgneal@228 64 create_forum_thread = models.BooleanField(default=False)
gremmie@1 65
gremmie@1 66 objects = models.Manager()
gremmie@1 67 pending_events = PendingEventManager()
gremmie@1 68
gremmie@1 69 def __unicode__(self):
gremmie@1 70 return self.what
gremmie@1 71
gremmie@1 72 class Meta:
gremmie@1 73 ordering = ('-date_submitted', )
gremmie@1 74
gremmie@1 75 def save(self, *args, **kwargs):
bgneal@128 76 self.html = site_markup(self.description)
gremmie@1 77 super(Event, self).save(*args, **kwargs)
gremmie@1 78
bgneal@139 79 def is_approved(self):
bgneal@139 80 return self.status not in (self.NEW, self.EDIT_REQ, self.DEL_REQ)
bgneal@139 81 is_approved.boolean = True
gremmie@1 82
bgneal@228 83 def google_html(self):
bgneal@228 84 """Returns a HTML <a> tag to the event if it exits."""
bgneal@228 85 if self.google_url:
bgneal@228 86 return u'<a href="%s">On Google</a>' % self.google_url
bgneal@228 87 return u''
bgneal@228 88 google_html.allow_tags = True
bgneal@228 89 google_html.short_description = 'Google Link'
bgneal@228 90
bgneal@228 91 def notify_on_calendar(self):
bgneal@228 92 """
bgneal@228 93 This function should be called when the event has been added to the
bgneal@228 94 Google calendar for the first time. This gives us a chance to perform
bgneal@228 95 any first-time processing, like creating a forum thread.
bgneal@228 96 """
bgneal@228 97 if self.create_forum_thread:
bgneal@228 98 topic_name = '%s: %s' % (self.start_date.strftime('%m/%d/%Y'),
bgneal@228 99 self.what)
bgneal@228 100 post_body = "%s\n\n[Link to event on Google Calendar](%s)" % (
bgneal@228 101 self.description, self.google_url)
bgneal@228 102
bgneal@228 103 forums.tools.create_topic(
bgneal@228 104 forum_slug=GIG_FORUM_SLUG,
bgneal@456 105 user=self.user,
bgneal@228 106 topic_name=topic_name,
bgneal@228 107 post_body=post_body)
bgneal@228 108
bgneal@228 109 self.create_forum_thread = False
bgneal@228 110 self.save()
bgneal@456 111
bgneal@456 112
bgneal@458 113 class AccessTokenManager(models.Manager):
bgneal@458 114 """
bgneal@458 115 A manager for the AccessToken table. Only one access token is saved in the
bgneal@458 116 database. This manager provides a convenience method to either return that
bgneal@458 117 access token or a brand new one.
bgneal@458 118
bgneal@458 119 """
bgneal@458 120 def get_token(self):
bgneal@458 121 try:
bgneal@458 122 token = self.get(pk=1)
bgneal@458 123 except AccessToken.DoesNotExist:
bgneal@458 124 token = AccessToken()
bgneal@458 125
bgneal@458 126 return token
bgneal@458 127
bgneal@458 128
bgneal@456 129 class AccessToken(models.Model):
bgneal@456 130 """
bgneal@456 131 This model represents serialized OAuth access tokens for reading and
bgneal@456 132 updating the Google Calendar.
bgneal@456 133
bgneal@456 134 """
bgneal@456 135 auth_date = models.DateTimeField()
bgneal@456 136 token = models.TextField()
bgneal@456 137
bgneal@458 138 objects = AccessTokenManager()
bgneal@458 139
bgneal@456 140 def __unicode__(self):
bgneal@456 141 return u'Access token created on ' + unicode(self.auth_date)
bgneal@456 142
bgneal@458 143 def update(self, access_token, auth_date=None):
bgneal@458 144 """
bgneal@458 145 This function updates the AccessToken object with the input parameters:
bgneal@458 146 access_token - an access token from Google's OAuth dance
bgneal@458 147 auth_date - a datetime or None. If None, now() is used.
bgneal@458 148
bgneal@458 149 """
bgneal@458 150 self.auth_date = auth_date if auth_date else datetime.datetime.now()
bgneal@458 151 self.token = serialize_token(access_token)
bgneal@458 152
bgneal@458 153 def access_token(self):
bgneal@458 154 """
bgneal@458 155 This function returns a Google OAuth access token by deserializing the
bgneal@458 156 token field from the database.
bgneal@458 157 If the token attribute is empty, None is returned.
bgneal@458 158
bgneal@458 159 """
bgneal@458 160 return deserialize_token(self.token) if self.token else None