Send email. It does not work. Please, fix it!
[cascardo/ema.git] / eventos / views.py
1 # -*- coding: utf-8 -*-
2 # Copyright (C) 2008 Lincoln de Sousa <lincoln@minaslivre.org>
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License as
6 # published by the Free Software Foundation; either version 2 of the
7 # License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 # General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public
15 # License along with this program; if not, write to the
16 # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 # Boston, MA 02111-1307, USA.
18 from django.conf import settings
19 from django.http import HttpResponseRedirect, HttpResponseForbidden
20 from django.contrib.auth import authenticate, login as login_django, \
21     logout as logout_django
22 from django.contrib.auth.models import User, Group
23 from django.forms import HiddenInput, ModelForm
24 from django import forms
25 from django.shortcuts import render_to_response, get_object_or_404
26 from django.template import RequestContext, Context, loader
27 from eventos.models import Palestrante, Trabalho, TipoTrabalho, Trilha, Evento, Improve
28 from eventos.forms import RegisterSpeaker
29 from django.db.models import Q
30 import smtplib
31
32 forbidden = \
33     HttpResponseForbidden('<h2>You are not allowed to do this action.<h2>')
34
35 class SpeakerForm(ModelForm):
36     class Meta:
37         model = Palestrante
38         exclude = ('usuario',)
39
40 class TalkForm(ModelForm):
41     class Meta:
42         model = Trabalho
43
44 class ImproveForm(ModelForm):
45     class Meta:
46         model = Improve
47
48 class SubscribeForm(forms.Form):
49     full_name = forms.CharField(label=u'Nome completo', max_length=255)
50     email = forms.EmailField()
51     username = forms.CharField(max_length=255)
52     password = forms.CharField(label=u'Senha',
53                                max_length=255,
54                                widget=forms.PasswordInput)
55     confirm_password = forms.CharField(label=u'Confirmar senha',
56                                        max_length=255,
57                                        widget=forms.PasswordInput)
58
59     def clean_username(self):
60         data = self.cleaned_data['username']
61         if User.objects.filter(username=data):
62             raise forms.ValidationError(u'O usuário "%s" já existe' % data)
63         return data
64
65     def clean_confirm_password(self):
66         passwd = self.cleaned_data['password']
67         conf_passwd = self.cleaned_data['confirm_password']
68         if passwd != conf_passwd:
69             raise forms.ValidationError(u'A confirmação difere da senha')
70         return conf_passwd
71
72 def login(request):
73     """This is a function that will be used as a front-end to the
74     django's login system. It receives username and password fields
75     from a POST request and tries to login the user.
76
77     If login is successful, user will be redirected to the referer
78     address, otherwise will be redirected to /?login_failed.
79     """
80     username = request.POST['username']
81     password = request.POST['password']
82
83     user = authenticate(username=username, password=password)
84
85     if user is not None:
86         if user.is_active:
87             login_django(request, user)
88             try:
89                 request.session.delete_test_cookie()
90             except KeyError:
91                 pass
92             return HttpResponseRedirect('/')
93         else:
94             return HttpResponseRedirect('/?login_failed')
95     else:
96         return HttpResponseRedirect('/?login_failed')
97
98     request.session.set_test_cookie()
99     return HttpResponseRedirect(request.META.get('HTTP_REFERER', '/'))
100
101 def logout(request):
102     """Simple front-end to django's logout stuff. This function should
103     be mapped to an url and simply called without any parameter.
104     """
105     logout_django(request)
106     return HttpResponseRedirect('/')
107
108 def speaker_add(request):
109     """Adds a new speaker to the system.
110     """
111     uform = RegisterSpeaker(request.POST or None)
112
113     form = SpeakerForm(request.POST or None)
114
115     if request.POST and form.is_valid() and uform.is_valid():
116         cd = uform.cleaned_data
117         group = Group.objects.get_or_create(name='palestrantes')[0]
118
119         # creating the user that will be set as the user of the
120         # speaker.
121         user = User(username=cd['username'])
122         user.set_password(cd['password1'])
123         user.is_active = True
124         user.save()
125         user.groups.add(group)
126
127         # this commit=False is to avoid IntegritErrors, because at
128         # this point, the speaker doesn't have an user associated
129         # with it.
130         instance = form.save(commit=False)
131         instance.usuario = user
132         instance.save()
133         return HttpResponseRedirect('/')
134
135     c = {'form': form, 'uform': uform}
136     return render_to_response('eventos/speaker-add.html', Context(c),
137                               context_instance=RequestContext(request))
138
139 def speaker_details(request, lid):
140     """Shows a simple form containing all editable fields of a
141     speaker and gives the speaker the possibility to save them =)
142     """
143     speaker = get_object_or_404(Palestrante, pk=lid)
144     d = {'speaker' : speaker}
145     if not hasattr(request.user, 'palestrante_set'):
146         return render_to_response('eventos/speaker-details2.html', Context(d),
147                                   context_instance=RequestContext(request))
148
149     entity = request.user.palestrante_set.get()
150     if entity.id != int(lid):
151         return render_to_response('eventos/speaker-details2.html', Context(d),
152                                   context_instance=RequestContext(request))
153
154     form = SpeakerForm(request.POST or None, instance=entity)
155
156     if request.POST and form.is_valid():
157         form.save()
158
159     c = {'form': form}
160     return render_to_response('eventos/speaker-details.html', Context(c),
161                               context_instance=RequestContext(request))
162
163 def speaker_talks(request, lid):
164     """Lists all talks of a speaker (based on speaker id -- lid
165     parameter).
166     """
167     if not hasattr(request.user, 'palestrante_set'):
168         return forbidden
169
170     entity = request.user.palestrante_set.get()
171     if entity.id != int(lid):
172         return forbidden
173
174     talks = Trabalho.objects.filter(
175         Q(palestrante=entity) | Q(outros_palestrantes=entity) )
176
177     c = {'speaker': entity, 'talks': talks}
178     return render_to_response('eventos/talk-list.html', Context(c),
179                               context_instance=RequestContext(request))
180
181 def talk_details(request, tid):
182     """Shows a form to edit a talk
183     """
184     # If the user is not a speaker we should not try to show anything.
185     if not hasattr(request.user, 'palestrante_set'):
186         return forbidden
187
188     # Selected in settings.py (SITE_ID) variable, because an event can
189     # be linked with only one site.
190     event = Evento.objects.get(site__id__exact=settings.SITE_ID)
191
192     # building the form
193     entity = get_object_or_404(Trabalho, pk=tid)
194     form = TalkForm(request.POST or None, instance=entity)
195
196     # These fields should not be shown to the user.
197     form.fields['palestrante'].widget = HiddenInput()
198     form.fields['evento'].widget = HiddenInput()
199
200     # These fields are event specific
201     trilhas = Trilha.objects.filter(evento=event)
202     form.fields['trilha']._set_queryset(trilhas)
203
204     tipos = TipoTrabalho.objects.filter(evento=event)
205     form.fields['tipo']._set_queryset(tipos)
206
207     # hidding the owner in the other speakers list
208     other = Palestrante.objects.exclude(pk=entity.id)
209     form.fields['outros_palestrantes']._set_queryset(other)
210     if other.count() == 0:
211         # I need set the value to '', otherwise the wise django
212         # newforms will fill the field with the invalid string '[]'
213         form.fields['outros_palestrantes'].initial = ''
214         form.fields['outros_palestrantes'].widget = HiddenInput()
215
216     # avoiding smart people trying to se talks of other speakers.
217     speaker = request.user.palestrante_set.get()
218     if speaker.id != entity.palestrante.id \
219             and speaker not in entity.outros_palestrantes.all():
220         return forbidden
221
222     if request.POST and form.is_valid():
223         form.save()
224
225     c = {'form': form}
226     return render_to_response('eventos/talk-details.html', Context(c),
227                               context_instance=RequestContext(request))
228
229 def talk_delete(request, tid):
230     """Drops a talk but only if the logged in user is its owner.
231     """
232     if not hasattr(request.user, 'palestrante_set'):
233         return forbidden
234
235     entity = request.user.palestrante_set.get()
236     talk = Trabalho.objects.filter(pk=tid, palestrante=entity)
237     if not talk:
238         return forbidden
239
240     talk.delete()
241     return HttpResponseRedirect('/speaker/%d/talks/' % entity.id)
242
243 def talk_add(request):
244     """Shows a form to the speaker send a talk
245     """
246     if not hasattr(request.user, 'palestrante_set'):
247         return forbidden
248
249     # building the form
250     form = TalkForm(request.POST or None)
251
252     # These fields should not be shown to the user.
253
254     # Selected in settings.py (SITE_ID) variable, because an event can
255     # be linked with only one site.
256     entity = request.user.palestrante_set.get()
257     form.fields['palestrante'].widget = HiddenInput(attrs={'value' : entity.id})
258
259     event = Evento.objects.get(site__id__exact=settings.SITE_ID)
260     form.fields['evento'].widget = HiddenInput(attrs={'value' : event.id})
261
262     # These fields are event specific
263     trilhas = Trilha.objects.filter(evento=event)
264     form.fields['trilha']._set_queryset(trilhas)
265
266     tipos = TipoTrabalho.objects.filter(evento=event)
267     form.fields['tipo']._set_queryset(tipos)
268
269     # hidding the owner in the other speakers list
270     other = Palestrante.objects.exclude(pk=entity.id)
271     form.fields['outros_palestrantes']._set_queryset(other)
272     if other.count() == 0:
273         form.fields['outros_palestrantes'].widget = HiddenInput()
274
275     if request.POST and form.is_valid():
276         # validation
277         cleaned = form.cleaned_data
278         if cleaned['tipo'].evento.id != event.id:
279             return forbidden
280
281         if cleaned['trilha'].evento.id != event.id:
282             return forbidden
283
284         instance = form.save()
285         return HttpResponseRedirect('/speaker/%d/talks/' % entity.id)
286
287     c = {'form': form}
288     return render_to_response('eventos/talk-add.html', Context(c),
289                               context_instance=RequestContext(request))
290
291 def list_all_talks(request):
292     event = Evento.objects.get(site__id__exact=settings.SITE_ID)
293     trilhas = Trilha.objects.filter(evento=event)
294
295     improve = []
296     for t in trilhas:
297         talks = Trabalho.objects.filter(trilha=t)
298         aux = {'trilha':t.nome, 'talks':talks}
299         improve.append(aux)
300
301     c = {'improve': improve,}
302     return render_to_response('eventos/improve.html', Context(c),
303                               context_instance=RequestContext(request))
304
305 def talk_improve(request, tid):
306     if not hasattr(request.user, 'palestrante_set') and request.POST:
307         return forbidden
308
309     talk = get_object_or_404(Trabalho, pk=tid)
310     speakers = [i for i in talk.outros_palestrantes.all()]
311     speakers = [ talk.palestrante ] + speakers
312     improve = Improve.objects.filter(trabalho=talk)
313
314     # building the form
315     form = ImproveForm(request.POST or None)
316     form.fields['trabalho'].widget = HiddenInput(attrs={'value':talk.id})
317     form.fields['usuario'].widget = HiddenInput(attrs={'value':request.user.id})
318
319     if request.POST and form.is_valid():
320         event = Evento.objects.get(site__id__exact=settings.SITE_ID)
321         # validation
322         cleaned = form.cleaned_data
323         if cleaned['trabalho'].evento.id != event.id:
324             return forbidden
325
326         emails = [i.email for i in speakers]
327         user = cleaned['usuario'].get_full_name()
328         comments = cleaned['comentario']
329         msg = (u"From: emsl@minaslivre.org\r\nTo: %s\r\n"
330                u"Subject: Comentário em seu Trabalho EMSL 2008\r\n"
331                u"Content-Type: text/plain; charset=utf-8\r\n"
332                u"\r\n %s comentou seu trabalho.\r\n%s\r\r\n"
333                % (", ".join(emails), user, comments))
334         smtp = smtplib.SMTP("localhost")
335         smtp.sendmail("emsl@minaslivre.org", emails, str(msg.encode("utf8")))
336         smtp.quit()
337
338         instance = form.save()
339         return HttpResponseRedirect('/improve/%d/' % talk.id)
340
341     c = {'talk': talk, 'form': form, 'improve': improve,
342          'len_comments': len(improve), 'speakers': speakers}
343     return render_to_response('eventos/talk_improve.html', Context(c),
344                               context_instance=RequestContext(request))
345
346 def subscribe(request):
347     """This view shows a form with name, login and password fields and
348     if it receives a post, it will get data from the above fields and
349     create an User (yes, the django User). I think this user will be
350     used as an attendee.
351
352     This function authenticates the new user.
353     """
354     form = SubscribeForm(request.POST or None)
355
356     if request.POST and form.is_valid():
357         new_user = User.objects.create_user(request.POST['username'],
358                                             request.POST['email'],
359                                             request.POST['password'])
360         login(request)
361         return HttpResponseRedirect('/')
362
363     context = {'form': form}
364     return render_to_response('eventos/subscribe.html', Context(context),
365                               context_instance=RequestContext(request))