1 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
2 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
4 from datetime import date, datetime
5 from urllib.parse import quote_plus
7 from allauth.socialaccount.views import SignupView
9 from django.conf import settings
10 from django.contrib import auth
11 from django.contrib.auth.decorators import login_required
12 from django.contrib.auth.forms import AuthenticationForm
13 from django.contrib.auth.views import LoginView
14 from django.core.cache import cache
15 from django.views.generic import FormView
16 from django.http import HttpResponse, HttpResponseRedirect
17 from django.shortcuts import render
18 from django.utils.translation import gettext_lazy as _
19 from django.views.decorators.cache import never_cache
21 from ajaxable.utils import AjaxableFormView
22 from ajaxable.utils import placeholdized
23 from catalogue.models import Book, Collection, Tag, Fragment
25 from social.utils import get_or_choose_cite
26 from wolnelektury.forms import RegistrationForm, SocialSignupForm, WLAuthenticationForm
30 def main_page(request):
32 'last_published': Book.objects.exclude(cover_thumb='').filter(findable=True, parent=None).order_by('-created_at')[:6],
36 # FIXME: find this theme and books properly.
37 if Fragment.objects.exists():
39 ctx['theme'] = Tag.objects.filter(category='theme').order_by('?')[:1][0]
40 tf = Fragment.tagged.with_any([ctx['theme']]).select_related('book').filter(book__findable=True).order_by('?')[:100]
43 ctx['theme_fragment'] = tf[0]
45 if f.book not in ctx['theme_books']:
46 ctx['theme_books'].append(f.book)
47 if len(ctx['theme_books']) == 3:
51 # Choose collections for main.
52 ctx['collections'] = Collection.objects.filter(listed=True).order_by('?')[:4]
56 recommended_collection = None
57 for recommended in Collection.objects.filter(listed=True, role='recommend').order_by('?'):
58 if recommended_collection is None:
59 recommended_collection = recommended
60 books = list(recommended.get_books().exclude(id__in=[b.id for b in best]).order_by('?')[:best_places])
62 best_places -= len(books)
65 ctx['recommended_collection'] = recommended_collection
69 Book.objects.filter(findable=True).exclude(id__in=[b.id for b in best]).order_by('?')[:best_places]
74 return render(request, "main_page.html", ctx)
77 class WLLoginView(LoginView):
78 form_class = WLAuthenticationForm
81 wl_login_view = WLLoginView.as_view()
84 class LoginFormView(AjaxableFormView):
85 form_class = AuthenticationForm
86 template = "auth/login.html"
92 def __call__(self, request):
93 if request.EXPERIMENTS['layout'].value:
94 return wl_login_view(request)
96 if request.user.is_authenticated:
97 return self.redirect_or_refresh(
99 message=_('Already logged in as user %(user)s', ) % {'user': request.user.username})
100 return super(LoginFormView, self).__call__(request)
102 def success(self, form, request):
103 auth.login(request, form.get_user())
106 class WLRegisterView(FormView):
107 form_class = RegistrationForm
108 template_name = 'registration/register.html'
110 wl_register_view = WLRegisterView.as_view()
113 class RegisterFormView(AjaxableFormView):
114 form_class = RegistrationForm
115 template = "auth/register.html"
117 title = _('Register')
118 submit = _('Register')
120 form_prefix = 'register'
123 def __call__(self, request):
124 if request.EXPERIMENTS['layout'].value:
125 return wl_register_view(request)
127 if request.user.is_authenticated:
128 return self.redirect_or_refresh(
130 message=_('Already logged in as user %(user)s', ) % {'user': request.user.username})
131 return super(RegisterFormView, self).__call__(request)
133 def success(self, form, request):
135 user = auth.authenticate(
136 username=form.cleaned_data['username'],
137 password=form.cleaned_data['password1']
139 auth.login(request, user)
142 class LoginRegisterFormView(LoginFormView):
143 template = 'auth/login_register.html'
144 title = _('You have to be logged in to continue')
146 def extra_context(self, request, obj):
148 "register_form": placeholdized(RegistrationForm(prefix='register')),
149 "register_submit": _('Register'),
154 def logout_then_redirect(request):
156 return HttpResponseRedirect(quote_plus(request.GET.get('next', '/'), safe='/?='))
161 """ Provides server UTC time for jquery.countdown,
162 in a format suitable for Date.parse()
164 return HttpResponse(datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S UTC'))
167 def publish_plan(request):
168 cache_key = "publish_plan"
169 plan = cache.get(cache_key)
174 feed = feedparser.parse(settings.PUBLISH_PLAN_FEED)
178 for i in range(len(feed['entries'])):
180 'title': feed['entries'][i].title,
181 'link': feed['entries'][i].link,
183 cache.set(cache_key, plan, 1800)
185 return render(request, "publish_plan.html", {'plan': plan})
189 def user_settings(request):
190 return render(request, "user.html")
194 return render(request, 'widget.html')
197 class SocialSignupView(SignupView):
198 form_class = SocialSignupForm
201 def exception_test(request):
202 msg = request.GET.get('msg')
204 raise Exception('Exception test: %s' % msg)
206 raise Exception('Exception test')
209 def post_test(request):
210 return render(request, 'post_test.html', {'action': '/api/reading/jego-zasady/complete/'})