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
29 def main_page_2022(request):
31 ctx['last_published'] = Book.objects.exclude(cover_clean='').filter(findable=True, parent=None).order_by('-created_at')[:10]
32 ctx['recommended_collection'] = Collection.objects.filter(listed=True, role='recommend').order_by('?').first()
33 ctx['ambassadors'] = club.models.Ambassador.objects.all().order_by('?')
34 ctx['widget'] = settings.WIDGETS.get(request.GET.get('w'))
35 if not ctx['widget'] and request.EXPERIMENTS['sowka'].value:
36 ctx['widget'] = settings.WIDGETS['pan-sowka']
37 return render(request, '2022/main_page.html', ctx)
40 def main_page(request):
41 if request.GET.get('w') in settings.WIDGETS:
42 request.EXPERIMENTS['layout'].override(True)
43 if request.EXPERIMENTS['sowka'].value:
44 request.EXPERIMENTS['layout'].override(True)
46 if request.EXPERIMENTS['layout'].value:
47 return main_page_2022(request)
50 'last_published': Book.objects.exclude(cover_clean='').filter(findable=True, parent=None).order_by('-created_at')[:6],
54 # FIXME: find this theme and books properly.
55 if Fragment.objects.exists():
57 ctx['theme'] = Tag.objects.filter(category='theme').order_by('?')[:1][0]
58 tf = Fragment.tagged.with_any([ctx['theme']]).select_related('book').filter(book__findable=True).order_by('?')[:100]
61 ctx['theme_fragment'] = tf[0]
63 if f.book not in ctx['theme_books']:
64 ctx['theme_books'].append(f.book)
65 if len(ctx['theme_books']) == 3:
69 # Choose collections for main.
70 ctx['collections'] = Collection.objects.filter(listed=True).order_by('?')[:4]
74 recommended_collection = None
75 for recommended in Collection.objects.filter(listed=True, role='recommend').order_by('?'):
76 if recommended_collection is None:
77 recommended_collection = recommended
78 books = list(recommended.get_books().exclude(id__in=[b.id for b in best]).order_by('?')[:best_places])
80 best_places -= len(books)
83 ctx['recommended_collection'] = recommended_collection
87 Book.objects.filter(findable=True).exclude(id__in=[b.id for b in best]).order_by('?')[:best_places]
92 return render(request, "main_page.html", ctx)
95 class WLLoginView(LoginView):
96 form_class = WLAuthenticationForm
99 wl_login_view = WLLoginView.as_view()
102 class LoginFormView(AjaxableFormView):
103 form_class = AuthenticationForm
104 template = "auth/login.html"
107 submit = _('Sign in')
110 def __call__(self, request):
111 if request.EXPERIMENTS['layout'].value:
112 return wl_login_view(request)
114 if request.user.is_authenticated:
115 return self.redirect_or_refresh(
117 message=_('Already logged in as user %(user)s', ) % {'user': request.user.username})
118 return super(LoginFormView, self).__call__(request)
120 def success(self, form, request):
121 auth.login(request, form.get_user())
124 class WLRegisterView(FormView):
125 form_class = RegistrationForm
126 template_name = 'registration/register.html'
128 def form_valid(self, form):
130 user = auth.authenticate(
131 username=form.cleaned_data['username'],
132 password=form.cleaned_data['password1']
134 auth.login(self.request, user)
135 return HttpResponseRedirect(quote_plus(self.request.GET.get('next', '/'), safe='/?='))
137 wl_register_view = WLRegisterView.as_view()
140 class RegisterFormView(AjaxableFormView):
141 form_class = RegistrationForm
142 template = "auth/register.html"
144 title = _('Register')
145 submit = _('Register')
147 form_prefix = 'register'
150 def __call__(self, request):
151 if request.EXPERIMENTS['layout'].value:
152 return wl_register_view(request)
154 if request.user.is_authenticated:
155 return self.redirect_or_refresh(
157 message=_('Already logged in as user %(user)s', ) % {'user': request.user.username})
158 return super(RegisterFormView, self).__call__(request)
160 def success(self, form, request):
162 user = auth.authenticate(
163 username=form.cleaned_data['username'],
164 password=form.cleaned_data['password1']
166 auth.login(request, user)
169 class LoginRegisterFormView(LoginFormView):
170 template = 'auth/login_register.html'
171 title = _('You have to be logged in to continue')
173 def extra_context(self, request, obj):
175 "register_form": placeholdized(RegistrationForm(prefix='register')),
176 "register_submit": _('Register'),
181 def logout_then_redirect(request):
183 return HttpResponseRedirect(quote_plus(request.GET.get('next', '/'), safe='/?='))
188 """ Provides server UTC time for jquery.countdown,
189 in a format suitable for Date.parse()
191 return HttpResponse(datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S UTC'))
194 def publish_plan(request):
195 cache_key = "publish_plan"
196 plan = cache.get(cache_key)
201 feed = feedparser.parse(settings.PUBLISH_PLAN_FEED)
205 for i in range(len(feed['entries'])):
207 'title': feed['entries'][i].title,
208 'link': feed['entries'][i].link,
210 cache.set(cache_key, plan, 1800)
212 return render(request, "publish_plan.html", {'plan': plan})
216 def user_settings(request):
217 return render(request, "user.html")
221 return render(request, 'widget.html')
224 class SocialSignupView(SignupView):
225 form_class = SocialSignupForm
228 def exception_test(request):
229 msg = request.GET.get('msg')
231 raise Exception('Exception test: %s' % msg)
233 raise Exception('Exception test')
236 def post_test(request):
237 return render(request, 'post_test.html', {'action': '/api/reading/jego-zasady/complete/'})