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 return render(request, '2022/main_page.html', ctx)
37 def main_page(request):
38 if request.EXPERIMENTS['layout'].value:
39 return main_page_2022(request)
42 'last_published': Book.objects.exclude(cover_thumb='').filter(findable=True, parent=None).order_by('-created_at')[:6],
46 # FIXME: find this theme and books properly.
47 if Fragment.objects.exists():
49 ctx['theme'] = Tag.objects.filter(category='theme').order_by('?')[:1][0]
50 tf = Fragment.tagged.with_any([ctx['theme']]).select_related('book').filter(book__findable=True).order_by('?')[:100]
53 ctx['theme_fragment'] = tf[0]
55 if f.book not in ctx['theme_books']:
56 ctx['theme_books'].append(f.book)
57 if len(ctx['theme_books']) == 3:
61 # Choose collections for main.
62 ctx['collections'] = Collection.objects.filter(listed=True).order_by('?')[:4]
66 recommended_collection = None
67 for recommended in Collection.objects.filter(listed=True, role='recommend').order_by('?'):
68 if recommended_collection is None:
69 recommended_collection = recommended
70 books = list(recommended.get_books().exclude(id__in=[b.id for b in best]).order_by('?')[:best_places])
72 best_places -= len(books)
75 ctx['recommended_collection'] = recommended_collection
79 Book.objects.filter(findable=True).exclude(id__in=[b.id for b in best]).order_by('?')[:best_places]
84 return render(request, "main_page.html", ctx)
87 class WLLoginView(LoginView):
88 form_class = WLAuthenticationForm
91 wl_login_view = WLLoginView.as_view()
94 class LoginFormView(AjaxableFormView):
95 form_class = AuthenticationForm
96 template = "auth/login.html"
102 def __call__(self, request):
103 if request.EXPERIMENTS['layout'].value:
104 return wl_login_view(request)
106 if request.user.is_authenticated:
107 return self.redirect_or_refresh(
109 message=_('Already logged in as user %(user)s', ) % {'user': request.user.username})
110 return super(LoginFormView, self).__call__(request)
112 def success(self, form, request):
113 auth.login(request, form.get_user())
116 class WLRegisterView(FormView):
117 form_class = RegistrationForm
118 template_name = 'registration/register.html'
120 wl_register_view = WLRegisterView.as_view()
123 class RegisterFormView(AjaxableFormView):
124 form_class = RegistrationForm
125 template = "auth/register.html"
127 title = _('Register')
128 submit = _('Register')
130 form_prefix = 'register'
133 def __call__(self, request):
134 if request.EXPERIMENTS['layout'].value:
135 return wl_register_view(request)
137 if request.user.is_authenticated:
138 return self.redirect_or_refresh(
140 message=_('Already logged in as user %(user)s', ) % {'user': request.user.username})
141 return super(RegisterFormView, self).__call__(request)
143 def success(self, form, request):
145 user = auth.authenticate(
146 username=form.cleaned_data['username'],
147 password=form.cleaned_data['password1']
149 auth.login(request, user)
152 class LoginRegisterFormView(LoginFormView):
153 template = 'auth/login_register.html'
154 title = _('You have to be logged in to continue')
156 def extra_context(self, request, obj):
158 "register_form": placeholdized(RegistrationForm(prefix='register')),
159 "register_submit": _('Register'),
164 def logout_then_redirect(request):
166 return HttpResponseRedirect(quote_plus(request.GET.get('next', '/'), safe='/?='))
171 """ Provides server UTC time for jquery.countdown,
172 in a format suitable for Date.parse()
174 return HttpResponse(datetime.utcnow().strftime('%Y/%m/%d %H:%M:%S UTC'))
177 def publish_plan(request):
178 cache_key = "publish_plan"
179 plan = cache.get(cache_key)
184 feed = feedparser.parse(settings.PUBLISH_PLAN_FEED)
188 for i in range(len(feed['entries'])):
190 'title': feed['entries'][i].title,
191 'link': feed['entries'][i].link,
193 cache.set(cache_key, plan, 1800)
195 return render(request, "publish_plan.html", {'plan': plan})
199 def user_settings(request):
200 return render(request, "user.html")
204 return render(request, 'widget.html')
207 class SocialSignupView(SignupView):
208 form_class = SocialSignupForm
211 def exception_test(request):
212 msg = request.GET.get('msg')
214 raise Exception('Exception test: %s' % msg)
216 raise Exception('Exception test')
219 def post_test(request):
220 return render(request, 'post_test.html', {'action': '/api/reading/jego-zasady/complete/'})