view gcalendar/models.py @ 693:ad69236e8501

For issue #52, update many 3rd party Javascript libraries. Updated to jquery 1.10.2, jquery ui 1.10.3. This broke a lot of stuff. - Found a newer version of the jquery cycle all plugin (3.0.3). - Updated JPlayer to 2.4.0. - Updated to MarkItUp 1.1.14. This also required me to add multiline attributes set to true on various buttons in the markdown set. - As per a stackoverflow post, added some code to get multiline titles in a jQuery UI dialog. They removed that functionality but allow you to put it back. Tweaked the MarkItUp preview CSS to show blockquotes in italic. Did not update TinyMCE at this time. I'm not using the JQuery version and this version appears to work ok for now. What I should do is make a repo for MarkItUp and do a vendor branch thing so I don't have to futz around diffing directories to figure out if I'll lose changes when I update.
author Brian Neal <bgneal@gmail.com>
date Wed, 04 Sep 2013 19:55:20 -0500
parents ee87ea74d46b
children 3e1905e523be
line wrap: on
line source
"""
Models for the gcalendar application.

"""
import datetime

from django.db import models
from django.db.models import Q
from django.contrib.auth.models import User

from core.markup import site_markup
import forums.tools
from gcalendar.oauth import serialize_token, deserialize_token


GIG_FORUM_SLUG = "gigs"

class PendingEventManager(models.Manager):
    """A manager for pending events."""

    def get_query_set(self):
        """Returns a queryset of events that have been approved to update
        the Google calendar."""
        return super(PendingEventManager, self).get_query_set().filter(
                Q(status=Event.NEW_APRV) |
                Q(status=Event.EDIT_APRV) |
                Q(status=Event.DEL_APRV)
            )


class Event(models.Model):
    """Model to represent calendar events."""

    # Event status codes:
    (NEW, NEW_APRV, EDIT_REQ, EDIT_APRV, DEL_REQ, DEL_APRV, ON_CAL) = range(7)

    STATUS_CHOICES = (
        (NEW, 'New'),
        (NEW_APRV, 'New Approved'),
        (EDIT_REQ, 'Edit Request'),
        (EDIT_APRV, 'Edit Approved'),
        (DEL_REQ, 'Delete Request'),
        (DEL_APRV, 'Delete Approved'),
        (ON_CAL, 'On Calendar'),
    )

    user = models.ForeignKey(User)
    what = models.CharField(max_length=255)
    start_date = models.DateField()
    start_time = models.TimeField(null=True, blank=True)
    end_date = models.DateField()
    end_time = models.TimeField(null=True, blank=True)
    time_zone = models.CharField(max_length=64, blank=True)
    all_day = models.BooleanField(default=False)
    where = models.CharField(max_length=255, blank=True)
    description = models.TextField(blank=True)
    html = models.TextField(blank=True)
    date_submitted = models.DateTimeField(auto_now_add=True)
    google_id = models.CharField(max_length=255, blank=True)
    google_url = models.URLField(max_length=255, blank=True)
    status = models.SmallIntegerField(choices=STATUS_CHOICES, default=NEW,
            db_index=True)
    create_forum_thread = models.BooleanField(default=False)

    objects = models.Manager()
    pending_events = PendingEventManager()

    def __unicode__(self):
        return self.what

    class Meta:
        ordering = ('-date_submitted', )

    def save(self, *args, **kwargs):
        self.html = site_markup(self.description)
        super(Event, self).save(*args, **kwargs)

    def is_approved(self):
        return self.status not in (self.NEW, self.EDIT_REQ, self.DEL_REQ)
    is_approved.boolean = True

    def google_html(self):
        """Returns a HTML <a> tag to the event if it exits."""
        if self.google_url:
            return u'<a href="%s">On Google</a>' % self.google_url
        return u''
    google_html.allow_tags = True
    google_html.short_description = 'Google Link'

    def notify_on_calendar(self):
        """
        This function should be called when the event has been added to the
        Google calendar for the first time. This gives us a chance to perform
        any first-time processing, like creating a forum thread.
        """
        if self.create_forum_thread:
            topic_name = '%s: %s' % (self.start_date.strftime('%m/%d/%Y'),
                    self.what)
            post_body = "%s\n\n[Link to event on Google Calendar](%s)" % (
                    self.description, self.google_url)

            forums.tools.create_topic(
                forum_slug=GIG_FORUM_SLUG,
                user=self.user,
                topic_name=topic_name,
                post_body=post_body)

            self.create_forum_thread = False
            self.save()


class AccessTokenManager(models.Manager):
    """
    A manager for the AccessToken table. Only one access token is saved in the
    database. This manager provides a convenience method to either return that
    access token or a brand new one.

    """
    def get_token(self):
        try:
            token = self.get(pk=1)
        except AccessToken.DoesNotExist:
            token = AccessToken()

        return token


class AccessToken(models.Model):
    """
    This model represents serialized OAuth access tokens for reading and
    updating the Google Calendar.

    """
    auth_date = models.DateTimeField()
    token = models.TextField()

    objects = AccessTokenManager()

    def __unicode__(self):
        return u'Access token created on ' + unicode(self.auth_date)

    def update(self, access_token, auth_date=None):
        """
        This function updates the AccessToken object with the input parameters:
            access_token - an access token from Google's OAuth dance
            auth_date - a datetime or None. If None, now() is used.

        """
        self.auth_date = auth_date if auth_date else datetime.datetime.now()
        self.token = serialize_token(access_token)

    def access_token(self):
        """
        This function returns a Google OAuth access token by deserializing the
        token field from the database.
        If the token attribute is empty, None is returned.

        """
        return deserialize_token(self.token) if self.token else None