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