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@857: from gcalendar.models import Event
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: 
gremmie@1: class EventAdmin(admin.ModelAdmin):
bgneal@857:     list_display = ['what', 'user', 'start_date', 'where', 'date_submitted',
bgneal@857:             'status', 'is_approved', 'google_html']
bgneal@857:     list_filter = ['start_date', 'status']
bgneal@152:     date_hierarchy = 'start_date'
bgneal@857:     search_fields = ['what', 'where', 'description']
bgneal@857:     raw_id_fields = ['user']
bgneal@857:     exclude = ['html', 'google_id', 'google_url']
gremmie@1:     save_on_top = True
bgneal@857:     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@855:             url(r'^authorize/$',
bgneal@855:                 self.admin_site.admin_view(self.authorize),
bgneal@855:                 name="gcalendar-authorize"),
bgneal@855:              url(r'^auth_return/$',
bgneal@855:                 self.admin_site.admin_view(self.auth_return),
bgneal@855:                 name="gcalendar-auth_return"),
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@855:         # Check status of credentials file
bgneal@855:         cred_status = oauth.check_credentials_status()
bgneal@458: 
bgneal@855:         msgs = []
bgneal@451:         err_msg = ''
bgneal@451:         if request.method == 'POST':
bgneal@857:             credentials = oauth.get_credentials()
bgneal@857:             if credentials:
bgneal@451:                 try:
bgneal@857:                     cal = Calendar(calendar_id=settings.GCAL_CALENDAR_ID,
bgneal@857:                             credentials=credentials)
bgneal@451:                     cal.sync_events(events)
bgneal@451:                 except CalendarError, e:
bgneal@857:                     err_msg = str(e)
bgneal@451:                     events = Event.pending_events.all()
bgneal@451:                 else:
bgneal@855:                     msgs.append('All events processed successfully.')
bgneal@451:                     events = Event.objects.none()
bgneal@857:             else:
bgneal@857:                 self.message_user(request, "Invalid or missing credentials",
bgneal@857:                         level=messages.ERROR)
bgneal@451: 
bgneal@458:         return render(request, 'gcalendar/google_sync.html', {
bgneal@451:             'current_app': self.admin_site.name,
bgneal@855:             'cred_status': cred_status,
bgneal@855:             'messages': msgs,
bgneal@451:             'err_msg': err_msg,
bgneal@451:             'events': events,
bgneal@458:             })
bgneal@451: 
bgneal@855:     def authorize(self, request):
bgneal@451:         """
bgneal@855:         This view generates the authorization URL and redirects the user to it.
bgneal@451:         """
bgneal@454:         site = Site.objects.get_current()
bgneal@454:         callback_url = 'http://%s%s' % (site.domain,
bgneal@855:                 reverse('admin:gcalendar-auth_return'))
bgneal@857:         auth_url = oauth.get_auth_url(callback_url)
bgneal@855:         return HttpResponseRedirect(auth_url)
bgneal@451: 
bgneal@855:     def auth_return(self, request):
bgneal@451:         """
bgneal@451:         This view is called by Google after the user has authorized us access to
bgneal@855:         their data. We call into the oauth module to process the authorization
bgneal@855:         code and exchange it for tokens.
bgneal@451:         """
bgneal@451:         try:
bgneal@855:             oauth.auth_return(request)
bgneal@855:         except oauth.OAuthError as e:
bgneal@855:             self.message_user(request, str(e), level=messages.ERROR)
bgneal@451: 
bgneal@451:         return HttpResponseRedirect(reverse('admin:gcalendar-google_sync'))
bgneal@451: 
gremmie@1: 
gremmie@1: admin.site.register(Event, EventAdmin)