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
|