Login

Link Models to Google Calendar

Author:
JosefK
Posted:
July 16, 2007
Language:
Python
Version:
.96
Score:
4 (after 4 ratings)

I've replaced this with the (much nicer) django-gcal.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
"""
Provides a method of keeping models and Google Calendar synchronised.
"""

from datetime import datetime, tzinfo

from django.db.models import signals
from django.dispatch import dispatcher
from django.utils.tzinfo import FixedOffset, LocalTimezone

from gdata.calendar import CalendarEventEntry
from gdata.calendar.service import CalendarService

class CalendarModelFacade(object):
    """
    A proxy between an instance of a model and Google Calendar.
    """
    
    DATE_FORMAT = '%Y-%m-%dT%H:%M:%S.000Z'
    
    def __init__(self, instance):
        """ Creates a new instance of CalendarModelFacade. """
        self.instance = instance
    
    def get_edit_href(self):
        """
        Should return the address used to edit a CalendarEventEntry.
        """
        raise NotImplementedError
    
    def set_edit_href(self, href):
        """
        Should store the address used to edit a CalendarEventEntry.
        """
        raise NotImplementedError
    
    def get_when(self):
        """
        Should return a list of gdata.calendar.When objects, which
        define when the event starts/finishes.
        """
        raise NotImplementedError
    
    def get_title(self):
        """
        May return an atom.Title object, which will be the title of the
        CalendarEventEntry.
        """
        return None
    
    def get_content(self):
        """
        May return an atom.Content object, which will be the content of the
        CalendarEventEntry.
        """
        return None
    
    def get_where(self):
        """
        Should return a list of gdata.calendar.Where objects, which
        define where the CalendarEventEntry takes place.
        """
        return []
    
    def get_categories(self):
        """
        Should return a list of atom.Category objects, which define
        what categories the CalendarEventEntry will fall under.
        """
        return []
    
    def format_datetime(self, date):
        """
        A utility method that converts the datetime to UTC serialized
        for Google Calendar.
        """
        local = date.replace(tzinfo=LocalTimezone(date))
        return local.astimezone(FixedOffset(0)).strftime(self.DATE_FORMAT)
    
    def populate_event(self, event):
        """
        A utility method to populate an instance of CalendarEventEntry
        with values obtained from the model instance this is a proxy
        for.
        """
        event.when = self.get_when()
        event.title = self.get_title()
        event.content = self.get_content()
        event.where = self.get_where()
        event.categories = self.get_categories()

class CalendarObserver(object):
    """
    An observer which monitors the lifecycle of a model instance, and
    automatically updates Google Calendar.
    
    Requires the type of the model to observe and the type of a facade
    object for that model.  Also required are the login details for
    Google Calendar.  Unless specified, the account's default feed will
    be used.
    """
    
    def __init__(self, model, facade, email, password,
                 feed='/calendar/feeds/default/private/full'):
        """ Creates a new instance of CalendarObserver. """
        self.facade = facade
        self.email = email
        self.password = password
        self.feed = feed
        dispatcher.connect(self.update,
                           signal=signals.pre_save,
                           sender=model)
        dispatcher.connect(self.delete,
                           signal=signals.post_delete,
                           sender=model)
    
    def update(self, signal, sender, instance):
        """
        Called when an instance of the observed model is saved.  If
        no entry exists (ie. has not yet been created, or has been
        manually deleted), a new CalendarEventEntry will be created.
        Otherwise, the existing CalendarEventEntry will be updated.
        """
        service = self.get_service()
        proxy = self.facade(instance)
        event = self.get_event(service, proxy) or CalendarEventEntry()
        proxy.populate_event(event)
        if event.GetEditLink():
            service.UpdateEvent(event.GetEditLink().href, event)
        else:
            new_event = service.InsertEvent(event, self.feed)
            proxy.set_edit_href(new_event.GetEditLink().href)
    
    def delete(self, signal, sender, instance):
        """
        Called when an instance of the observed model is deleted.
        """
        service = self.get_service()
        proxy = self.facade(instance)
        event = self.get_event(service, proxy)
        if event:
            service.DeleteEvent(event.GetEditLink().href)
    
    def get_service(self):
        """
        Returns a logged in instance of CalendarService.
        """
        service = CalendarService(email=self.email, password=self.password)
        service.ProgrammaticLogin()
        return service
    
    def get_event(self, service, proxy):
        """
        Loads a CalendarEventEntry from Google Calendar.  If that fails,
        returns None.
        """
        try:
            return service.GetCalendarEventEntry(proxy.get_edit_href())
        except:
            return None

More like this

  1. Template tag - list punctuation for a list of items by shapiromatron 10 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 10 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 5 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 6 months ago
  5. Help text hyperlinks by sa2812 1 year, 6 months ago

Comments

Please login first before commenting.