gremmie@1: """ gremmie@1: This file contains the automatic admin site definitions for the gcalendar application. bgneal@451: gremmie@1: """ bgneal@451: from django.conf import settings bgneal@574: from django.conf.urls import patterns, url gremmie@1: from django.contrib import admin bgneal@451: from django.contrib import messages bgneal@454: from django.contrib.sites.models import Site bgneal@451: from django.core.urlresolvers import reverse bgneal@451: from django.http import HttpResponseRedirect bgneal@458: from django.shortcuts import render bgneal@451: bgneal@451: import gdata.client gremmie@1: bgneal@456: from gcalendar.models import Event, AccessToken bgneal@458: from gcalendar.calendar import Calendar, CalendarError bgneal@451: from gcalendar import oauth bgneal@451: bgneal@204: import bio.badges gremmie@1: gremmie@1: bgneal@451: SCOPES = ['https://www.google.com/calendar/feeds/'] bgneal@451: bgneal@451: gremmie@1: class EventAdmin(admin.ModelAdmin): gremmie@1: list_display = ('what', 'user', 'start_date', 'where', 'date_submitted', bgneal@228: 'status', 'is_approved', 'google_html') gremmie@1: list_filter = ('start_date', 'status') bgneal@152: date_hierarchy = 'start_date' gremmie@1: search_fields = ('what', 'where', 'description') gremmie@1: raw_id_fields = ('user', ) bgneal@228: exclude = ('html', 'google_id', 'google_url') gremmie@1: save_on_top = True bgneal@152: actions = ('approve_events', ) bgneal@152: bgneal@152: pending_states = { bgneal@152: Event.NEW: Event.NEW_APRV, bgneal@152: Event.EDIT_REQ: Event.EDIT_APRV, bgneal@152: Event.DEL_REQ: Event.DEL_APRV, bgneal@152: } gremmie@1: gremmie@1: def get_urls(self): gremmie@1: urls = super(EventAdmin, self).get_urls() gremmie@1: my_urls = patterns('', bgneal@451: url(r'^google_sync/$', bgneal@451: self.admin_site.admin_view(self.google_sync), bgneal@451: name="gcalendar-google_sync"), bgneal@451: url(r'^fetch_auth/$', bgneal@451: self.admin_site.admin_view(self.fetch_auth), bgneal@451: name="gcalendar-fetch_auth"), bgneal@451: url(r'^get_access_token/$', bgneal@451: self.admin_site.admin_view(self.get_access_token), bgneal@451: name="gcalendar-get_access_token"), gremmie@1: ) gremmie@1: return my_urls + urls gremmie@1: bgneal@152: def approve_events(self, request, qs): bgneal@152: """ bgneal@152: Ratchets the selected events forward to the approved state. bgneal@152: Ignores events that aren't in the proper state. bgneal@152: """ bgneal@389: count = 0 bgneal@152: for event in qs: bgneal@152: if event.status in self.pending_states: bgneal@152: event.status = self.pending_states[event.status] bgneal@152: event.save() bgneal@152: count += 1 bgneal@152: bgneal@204: if event.status == Event.NEW_APRV: bgneal@204: bio.badges.award_badge(bio.badges.CALENDAR_PIN, event.user) bgneal@204: bgneal@152: msg = "1 event was" if count == 1 else "%d events were" % count bgneal@152: msg += " approved." bgneal@152: self.message_user(request, msg) bgneal@152: bgneal@152: approve_events.short_description = "Approve selected events" bgneal@152: bgneal@451: def google_sync(self, request): bgneal@458: """ bgneal@458: View to synchronize approved event changes with Google calendar. bgneal@458: bgneal@458: """ bgneal@458: # Get pending events bgneal@451: events = Event.pending_events.all() bgneal@458: bgneal@458: # Attempt to get saved access token to the Google calendar bgneal@458: access_token = AccessToken.objects.get_token().access_token() bgneal@458: bgneal@451: messages = [] bgneal@451: err_msg = '' bgneal@451: if request.method == 'POST': bgneal@458: if access_token: bgneal@451: try: bgneal@458: cal = Calendar(source=oauth.USER_AGENT, bgneal@458: calendar_id=settings.GCAL_CALENDAR_ID, bgneal@458: access_token=access_token) bgneal@451: cal.sync_events(events) bgneal@451: except CalendarError, e: bgneal@451: err_msg = e.msg bgneal@451: events = Event.pending_events.all() bgneal@451: else: bgneal@451: messages.append('All events processed successfully.') bgneal@451: events = Event.objects.none() bgneal@451: bgneal@458: return render(request, 'gcalendar/google_sync.html', { bgneal@451: 'current_app': self.admin_site.name, bgneal@458: 'access_token': access_token, bgneal@451: 'messages': messages, bgneal@451: 'err_msg': err_msg, bgneal@451: 'events': events, bgneal@458: }) bgneal@451: bgneal@451: def fetch_auth(self, request): bgneal@451: """ bgneal@451: This view fetches a request token and then redirects the user to bgneal@451: authorize it. bgneal@451: bgneal@451: """ bgneal@454: site = Site.objects.get_current() bgneal@454: callback_url = 'http://%s%s' % (site.domain, bgneal@454: reverse('admin:gcalendar-get_access_token')) bgneal@451: try: bgneal@451: auth_url = oauth.fetch_auth(request, SCOPES, callback_url) bgneal@451: except gdata.client.Error, e: bgneal@451: messages.error(request, str(e)) bgneal@451: return HttpResponseRedirect(reverse('admin:gcalendar-google_sync')) bgneal@451: else: bgneal@451: return HttpResponseRedirect(auth_url) bgneal@451: bgneal@451: def get_access_token(self, request): bgneal@451: """ bgneal@451: This view is called by Google after the user has authorized us access to bgneal@456: their data. We call into the oauth module to upgrade the oauth token to bgneal@451: an access token. We then save the access token in the database and bgneal@451: redirect back to our admin Google sync view. bgneal@451: bgneal@451: """ bgneal@451: try: bgneal@451: access_token = oauth.get_access_token(request) bgneal@451: except gdata.client.Error, e: bgneal@451: messages.error(request, str(e)) bgneal@451: else: bgneal@458: token = AccessToken.objects.get_token() bgneal@458: token.update(access_token) bgneal@456: token.save() bgneal@451: bgneal@451: return HttpResponseRedirect(reverse('admin:gcalendar-google_sync')) bgneal@451: gremmie@1: gremmie@1: admin.site.register(Event, EventAdmin) bgneal@456: admin.site.register(AccessToken)