annotate gpp/gcalendar/models.py @ 493:bdcce55f137e

For #235, some minor news tweaks. The submitted by text is now a link to the author's profile. Only show 1 textarea to the user when submitting a new news story. The admin can paste into the 2nd one if needed.
author Brian Neal <bgneal@gmail.com>
date Sat, 22 Oct 2011 00:48:45 +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