This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
corbo/corbo/views.py

387 lines
12 KiB
Python

import json
from django.conf import settings
from django.contrib import messages
from django.core import signing
from django.utils import timezone
from django.core.urlresolvers import reverse
from django.views.generic import CreateView, UpdateView, DeleteView, \
ListView, TemplateView, RedirectView, DetailView, FormView
from django.contrib.syndication.views import Feed
from django.shortcuts import resolve_url
from django.utils.encoding import force_text
from django.utils.feedgenerator import Atom1Feed as DjangoAtom1Feed
from django.utils.http import quote
from django.http import HttpResponseRedirect, HttpResponse, Http404
from django.contrib.auth import logout as auth_logout
from django.contrib.auth import views as auth_views
from django.contrib import messages
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ngettext
from . import models
from .forms import AnnounceForm, CategoryForm, SubscriptionsImportForm, \
SendTestEmailForm, SendTestSMSForm
from . import utils
try:
from mellon.utils import get_idps
except ImportError:
get_idps = lambda: []
def login(request, *args, **kwargs):
if any(get_idps()):
if 'next' not in request.GET:
return HttpResponseRedirect(resolve_url('mellon_login'))
return HttpResponseRedirect(resolve_url('mellon_login') + '?next=' +
quote(request.GET.get('next')))
return auth_views.login(request, *args, **kwargs)
def logout(request, next_page=None):
if any(get_idps()):
return HttpResponseRedirect(resolve_url('mellon_logout'))
auth_logout(request)
if next_page is not None:
next_page = resolve_url(next_page)
else:
next_page = '/'
return HttpResponseRedirect(next_page)
class HomepageView(RedirectView):
pattern_name = 'manage'
permanent = False
homepage = HomepageView.as_view()
class AnnounceCreateView(CreateView):
form_class = AnnounceForm
template_name = 'corbo/announce_form.html'
def get_success_url(self):
return reverse('view_category', kwargs={'slug': self.object.category.slug})
def get_initial(self):
initial = super(AnnounceCreateView, self).get_initial()
initial['category'] = models.Category.objects.get(slug=self.kwargs['slug'])
return initial
def get_context_data(self, **kwargs):
context = super(AnnounceCreateView, self).get_context_data(**kwargs)
context['category'] = context['form'].initial['category']
return context
add_announce = AnnounceCreateView.as_view()
class AnnounceEditView(UpdateView):
model = models.Announce
form_class = AnnounceForm
def get_context_data(self, **kwargs):
context = super(AnnounceEditView, self).get_context_data(**kwargs)
category_id = context['form'].initial['category']
context['category'] = models.Category.objects.get(pk=category_id)
return context
def get_success_url(self):
return reverse('view_announce', kwargs={'pk': self.object.pk})
edit_announce = AnnounceEditView.as_view()
class AnnounceDeleteView(DeleteView):
model = models.Announce
def get_success_url(self):
return reverse('view_category', kwargs={'slug': self.object.category.slug})
delete_announce = AnnounceDeleteView.as_view()
class CategoryCreateView(CreateView):
form_class = CategoryForm
template_name = 'corbo/category_form.html'
def get_success_url(self):
return reverse('manage')
def form_valid(self, form):
form.save()
return super(CategoryCreateView, self).form_valid(form)
add_category = CategoryCreateView.as_view()
class CategoryEditView(UpdateView):
form_class = CategoryForm
model = models.Category
def get_success_url(self):
return reverse('view_category', kwargs={'slug': self.object.slug})
edit_category = CategoryEditView.as_view()
class CategoryView(ListView):
model = models.Announce
paginate_by = settings.ANNOUNCES_PER_PAGE
def get_queryset(self):
qs = super(CategoryView, self).get_queryset()
return qs.filter(category__slug=self.kwargs['slug'])
def get_context_data(self, **kwargs):
context = super(CategoryView, self).get_context_data(**kwargs)
context['category'] = models.Category.objects.get(slug=self.kwargs['slug'])
return context
view_category = CategoryView.as_view()
class CategoryDeleteView(DeleteView):
model = models.Category
def get_success_url(self):
return reverse('manage')
delete_category = CategoryDeleteView.as_view()
class UnsubscribeView(DeleteView):
model = models.Subscription
def get_object(self, queryset=None):
try:
data = signing.loads(self.kwargs['unsubscription_token'])
except signing.BadSignature:
raise Http404
try:
return models.Subscription.objects.get(category__pk=data['category'],
identifier=data['identifier'])
except models.Subscription.DoesNotExist:
raise Http404
def get_success_url(self):
return reverse('unsubscription_done')
unsubscribe = UnsubscribeView.as_view()
class UnsubscriptionDoneView(TemplateView):
template_name = 'corbo/unsubscription_done.html'
unsubscription_done = UnsubscriptionDoneView.as_view()
class ManageView(ListView):
template_name = 'corbo/manage.html'
model = models.Category
paginate_by = settings.CATEGORIES_PER_PAGE
manage = ManageView.as_view()
class Atom1Feed(DjangoAtom1Feed):
def root_attributes(self):
attrs = super(Atom1Feed, self).root_attributes()
attrs.update({'xml:base': self.feed['link']})
return attrs
class AtomView(Feed):
title = settings.RSS_TITLE
description = settings.RSS_DESCRIPTION
link = settings.RSS_LINK
feed_item_link_template = settings.RSS_LINK_TEMPLATE
feed_type = Atom1Feed
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
def items(self):
limit = settings.RSS_ITEMS_LIMIT
return models.Announce.objects.filter(publication_time__lte=timezone.now()).exclude(
expiration_time__lt=timezone.now()).order_by('-publication_time')[:limit]
def item_title(self, item):
return item.title
def item_description(self, item):
return item.text
def item_link(self, item):
return self.feed_item_link_template.format(item.pk)
def item_pubdate(self, item):
return item.publication_time or item.mtime
atom = AtomView()
class SubscriptionsImportView(FormView):
form_class = SubscriptionsImportForm
template_name = 'corbo/subscriptions_import_form.html'
def get_context_data(self, **kwargs):
context = super(SubscriptionsImportView, self).get_context_data(**kwargs)
context['category'] = models.Category.objects.get(slug=self.kwargs['slug'])
return context
def get_success_url(self):
category = models.Category.objects.get(slug=self.kwargs['slug'])
return reverse('view_category', kwargs={'slug': category.slug})
def form_valid(self, form):
new = 0
c = models.Category.objects.get(slug=self.kwargs['slug'])
for email in form.cleaned_data['subscribers']:
obj, created = models.Subscription.objects.get_or_create(category=c, identifier='mailto:%s' % email)
if created:
new += 1
messages.info(self.request, ngettext('%(new)d subscriber added', '%(new)d subscribers added', new) % {'new': new})
return super(SubscriptionsImportView, self).form_valid(form)
subscriptions_import = SubscriptionsImportView.as_view()
class SubscriptionSearchView(TemplateView):
template_name = 'corbo/subscription_search.html'
def get_context_data(self, **kwargs):
context = super(SubscriptionSearchView, self).get_context_data(**kwargs)
query = self.request.GET.get('q', '').strip()
context['query'] = query
if not query:
return context
context['subscriptions'] = models.Subscription.objects.filter(identifier='mailto:' + query)
phonenumber = utils.format_phonenumber(query)
if not context['subscriptions'] and phonenumber:
# search by last n digits
context['subscriptions'] = models.Subscription.objects.filter(
identifier__endswith=phonenumber[-settings.CORBO_PHONE_SEARCH_DIGITS:])
return context
subscription_search = SubscriptionSearchView.as_view()
class SubscriptionDeleteView(DeleteView):
model = models.Subscription
template_name = 'corbo/subscription_delete.html'
def get_context_data(self, **kwargs):
context = super(SubscriptionDeleteView, self).get_context_data(**kwargs)
context['identifier'] = self.object.identifier.split(':', 1)[1]
context['category'] = self.object.category.name
return context
def get_success_url(self):
identifier = self.object.identifier.split(':', 1)[1]
return reverse('subscription-search') + '?q=%s' % identifier
def delete(self, request, *args, **kwargs):
response = super(SubscriptionDeleteView, self).delete(request, *args, **kwargs)
success_message = _('%(user)s successfuly unsubscribed from %(category)s') % {
'user': self.object.identifier.split(':', 1)[1],
'category': self.object.category.name}
messages.success(request, success_message)
return response
subscription_delete = SubscriptionDeleteView.as_view()
class AnnounceView(DetailView):
model = models.Announce
template_name = 'corbo/announce_view.html'
def get_context_data(self, **kwargs):
context = super(AnnounceView, self).get_context_data(**kwargs)
context['category'] = self.object.category
context['broadcasts'] = self.object.broadcast_set.filter(deliver_time__isnull=False)
context['sms_enabled'] = settings.SMS_GATEWAY_URL
return context
view_announce = AnnounceView.as_view()
class SendAnnounceView(FormView):
def get_initial(self):
return {'email': self.request.user.email,
'mobile': self.request.session.get('mellon_session', {}).get('mobile', [''])[0]}
def get_success_url(self, *args, **kwargs):
return reverse('view_announce', kwargs={'pk': self.kwargs['pk']})
def get_context_data(self, **kwargs):
context = super(SendAnnounceView, self).get_context_data(**kwargs)
context['object'] = models.Announce.objects.get(pk=self.kwargs['pk'])
return context
class EmailAnnounceView(SendAnnounceView):
form_class = SendTestEmailForm
template_name = 'corbo/email_test_announce_form.html'
def form_valid(self, form):
email = form.cleaned_data['email']
announce = models.Announce.objects.get(pk=self.kwargs['pk'])
utils.send_email(announce.title, announce.text, [email], announce.category.pk)
messages.info(self.request, _('Email successfully sent'))
return super(EmailAnnounceView, self).form_valid(form)
email_announce = EmailAnnounceView.as_view()
class SMSAnnounceView(SendAnnounceView):
form_class = SendTestSMSForm
template_name = 'corbo/sms_test_announce_form.html'
def form_valid(self, form):
mobile = form.cleaned_data['mobile']
announce = models.Announce.objects.get(pk=self.kwargs['pk'])
sms_sent = utils.send_sms(announce.text, [mobile])
if sms_sent == 1:
messages.info(self.request, _('SMS successfully sent'))
else:
messages.error(self.request, _('Error occured while sending SMS'))
return super(SMSAnnounceView, self).form_valid(form)
sms_announce = SMSAnnounceView.as_view()
def menu_json(request):
label = _('Announces')
json_str = json.dumps([{'label': force_text(label),
'slug': 'announces',
'url': request.build_absolute_uri(reverse('manage'))}])
for variable in ('jsonpCallback', 'callback'):
if variable in request.GET:
response = HttpResponse(content_type='application/javascript')
json_str = '%s(%s);' % (request.GET[variable], json_str)
break
else:
response = HttpResponse(content_type='application/json')
response.write(json_str)
return response