gremmie@1
|
1 """
|
gremmie@1
|
2 This file contains the automatic admin site definitions for the gcalendar application.
|
bgneal@451
|
3
|
gremmie@1
|
4 """
|
bgneal@457
|
5 import datetime
|
bgneal@457
|
6
|
bgneal@451
|
7 from django.conf import settings
|
bgneal@451
|
8 from django.conf.urls.defaults import *
|
gremmie@1
|
9 from django.contrib import admin
|
bgneal@451
|
10 from django.contrib import messages
|
bgneal@454
|
11 from django.contrib.sites.models import Site
|
bgneal@451
|
12 from django.core.urlresolvers import reverse
|
gremmie@1
|
13 from django.http import HttpResponse
|
bgneal@451
|
14 from django.http import HttpResponseRedirect
|
bgneal@451
|
15 from django.shortcuts import render_to_response
|
bgneal@451
|
16 from django.template import RequestContext
|
bgneal@451
|
17
|
bgneal@451
|
18 import gdata.client
|
gremmie@1
|
19
|
bgneal@456
|
20 from gcalendar.models import Event, AccessToken
|
bgneal@451
|
21 from gcalendar.forms import PasswordForm
|
bgneal@451
|
22 from gcalendar.calendar import Calendar
|
bgneal@451
|
23 from gcalendar.calendar import CalendarError
|
bgneal@451
|
24 from gcalendar import oauth
|
bgneal@451
|
25
|
bgneal@204
|
26 import bio.badges
|
gremmie@1
|
27
|
gremmie@1
|
28
|
bgneal@451
|
29 SCOPES = ['https://www.google.com/calendar/feeds/']
|
bgneal@451
|
30
|
bgneal@451
|
31
|
gremmie@1
|
32 class EventAdmin(admin.ModelAdmin):
|
gremmie@1
|
33 list_display = ('what', 'user', 'start_date', 'where', 'date_submitted',
|
bgneal@228
|
34 'status', 'is_approved', 'google_html')
|
gremmie@1
|
35 list_filter = ('start_date', 'status')
|
bgneal@152
|
36 date_hierarchy = 'start_date'
|
gremmie@1
|
37 search_fields = ('what', 'where', 'description')
|
gremmie@1
|
38 raw_id_fields = ('user', )
|
bgneal@228
|
39 exclude = ('html', 'google_id', 'google_url')
|
gremmie@1
|
40 save_on_top = True
|
bgneal@152
|
41 actions = ('approve_events', )
|
bgneal@152
|
42
|
bgneal@152
|
43 pending_states = {
|
bgneal@152
|
44 Event.NEW: Event.NEW_APRV,
|
bgneal@152
|
45 Event.EDIT_REQ: Event.EDIT_APRV,
|
bgneal@152
|
46 Event.DEL_REQ: Event.DEL_APRV,
|
bgneal@152
|
47 }
|
gremmie@1
|
48
|
gremmie@1
|
49 def get_urls(self):
|
gremmie@1
|
50 urls = super(EventAdmin, self).get_urls()
|
gremmie@1
|
51 my_urls = patterns('',
|
bgneal@451
|
52 url(r'^google_sync/$',
|
bgneal@451
|
53 self.admin_site.admin_view(self.google_sync),
|
bgneal@451
|
54 name="gcalendar-google_sync"),
|
bgneal@451
|
55 url(r'^fetch_auth/$',
|
bgneal@451
|
56 self.admin_site.admin_view(self.fetch_auth),
|
bgneal@451
|
57 name="gcalendar-fetch_auth"),
|
bgneal@451
|
58 url(r'^get_access_token/$',
|
bgneal@451
|
59 self.admin_site.admin_view(self.get_access_token),
|
bgneal@451
|
60 name="gcalendar-get_access_token"),
|
gremmie@1
|
61 )
|
gremmie@1
|
62 return my_urls + urls
|
gremmie@1
|
63
|
bgneal@152
|
64 def approve_events(self, request, qs):
|
bgneal@152
|
65 """
|
bgneal@152
|
66 Ratchets the selected events forward to the approved state.
|
bgneal@152
|
67 Ignores events that aren't in the proper state.
|
bgneal@152
|
68 """
|
bgneal@389
|
69 count = 0
|
bgneal@152
|
70 for event in qs:
|
bgneal@152
|
71 if event.status in self.pending_states:
|
bgneal@152
|
72 event.status = self.pending_states[event.status]
|
bgneal@152
|
73 event.save()
|
bgneal@152
|
74 count += 1
|
bgneal@152
|
75
|
bgneal@204
|
76 if event.status == Event.NEW_APRV:
|
bgneal@204
|
77 bio.badges.award_badge(bio.badges.CALENDAR_PIN, event.user)
|
bgneal@204
|
78
|
bgneal@152
|
79 msg = "1 event was" if count == 1 else "%d events were" % count
|
bgneal@152
|
80 msg += " approved."
|
bgneal@152
|
81 self.message_user(request, msg)
|
bgneal@152
|
82
|
bgneal@152
|
83 approve_events.short_description = "Approve selected events"
|
bgneal@152
|
84
|
bgneal@451
|
85 def google_sync(self, request):
|
bgneal@451
|
86 """View to synchronize approved event changes with Google calendar."""
|
bgneal@451
|
87 events = Event.pending_events.all()
|
bgneal@451
|
88 messages = []
|
bgneal@451
|
89 err_msg = ''
|
bgneal@451
|
90 if request.method == 'POST':
|
bgneal@451
|
91 form = PasswordForm(request.POST)
|
bgneal@451
|
92 if form.is_valid():
|
bgneal@451
|
93 try:
|
bgneal@451
|
94 cal = Calendar(settings.GCAL_EMAIL,
|
bgneal@451
|
95 form.cleaned_data['password'],
|
bgneal@451
|
96 settings.GCAL_CALENDAR_ID)
|
bgneal@451
|
97 cal.sync_events(events)
|
bgneal@451
|
98 except CalendarError, e:
|
bgneal@451
|
99 err_msg = e.msg
|
bgneal@451
|
100 events = Event.pending_events.all()
|
bgneal@451
|
101 form = PasswordForm()
|
bgneal@451
|
102 else:
|
bgneal@451
|
103 messages.append('All events processed successfully.')
|
bgneal@451
|
104 events = Event.objects.none()
|
bgneal@451
|
105 form = PasswordForm()
|
bgneal@451
|
106
|
bgneal@451
|
107 else:
|
bgneal@451
|
108 form = PasswordForm()
|
bgneal@451
|
109
|
bgneal@451
|
110 return render_to_response('gcalendar/google_sync.html', {
|
bgneal@451
|
111 'current_app': self.admin_site.name,
|
bgneal@451
|
112 'messages': messages,
|
bgneal@451
|
113 'err_msg': err_msg,
|
bgneal@451
|
114 'events': events,
|
bgneal@451
|
115 'form': form,
|
bgneal@451
|
116 },
|
bgneal@451
|
117 context_instance=RequestContext(request))
|
bgneal@451
|
118
|
bgneal@451
|
119 def fetch_auth(self, request):
|
bgneal@451
|
120 """
|
bgneal@451
|
121 This view fetches a request token and then redirects the user to
|
bgneal@451
|
122 authorize it.
|
bgneal@451
|
123
|
bgneal@451
|
124 """
|
bgneal@454
|
125 site = Site.objects.get_current()
|
bgneal@454
|
126 callback_url = 'http://%s%s' % (site.domain,
|
bgneal@454
|
127 reverse('admin:gcalendar-get_access_token'))
|
bgneal@451
|
128 try:
|
bgneal@451
|
129 auth_url = oauth.fetch_auth(request, SCOPES, callback_url)
|
bgneal@451
|
130 except gdata.client.Error, e:
|
bgneal@451
|
131 messages.error(request, str(e))
|
bgneal@451
|
132 return HttpResponseRedirect(reverse('admin:gcalendar-google_sync'))
|
bgneal@451
|
133 else:
|
bgneal@451
|
134 return HttpResponseRedirect(auth_url)
|
bgneal@451
|
135
|
bgneal@451
|
136 def get_access_token(self, request):
|
bgneal@451
|
137 """
|
bgneal@451
|
138 This view is called by Google after the user has authorized us access to
|
bgneal@456
|
139 their data. We call into the oauth module to upgrade the oauth token to
|
bgneal@451
|
140 an access token. We then save the access token in the database and
|
bgneal@451
|
141 redirect back to our admin Google sync view.
|
bgneal@451
|
142
|
bgneal@451
|
143 """
|
bgneal@451
|
144 try:
|
bgneal@451
|
145 access_token = oauth.get_access_token(request)
|
bgneal@451
|
146 except gdata.client.Error, e:
|
bgneal@451
|
147 messages.error(request, str(e))
|
bgneal@451
|
148 else:
|
bgneal@456
|
149 try:
|
bgneal@456
|
150 token = AccessToken.objects.get(id=1)
|
bgneal@456
|
151 except AccessToken.DoesNotExist:
|
bgneal@456
|
152 token = AccessToken()
|
bgneal@456
|
153
|
bgneal@456
|
154 token.token = gdata.gauth.TokenToBlob(access_token)
|
bgneal@456
|
155 token.auth_date = datetime.datetime.now()
|
bgneal@456
|
156 token.save()
|
bgneal@451
|
157
|
bgneal@451
|
158 return HttpResponseRedirect(reverse('admin:gcalendar-google_sync'))
|
bgneal@451
|
159
|
gremmie@1
|
160
|
gremmie@1
|
161 admin.site.register(Event, EventAdmin)
|
bgneal@456
|
162 admin.site.register(AccessToken)
|