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.http import HttpResponse, HttpResponseRedirect
16 from django.shortcuts import render
17 from django.utils.translation import gettext_lazy as _
18 from django.views.decorators.cache import never_cache
20 from ajaxable.utils import AjaxableFormView
21 from ajaxable.utils import placeholdized
22 from catalogue.models import Book, Collection, Tag, Fragment
24 from social.utils import get_or_choose_cite
25 from wolnelektury.forms import RegistrationForm, SocialSignupForm, WLAuthenticationForm
29 def main_page(request):
31 'last_published': Book.objects.exclude(cover_thumb='').filter(findable=True, parent=None).order_by('-created_at')[:6],
35 # FIXME: find this theme and books properly.
36 if Fragment.objects.exists():
38 ctx['theme'] = Tag.objects.filter(category='theme').order_by('?')[:1][0]
39 tf = Fragment.tagged.with_any([ctx['theme']]).select_related('book').filter(book__findable=True).order_by('?')[:100]
42 ctx['theme_fragment'] = tf[0]
44 if f.book not in ctx['theme_books']:
45 ctx['theme_books'].append(f.book)
46 if len(ctx['theme_books']) == 3:
50 # Choose collections for main.
51 ctx['collections'] = Collection.objects.filter(listed=True).order_by('?')[:4]
55 recommended_collection = None
56 for recommended in Collection.objects.filter(listed=True, role='recommend').order_by('?'):
57 if recommended_collection is None:
58 recommended_collection = recommended
59 books = list(recommended.get_books().exclude(id__in=[b.id for b in best]).order_by('?')[:best_places])
61 best_places -= len(books)
64 ctx['recommended_collection'] = recommended_collection
68 Book.objects.filter(findable=True).exclude(id__in=[b.id for b in best]).order_by('?')[:best_places]
73 return render(request, "main_page.html", ctx)
76 class WLLoginView(LoginView):
77 form_class = WLAuthenticationForm
80 wl_login_view = WLLoginView.as_view()
83 class LoginFormView(AjaxableFormView):
84 form_class = AuthenticationForm
85 template = "auth/login.html"
91 def __call__(self, request):
92 if request.EXPERIMENTS['layout'].value:
93 return wl_login_view(request)
95 if request.user.is_authenticated:
96 return self.redirect_or_refresh(
98 message=_('Already logged in as user %(user)s', ) % {'user': request.user.username})
99 return super(LoginFormView, self).__call__(request)
101 def success(self, form, request):
102 auth.login(request, form.get_user())
105 class RegisterFormView(AjaxableFormView):
106 form_class = RegistrationForm
107 template = "auth/register.html"
109 title = _('Register')
110 submit = _('Register')
112 form_prefix = 'register'
115 def __call__(self, request):
116 if request.user.is_authenticated:
117 return self.redirect_or_refresh(
119 message=_('Already logged in as user %(user)s', ) % {'user': request.user.username})
120 return super(RegisterFormView, self).__call__(request)
122 def success(self, form, request):
124 user = auth.authenticate(
125 username=form.cleaned_data['username'],
126 password=form.cleaned_data['password1']
128 auth.login(request, user)
131 class LoginRegisterFormView(LoginFormView):
132 template = 'auth/login_register.html'
133 title = _('You have to be logged in to continue')
135 def extra_context(self, request, obj):
137 "register_form": placeholdized(RegistrationForm(prefix='register')),
138 "register_submit": _('Register'),
143 def logout_then_redirect(request):
145 return HttpResponseRedirect(quote_plus(request.GET.get('next', '/'), safe='/?='))
150 """ Provides server UTC time for jquery.countdown,
151 in a format suitable for Date.parse()
153 return HttpResponse(datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S UTC'))
156 def publish_plan(request):
157 cache_key = "publish_plan"
158 plan = cache.get(cache_key)
163 feed = feedparser.parse(settings.PUBLISH_PLAN_FEED)
167 for i in range(len(feed['entries'])):
169 'title': feed['entries'][i].title,
170 'link': feed['entries'][i].link,
172 cache.set(cache_key, plan, 1800)
174 return render(request, "publish_plan.html", {'plan': plan})
178 def user_settings(request):
179 return render(request, "user.html")
183 return render(request, 'widget.html')
186 class SocialSignupView(SignupView):
187 form_class = SocialSignupForm
190 def exception_test(request):
191 msg = request.GET.get('msg')
193 raise Exception('Exception test: %s' % msg)
195 raise Exception('Exception test')
198 def post_test(request):
199 return render(request, 'post_test.html', {'action': '/api/reading/jego-zasady/complete/'})