diff --git a/seminar/utils.py b/seminar/utils.py index d910a5b6..3869ffd4 100644 --- a/seminar/utils.py +++ b/seminar/utils.py @@ -4,6 +4,8 @@ import datetime from django.contrib.auth.decorators import user_passes_test from html.parser import HTMLParser +import seminar.models as m + staff_member_required = user_passes_test(lambda u: u.is_staff) class FirstTagParser(HTMLParser): @@ -43,7 +45,6 @@ def from_roman(rom): def seznam_problemu(): - from .models import Problem, Resitel, Rocnik, Reseni, Cislo problemy = [] # Pomocna fce k formatovani problemovych hlasek @@ -65,27 +66,26 @@ def seznam_problemu(): # Duplicita jmen jmena = {} - for r in Resitel.objects.all(): + for r in m.Resitel.objects.all(): j = r.plne_jmeno() if j not in jmena: jmena[j] = [] jmena[j].append(r) for j in jmena: if len(jmena[j]) > 1: - prb(Resitel, u'Duplicitní jméno "%s"' % (j, ), jmena[j]) + prb(m.Resitel, u'Duplicitní jméno "%s"' % (j, ), jmena[j]) # Data maturity a narození - for r in Resitel.objects.all(): + for r in m.Resitel.objects.all(): if not r.rok_maturity: - prb(Resitel, u'Neznámý rok maturity', [r]) + prb(m.Resitel, u'Neznámý rok maturity', [r]) if r.rok_maturity and (r.rok_maturity < 1990 or r.rok_maturity > datetime.date.today().year + 10): - prb(Resitel, u'Podezřelé datum maturity', [r]) + prb(m.Resitel, u'Podezřelé datum maturity', [r]) if r.datum_narozeni and (r.datum_narozeni.year < 1970 or r.datum_narozeni.year > datetime.date.today().year - 12): - prb(Resitel, u'Podezřelé datum narození', [r]) + prb(m.Resitel, u'Podezřelé datum narození', [r]) # if not r.email: # prb(Resitel, u'Neznámý email', [r]) return problemy - diff --git a/seminar/views/__init__.py b/seminar/views/__init__.py new file mode 100644 index 00000000..976a34fe --- /dev/null +++ b/seminar/views/__init__.py @@ -0,0 +1,2 @@ +from .views_all import * +from .autocomplete import * diff --git a/seminar/views/autocomplete.py b/seminar/views/autocomplete.py new file mode 100644 index 00000000..04ddca83 --- /dev/null +++ b/seminar/views/autocomplete.py @@ -0,0 +1,63 @@ +from dal import autocomplete +from django.shortcuts import get_object_or_404 + +import seminar.models as m +from .helpers import LoginRequiredAjaxMixin + +class SkolaAutocomplete(autocomplete.Select2QuerySetView): + def get_queryset(self): + # Don't forget to filter out results depending on the visitor ! + qs = m.Skola.objects.all() + if self.q: + qs = qs.filter( + Q(nazev__istartswith=self.q)| + Q(kratky_nazev__istartswith=self.q)| + Q(ulice__istartswith=self.q)| + Q(mesto__istartswith=self.q)) + + return qs + +class ResitelAutocomplete(LoginRequiredAjaxMixin,autocomplete.Select2QuerySetView): + def get_queryset(self): + qs = m.Resitel.objects.all() + if self.q: + qs = qs.filter( + Q(osoba__jmeno__startswith=self.q)| + Q(osoba__prijmeni__startswith=self.q)| + Q(osoba__prezdivka__startswith=self.q) + ) + return qs + +class OdevzdatelnyProblemAutocomplete(autocomplete.Select2QuerySetView): + def get_queryset(self): + nastaveni = get_object_or_404(m.Nastaveni) + rocnik = nastaveni.aktualni_rocnik + temata = m.Tema.objects.filter(rocnik=rocnik, stav=m.Problem.STAV_ZADANY) + ulohy = m.Uloha.objects.filter(cislo_deadline__rocnik = rocnik) + ulohy.union(temata) + qs = ulohy + if self.q: + qs = qs.filter( + Q(nazev__startswith=self.q)) + return qs + +# Ceka na autocomplete v3 +# class OrganizatorAutocomplete(autocomplete.Select2QuerySetView): +# def get_queryset(self): +# if not self.request.user.is_authenticated(): +# return Organizator.objects.none() +# +# qs = aktivniOrganizatori() +# +# if self.q: +# if self.q[0] == "!": +# qs = Organizator.objects.all() +# query = self.q[1:] +# else: +# query = self.q +# qs = qs.filter( +# Q(prezdivka__isstartswith=query)| +# Q(user__first_name__isstartswith=query)| +# Q(user__last_name__isstartswith=query)) +# +# return qs diff --git a/seminar/views/helpers.py b/seminar/views/helpers.py new file mode 100644 index 00000000..0b06c0eb --- /dev/null +++ b/seminar/views/helpers.py @@ -0,0 +1,8 @@ +from dal import autocomplete + +class LoginRequiredAjaxMixin(object): + def dispatch(self, request, *args, **kwargs): + #if request.is_ajax() and not request.user.is_authenticated: # Pokud to otevřu jako stránku, tak se omezení neuplatní, takže to asi nechceme + if not request.user.is_authenticated: + return JsonResponse(data={'results': [], 'pagination': {}}, status=401) + return super(LoginRequiredAjaxMixin, self).dispatch(request, *args, **kwargs) diff --git a/seminar/unicodecsv.py b/seminar/views/unicodecsv.py similarity index 100% rename from seminar/unicodecsv.py rename to seminar/views/unicodecsv.py diff --git a/seminar/views/utils.py b/seminar/views/utils.py new file mode 100644 index 00000000..3869ffd4 --- /dev/null +++ b/seminar/views/utils.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- + +import datetime +from django.contrib.auth.decorators import user_passes_test +from html.parser import HTMLParser + +import seminar.models as m + +staff_member_required = user_passes_test(lambda u: u.is_staff) + +class FirstTagParser(HTMLParser): + def __init__(self, *args, **kwargs): + self.firstTag = None + super().__init__(*args, **kwargs) + def handle_data(self, data): + if self.firstTag == None: + self.firstTag = data + +def histogram(seznam): + d = {} + for i in seznam: + if i not in d: + d[i] = 0 + d[i] += 1 + return d + + +roman_numerals = zip((1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1), + ('M', 'CM', 'D', 'CD','C', 'XC','L','XL','X','IX','V','IV','I')) + +def roman(num): + res = "" + for i, n in roman_numerals: + res += n * (num // i) + num %= i + return res + +def from_roman(rom): + if not rom: + return 0 + for i, n in roman_numerals: + if rom.upper().startswith(n): + return i + from_roman(rom[len(n):]) + raise Exception('Invalid roman numeral: "%s"', rom) + + +def seznam_problemu(): + problemy = [] + + # Pomocna fce k formatovani problemovych hlasek + def prb(cls, msg, objs=None): + s = u'%s: %s' % (cls.__name__, msg) + if objs: + s += u' [' + for o in objs: + try: + url = o.admin_url() + except: + url = None + if url: + s += u'%s, ' % (url, o.pk, ) + else: + s += u'%s, ' % (o.pk, ) + s = s[:-2] + u']' + problemy.append(s) + + # Duplicita jmen + jmena = {} + for r in m.Resitel.objects.all(): + j = r.plne_jmeno() + if j not in jmena: + jmena[j] = [] + jmena[j].append(r) + for j in jmena: + if len(jmena[j]) > 1: + prb(m.Resitel, u'Duplicitní jméno "%s"' % (j, ), jmena[j]) + + # Data maturity a narození + for r in m.Resitel.objects.all(): + if not r.rok_maturity: + prb(m.Resitel, u'Neznámý rok maturity', [r]) + if r.rok_maturity and (r.rok_maturity < 1990 or r.rok_maturity > datetime.date.today().year + 10): + prb(m.Resitel, u'Podezřelé datum maturity', [r]) + if r.datum_narozeni and (r.datum_narozeni.year < 1970 or r.datum_narozeni.year > datetime.date.today().year - 12): + prb(m.Resitel, u'Podezřelé datum narození', [r]) +# if not r.email: +# prb(Resitel, u'Neznámý email', [r]) + + return problemy + + diff --git a/seminar/views.py b/seminar/views/views_all.py similarity index 95% rename from seminar/views.py rename to seminar/views/views_all.py index 36320ba3..3cfb0535 100644 --- a/seminar/views.py +++ b/seminar/views/views_all.py @@ -15,14 +15,13 @@ from django.contrib.auth import views as auth_views from django.contrib.auth.models import User from django.contrib.auth.mixins import LoginRequiredMixin from django.db import transaction -from dal import autocomplete import seminar.models as s -from .models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Organizator, Resitel, Novinky, Soustredeni_Ucastnici, Pohadka, Tema, Clanek, Osoba, Skola # Tohle je stare a chceme se toho zbavit. Pouzivejte s.ToCoChci +from seminar.models import Problem, Cislo, Reseni, Nastaveni, Rocnik, Soustredeni, Organizator, Resitel, Novinky, Soustredeni_Ucastnici, Pohadka, Tema, Clanek, Osoba, Skola # Tohle je stare a chceme se toho zbavit. Pouzivejte s.ToCoChci #from .models import VysledkyZaCislo, VysledkyKCisluZaRocnik, VysledkyKCisluOdjakziva -from . import utils +from seminar import utils from .unicodecsv import UnicodeWriter -from .forms import PrihlaskaForm, LoginForm, ProfileEditForm +from seminar.forms import PrihlaskaForm, LoginForm, ProfileEditForm import seminar.forms as f from datetime import timedelta, date, datetime @@ -1354,71 +1353,9 @@ def prihlaskaView(request): return render(request, 'seminar/prihlaska.html', {'form': form}) -class SkolaAutocomplete(autocomplete.Select2QuerySetView): - def get_queryset(self): - # Don't forget to filter out results depending on the visitor ! - qs = Skola.objects.all() - if self.q: - qs = qs.filter( - Q(nazev__istartswith=self.q)| - Q(kratky_nazev__istartswith=self.q)| - Q(ulice__istartswith=self.q)| - Q(mesto__istartswith=self.q)) - - return qs -class LoginRequiredAjaxMixin(object): - def dispatch(self, request, *args, **kwargs): - #if request.is_ajax() and not request.user.is_authenticated: # Pokud to otevřu jako stránku, tak se omezení neuplatní, takže to asi nechceme - if not request.user.is_authenticated: - return JsonResponse(data={'results': [], 'pagination': {}}, status=401) - return super(LoginRequiredAjaxMixin, self).dispatch(request, *args, **kwargs) -class ResitelAutocomplete(LoginRequiredAjaxMixin,autocomplete.Select2QuerySetView): - def get_queryset(self): - qs = Resitel.objects.all() - if self.q: - qs = qs.filter( - Q(osoba__jmeno__startswith=self.q)| - Q(osoba__prijmeni__startswith=self.q)| - Q(osoba__prezdivka__startswith=self.q) - ) - return qs -class OdevzdatelnyProblemAutocomplete(autocomplete.Select2QuerySetView): - def get_queryset(self): - nastaveni = get_object_or_404(Nastaveni) - rocnik = nastaveni.aktualni_rocnik - temata = s.Tema.objects.filter(rocnik=rocnik, stav=s.Problem.STAV_ZADANY) - ulohy = s.Uloha.objects.filter(cislo_deadline__rocnik = rocnik) - ulohy.union(temata) - qs = ulohy - if self.q: - qs = qs.filter( - Q(nazev__startswith=self.q)) - return qs - - -# Ceka na autocomplete v3 -# class OrganizatorAutocomplete(autocomplete.Select2QuerySetView): -# def get_queryset(self): -# if not self.request.user.is_authenticated(): -# return Organizator.objects.none() -# -# qs = aktivniOrganizatori() -# -# if self.q: -# if self.q[0] == "!": -# qs = Organizator.objects.all() -# query = self.q[1:] -# else: -# query = self.q -# qs = qs.filter( -# Q(prezdivka__isstartswith=query)| -# Q(user__first_name__isstartswith=query)| -# Q(user__last_name__isstartswith=query)) -# -# return qs # FIXME: Tohle asi vlastně vůbec nepatří do aplikace 'seminar' class LoginView(auth_views.LoginView):