Browse Source

První dokumentace

okenkove_obalky
Jonas Havelka 2 years ago
parent
commit
5113a7adab
  1. 3
      aesop/apps.py
  2. 7
      aesop/urls.py
  3. 5
      aesop/views.py
  4. 3
      api/apps.py
  5. 12
      api/urls.py
  6. 5
      api/views/__init__.py
  7. 6
      api/views/autocomplete.py
  8. 3
      api/views/exports.py
  9. 3
      api/views/helpers.py
  10. 92
      docs/dalsi_soubory.rst
  11. 55
      docs/default_doc.rst
  12. 1
      docs/index.rst
  13. 3
      docs/sphinx.rst
  14. 9
      galerie/urls.py
  15. 6
      header_fotky/__init__.py
  16. 15
      header_fotky/admin.py
  17. 3
      header_fotky/apps.py
  18. 16
      header_fotky/context_processors.py
  19. 28
      header_fotky/models.py
  20. 5
      korektury/__init__.py
  21. 21
      korektury/admin.py
  22. 11
      korektury/forms.py
  23. 16
      korektury/models.py
  24. 4
      korektury/testutils.py
  25. 8
      korektury/urls.py
  26. 6
      korektury/views.py
  27. 5
      mamweb/admin.py
  28. 17
      mamweb/urls.py
  29. 6
      odevzdavatko/admin.py
  30. 3
      odevzdavatko/apps.py
  31. 14
      odevzdavatko/urls.py
  32. 3
      personalni/apps.py
  33. 14
      personalni/urls.py
  34. 9
      prednasky/urls.py
  35. 6
      seminar/__init__.py
  36. 34
      seminar/urls.py
  37. 3
      soustredeni/apps.py
  38. 3
      treenode/apps.py
  39. 5
      treenode/urls.py
  40. 3
      various/apps.py
  41. 13
      various/autentizace/urls.py
  42. 3
      vysledkovky/apps.py

3
aesop/apps.py

@ -1,3 +1,6 @@
"""
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
"""
from django.apps import AppConfig from django.apps import AppConfig

7
aesop/urls.py

@ -1,3 +1,10 @@
"""
Soubor sloužící jako router, tj. zde se definují url adresy a na co ukazují:
- ``aesop-export/mam-rocnik-<int:prvni_rok>.csv`` (seminar_export_rocnik) :class:`~aesop.views.ExportRocnikView`
- ``aesop-export/mam-sous-<str:datum_zacatku>.csv`` (seminar_export_sous) :class:`~aesop.views.ExportSousView`
- ``aesop-export/index.csv`` (seminar_export_index) :class:`~aesop.views.ExportIndexView`
"""
from django.urls import path from django.urls import path
from aesop import views from aesop import views

5
aesop/views.py

@ -1,3 +1,8 @@
"""
Soubor sloužící k deklaraci jednotlivých views (nejčastěji funkce beroucí request
a vracející :func:`django.shortcuts.render` respektive nějakou response, nebo
třídy většinou rozšiřující nějakou třídu z :mod:`django.views.generic`)
"""
import django import django
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.http import HttpResponse from django.http import HttpResponse

3
api/apps.py

@ -1,3 +1,6 @@
"""
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
"""
from django.apps import AppConfig from django.apps import AppConfig

12
api/urls.py

@ -1,3 +1,15 @@
"""
Soubor sloužící jako router, tj. zde se definují url adresy a na co ukazují:
- ``api/expor/skoly/`` (export_skoly) :func:`~api.views.exports.exportSkolView`
- ``api/autocomplete/skola/`` (autocomplete_skola) :class:`~api.views.autocomplete.SkolaAutocomplete`
- ``api/autocomplete/resitel/`` (autocomplete_resitel) :class:`~api.views.autocomplete.ResitelAutocomplete`
- ``api/autocomplete/problem/odevzdatelny`` (autocomplete_problem_odevzdatelny) :class:`~api.views.autocomplete.OdevzdatelnyProblemAutocomplete`
Na autocomplete v3 čeká:
- ``autocomplete/organizatori/`` (seminar_autocomplete_organizator) :class:`~api.views.autocomplete.OrganizatorAutocomplete`
"""
from django.urls import path from django.urls import path
from . import views from . import views
from seminar.utils import org_required from seminar.utils import org_required

5
api/views/__init__.py

@ -1,2 +1,7 @@
"""
Soubory sloužící k deklaraci jednotlivých views (nejčastěji funkce beroucí request
a vracející :func:`django.shortcuts.render` respektive nějakou response, nebo
třídy většinou rozšiřující nějakou třídu z :mod:`django.views.generic`)
"""
from .autocomplete import * from .autocomplete import *
from .exports import * from .exports import *

6
api/views/autocomplete.py

@ -1,3 +1,6 @@
"""
Views k :mod:`dal.autocomplete` pro vyhledávání objektů nějaké třídy v databázi.
"""
from dal import autocomplete from dal import autocomplete
from django.shortcuts import get_object_or_404 from django.shortcuts import get_object_or_404
from django.db.models import Q from django.db.models import Q
@ -7,6 +10,7 @@ from .helpers import LoginRequiredAjaxMixin
# TODO filosofie - zkratky, jak v databázi, tak ve vyhledávání (SPŠE, GASOŠ, Kpt., soukr) # TODO filosofie - zkratky, jak v databázi, tak ve vyhledávání (SPŠE, GASOŠ, Kpt., soukr)
class SkolaAutocomplete(autocomplete.Select2QuerySetView): class SkolaAutocomplete(autocomplete.Select2QuerySetView):
""" View k :mod:`dal.autocomplete` pro vyhledávání škol hlavně při registraci. """
def get_queryset(self): def get_queryset(self):
# Don't forget to filter out results depending on the visitor ! # Don't forget to filter out results depending on the visitor !
qs = m.Skola.objects.all() qs = m.Skola.objects.all()
@ -25,6 +29,7 @@ class SkolaAutocomplete(autocomplete.Select2QuerySetView):
return qs return qs
class ResitelAutocomplete(LoginRequiredAjaxMixin,autocomplete.Select2QuerySetView): class ResitelAutocomplete(LoginRequiredAjaxMixin,autocomplete.Select2QuerySetView):
""" View k :mod:`dal.autocomplete` pro vyhledávání řešitelů především v odevzdávátku. """
def get_queryset(self): def get_queryset(self):
qs = m.Resitel.objects.all() qs = m.Resitel.objects.all()
if self.q: if self.q:
@ -40,6 +45,7 @@ class ResitelAutocomplete(LoginRequiredAjaxMixin,autocomplete.Select2QuerySetVie
return qs return qs
class OdevzdatelnyProblemAutocomplete(autocomplete.Select2QuerySetView): class OdevzdatelnyProblemAutocomplete(autocomplete.Select2QuerySetView):
""" View k :mod:`dal.autocomplete` pro vyhledávání problémů především v odevzdávátku. """
def get_queryset(self): def get_queryset(self):
nastaveni = get_object_or_404(m.Nastaveni) nastaveni = get_object_or_404(m.Nastaveni)
rocnik = nastaveni.aktualni_rocnik rocnik = nastaveni.aktualni_rocnik

3
api/views/exports.py

@ -2,6 +2,9 @@ import seminar.models as m
from django.core import serializers as ser from django.core import serializers as ser
from django.http import HttpResponse from django.http import HttpResponse
def exportSkolView(request): def exportSkolView(request):
"""
view, který vrací json se seznamem škol, u kterých je uvedeno: 'id', 'izo', 'nazev', 'kratky_nazev', 'ulice', 'mesto', 'psc', 'stat', 'je_zs', 'je_ss'
"""
# Některé fieldy nechceme: Kontaktní osoby, AESOP ID, org poznámky. # Některé fieldy nechceme: Kontaktní osoby, AESOP ID, org poznámky.
fields = ('id', 'izo', 'nazev', 'kratky_nazev', 'ulice', 'mesto', 'psc', 'stat', 'je_zs', 'je_ss') fields = ('id', 'izo', 'nazev', 'kratky_nazev', 'ulice', 'mesto', 'psc', 'stat', 'je_zs', 'je_ss')
# TODO: Použít JSONL, aby protistrana mohla číst po řádkách a nesežralo to tunu paměti úplně hned # TODO: Použít JSONL, aby protistrana mohla číst po řádkách a nesežralo to tunu paměti úplně hned

3
api/views/helpers.py

@ -2,6 +2,9 @@ from django.http import JsonResponse
class LoginRequiredAjaxMixin(object): class LoginRequiredAjaxMixin(object):
"""
Objekt přidávající povinnost být přihlášený k zobrazení daného view.
"""
def dispatch(self, request, *args, **kwargs): 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 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: if not request.user.is_authenticated:

92
docs/dalsi_soubory.rst

@ -0,0 +1,92 @@
Další soubory/složky v kořenovém adresáři
=========================================
media
-----
Složka, kam django nahrává soubory „jako by je nahrávalo do databáze“.
static
------
Složka, kam django nakopíruje všechno ze složek static a pak na to z templatů / kódu jde ukazovat pomocí ``static``.
_git_hooks
----------
Hooky do gitu pro kontrolu Pythoního stylu. Především ``flake8``.
Zbylo tu z minulosti mamwebu.
data
----
Obsahuje data, která patří do databáze, ale jsou přímo součástí webu jako
takového. Aktuálně jsou to statické stránky, meníčko a rozložení obrázků
v pozadí meníčka.
Generuje se za pomocí::
./manage.py dumpdata flatpages > data/flat_new.json
./fix_json.py data/flat_new.json data/flat.json
nebo (v případě meníčka)::
./manage.py dumpdata sitetree --natrual-foreign > data/sitetree_new.json
./fix_json.py data/sitetree_new.json data/sitetree.json
deploy_v2
---------
Věci, které byly potřeba při nasazování nového (2021) webu.
docs
----
Zde je dokumentace webu. Viz :ref:`Sphinx na našem webu`.
setup
-----
Tato složka obsahuje různé konfiguráky potřebné k rozběhnutí webu na serveru.
vue_frontend
------------
Obsahuje první pokusy o editory treenodů ve vue.
.gitignore
----------
Klasické `.gitignore`_
.. _.gitignore: https://git-scm.com/docs/gitignore
checklinks.sh
-------------
„Týrací“ skript na kontrolu, že nic, kam se lze proklikat na webu, nehází chybu.
constraints.txt
---------------
Obsahuje omezení na :ref:`requirements.txt`.
convert_spaces_to_tabs.sh
-------------------------
Skript na změnu odsazování.
db-local.sqlite3
----------------
Lokální databáze (na serveru není).
diff_db_backup.sh
-----------------
Nevím. Typoval bych skript na diff záloh (resp. dumpů) databáze.
Makefile
--------
Klasické `Makefile`_. Obsahuje například vytvoření virtual_env, instalaci a nasazování webu.
.. _Makefile: https://www.gnu.org/software/make/manual/make.html
manage.py
---------
Základní soubor djanga.
README.md
---------
Většina je spíš zbytek po bývalých webařích.
requirements.txt
----------------
Seznam balíčků, které jsou potřeba pro běh mamwebu. (Cílem je vytvoření virtualenvu se všemi těmito balíčky, např. pomocí daného příkazu v :ref:`Makefile`.)

55
docs/default_doc.rst

@ -0,0 +1,55 @@
Defaultní dokumentace speciálních souborů
=========================================
Drobná nápověda k běžným django souborům. (Do nich jsem to vkládal copy-paste.)
admin.py
--------
Soubor sloužící k definici toho, co bude v adminu. Většinou pouhým zavoláním
funkce :func:`django.contrib.admin.site.register`, v případě, že chceme něco
upravit, tak jako třída rozšiřující :class:`django.contrib.admin.ModelAdmin`
s dekorátorem :func:`django.contrib.admin.register`.
Zde se definuje admin pro:
apps.py
-------
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
forms.py
--------
Formuláře (:class:`django.forms.Form`) umožňují jednoduchou tvorbu formulářů,
které lze pak jednoduše dát do frontendu i zpracovat na backendu.
Pro přidání políčka do formuláře je potřeba
- mít v modelu tu položku, kterou chci upravovat
- přidat do views (prihlaskaView, resitelEditView)
- přidat do forms
- includovat do html
models.py
---------
Tento soubor slouží k definici databázového modelu.
Třídy rozšiřují většinou :class:`django.db.models.Model` a jejich atributy jsou
většinou sloupce v databázi (tj. nastaví se na hodnotu něčeho z :mod:`django.db.models`).
Na výběr jsou:
- :class:`django.db.models.TextField`
- :class:`django.db.models.ForeignKey`
- :class:`django.db.models.DateField`
- :class:`django.db.models.DateTimeField`
- :class:`django.db.models.ImageField`
- :class:`django.db.models.CharField`
testutils.py
------------
Soubor sloužící ke generování testdat.
urls.py
-------
Soubor sloužící jako „router“, tj. zde se definují url adresy a na co ukazují:
views.py
--------

1
docs/index.rst

@ -12,6 +12,7 @@ Vítejte v dokumentaci M&Mího webu!
vyvoj vyvoj
sphinx sphinx
dalsi_soubory
modules/modules modules/modules

3
docs/sphinx.rst

@ -6,9 +6,10 @@ Dokumentace se zkompiluje příkazem ``make html`` ve složce ``doc``.
Složka ``modules`` je automaticiky generována a přegenerovávána. (**Nic v ní neupravovat!**) Složka ``modules`` je automaticiky generována a přegenerovávána. (**Nic v ní neupravovat!**)
Jinak všechny rst, co jsou ve složce ``doc`` a jejích podsložkách nezačínajících podtržítkem, budou v dokumentaci a to je přesně to, co editovat pro změnu dokumentace (kromě dokumentace přímo v Pythonu). Jinak všechny rst, co jsou ve složce ``doc`` a jejích podsložkách nezačínajících podtržítkem, budou v dokumentaci a to je přesně to, co editovat pro změnu dokumentace (kromě dokumentace přímo v Pythonu).
Sphinx se píše v rst: `Návod na syntaxi rst`_ Sphinx se píše v rst: `Návod na syntaxi rst`_ `Cheat sheet`_
.. _Návod na syntaxi rst: https://sphinx-tutorial.readthedocs.io/step-1/#sections .. _Návod na syntaxi rst: https://sphinx-tutorial.readthedocs.io/step-1/#sections
.. _Cheat sheet: https://sphinx-tutorial.readthedocs.io/cheatsheet/
Problém Problém
------- -------

9
galerie/urls.py

@ -1,5 +1,12 @@
# coding: utf-8 """
Soubor sloužící jako router, tj. zde se definují url adresy a na co ukazují:
- ``<int:pk>/`` :func:`~galerie.views.nahled`
- ``<int:pk>/<int:fotka>/`` :func:`~galerie.views.detail`
- ``<int:galerie>/new/`` :func:`~galerie.views.new_galerie`
- ``<int:galerie>/plus/<int:subgalerie>/`` :func:`~galerie.views.plus_galerie`
- ``<int:galerie>/minus/<int:subgalerie>/`` :func:`~galerie.views.minus_galerie`
"""
from django.urls import path from django.urls import path
from seminar.utils import org_required from seminar.utils import org_required
from . import views from . import views

6
header_fotky/__init__.py

@ -0,0 +1,6 @@
"""
Aplikace umožňující na uživatelské úrovni měnit obrázek v pozadí meníčka.
Umožňuje uložit obrázek a následně popsat, na kterých stránkách (podle url)
a v který čas (den/noc) se zobrazovat.
"""

15
header_fotky/admin.py

@ -1,9 +1,24 @@
"""
Soubor sloužící k definici toho, co bude v adminu. Většinou pouhým zavoláním
funkce :func:`django.contrib.admin.site.register`, v případě, že chceme něco
upravit, tak jako třída rozšiřující :class:`django.contrib.admin.ModelAdmin`
s dekorátorem :func:`django.contrib.admin.register`.
Zde se definuje admin pro:
- :class:`~header_fotky.models.FotkaHeader`
- :class:`~header_fotky.models.FotkaUrlVazba`
"""
from django.contrib import admin from django.contrib import admin
from django.contrib.admin import ModelAdmin from django.contrib.admin import ModelAdmin
import header_fotky.models as m import header_fotky.models as m
class FotkaPozadiAdmin(ModelAdmin): class FotkaPozadiAdmin(ModelAdmin):
"""
Nastaví čas vložení (:attr:`~header_fotky.models.FotkaHeader.cas`) jako
readonly = neměnitelný
"""
readonly_fields = ['cas'] readonly_fields = ['cas']
admin.site.register(m.FotkaHeader, FotkaPozadiAdmin) admin.site.register(m.FotkaHeader, FotkaPozadiAdmin)

3
header_fotky/apps.py

@ -1,3 +1,6 @@
"""
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
"""
from django.apps import AppConfig from django.apps import AppConfig

16
header_fotky/context_processors.py

@ -1,4 +1,8 @@
"""
Context processory lze přidat do djanga v :mod:`~mamweb.settings` a dělají to,
že do contextu (tj. to, z čeho se např. berou proměnné v templatech) libovolné
stránky přidají další věci.
"""
from datetime import datetime, date from datetime import datetime, date
import random import random
@ -8,7 +12,15 @@ from header_fotky.models import FotkaUrlVazba
def vzhled(request): def vzhled(request):
''' Podle casu prida do templatu, zdali je nebo neni noc ''' """
Podle času přidá do contextu, zdali je nebo není noc. Dále podle dení
doby a url přidá do contextu správnou fotku.
url adresu nejprve vyzkouší celou, pak postupně odřezává věci za
lomítkem, dokud nenajde url, pro kterou existuje alespoň jedna fotka.
Z fotek pro toto url zkusí vybrat tu ve správné denní době a poté
libovolnou. (Z více možných fotek pro 1 url a 1 dobu vybírá náhodně.)
"""
hodin = datetime.now().hour hodin = datetime.now().hour
if (hodin <= 6) or (hodin >= 20): if (hodin <= 6) or (hodin >= 20):
noc = True noc = True

28
header_fotky/models.py

@ -1,9 +1,24 @@
"""
Tento soubor slouží k definici databázového modelu.
Třídy rozšiřují většinou :class:`django.db.models.Model` a jejich atributy jsou
většinou sloupce v databázi (tj. nastaví se na hodnotu něčeho z :mod:`django.db.models`).
Na výběr jsou:
- :class:`django.db.models.TextField`
- :class:`django.db.models.ForeignKey`
- :class:`django.db.models.DateField`
- :class:`django.db.models.DateTimeField`
- :class:`django.db.models.ImageField`
- :class:`django.db.models.CharField`
"""
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.db import models from django.db import models
from django.utils import timezone from django.utils import timezone
class FotkaHeader(models.Model): class FotkaHeader(models.Model):
""" fotka pro :mod:`fotka_header`, konkrétně :class:`~fotka_header.models.FotkaUrlVazba` """
class Meta: class Meta:
ordering = ['-cas'] ordering = ['-cas']
db_table = 'fotky_header' db_table = 'fotky_header'
@ -11,27 +26,34 @@ class FotkaHeader(models.Model):
verbose_name_plural = u'fotky do pozadí menu' verbose_name_plural = u'fotky do pozadí menu'
cas = models.DateTimeField(u'čas vložení fotky', default=timezone.now, help_text='Čas vložení fotky') cas = models.DateTimeField(u'čas vložení fotky', default=timezone.now, help_text='Čas vložení fotky')
""" čas vložení fotky """
nazev = models.CharField( nazev = models.CharField(
u'název fotky', null=False, blank=False, unique=True, primary_key=True, u'název fotky', null=False, blank=False, unique=True, primary_key=True,
max_length=50, help_text='Název např. archiv_noc' max_length=50, help_text='Název např. archiv_noc'
) )
""" jméno fotky na webu """
fotka = models.ImageField(upload_to='header', null=False, blank=False) fotka = models.ImageField(upload_to='header', null=False, blank=False)
""" soubor fotky (Nahrává se automaticky do složky ``media``.) """
def __str__(self): def __str__(self):
return self.nazev return self.nazev
def clean(self): def clean(self):
""" kontroluje, zda sedí poměr stran """
if not self.fotka: if not self.fotka:
raise ValidationError("Chybí obrázek") raise ValidationError("Chybí obrázek")
""" Kontroluje, zda sedí poměr stran """
if abs(self.fotka.width - (self.fotka.height * 970 / 350)) > 2: if abs(self.fotka.width - (self.fotka.height * 970 / 350)) > 2:
raise ValidationError("Obrázek by měl mít rozměry 970w na 350h, nebo alespoň podobný poměr stran.") raise ValidationError("Obrázek by měl mít rozměry 970w na 350h, nebo alespoň podobný poměr stran.")
super().clean() super().clean()
class FotkaUrlVazba(models.Model): class FotkaUrlVazba(models.Model):
"""
spojení :class:`~fotka_header.models.FotkaHeader` a url
(resp. prefixu url), na které být zobrazována
"""
class Meta: class Meta:
ordering = ['url'] ordering = ['url']
db_table = 'fotky_url_vazby' db_table = 'fotky_url_vazby'
@ -42,11 +64,13 @@ class FotkaUrlVazba(models.Model):
u'URL', blank=True, null=False, max_length=100, u'URL', blank=True, null=False, max_length=100,
help_text='url prefix stránek např: /archiv/ nebo /' help_text='url prefix stránek např: /archiv/ nebo /'
) )
""" url prefix stránek, kde má být fotka zobrazena, např: /archiv/ nebo / """
fotka = models.ForeignKey( fotka = models.ForeignKey(
FotkaHeader, blank=False, null=False, verbose_name='fotka', FotkaHeader, blank=False, null=False, verbose_name='fotka',
on_delete=models.CASCADE on_delete=models.CASCADE
) )
""" :class:`~fotka_header.models.FotkaHeader`, která má být zobrazována """
DOBA_DEN = 'den' DOBA_DEN = 'den'
DOBA_NOC = 'noc' DOBA_NOC = 'noc'
@ -57,9 +81,11 @@ class FotkaUrlVazba(models.Model):
(DOBA_OBOJI, 'Zobrazovat pořád')] (DOBA_OBOJI, 'Zobrazovat pořád')]
denni_doba = models.CharField('denní doba', max_length=16, choices=DOBA_CHOICES, blank=False, default=DOBA_OBOJI) denni_doba = models.CharField('denní doba', max_length=16, choices=DOBA_CHOICES, blank=False, default=DOBA_OBOJI)
""" dení doba, kdy tam má být zobrazována """
def __str__(self): def __str__(self):
return self.url return self.url
def url_fotky(self): def url_fotky(self):
""" vrací url fotky (tj. url, kde reálně získám soubor fotky) """
return self.fotka.fotka.url return self.fotka.fotka.url

5
korektury/__init__.py

@ -0,0 +1,5 @@
"""
Seznam pdf k opravě a `opraf`_ v djangu místo PHP.
.. _opraf: https://github.com/vitstradal/opraf
"""

21
korektury/admin.py

@ -1,3 +1,13 @@
"""
Soubor sloužící k definici toho, co bude v adminu. Většinou pouhým zavoláním
funkce :func:`django.contrib.admin.site.register`, v případě, že chceme něco
upravit, tak jako třída rozšiřující :class:`django.contrib.admin.ModelAdmin`
s dekorátorem :func:`django.contrib.admin.register`.
Zde se definuje admin pro:
- :class:`korektury.models.KorekturovanePDF`
"""
from django.contrib import admin from django.contrib import admin
from reversion.admin import VersionAdmin from reversion.admin import VersionAdmin
from korektury.models import KorekturovanePDF from korektury.models import KorekturovanePDF
@ -7,10 +17,18 @@ from django.urls import reverse
# Register your models here. # Register your models here.
class KorekturovanePDFAdmin(VersionAdmin): class KorekturovanePDFAdmin(VersionAdmin):
"""
nastaví čas vložení (:attr:`~koretkury.models.KorekturovanePDF.cas`) a počet
stran (:attr:`~koretkury.models.KorekturovanePDF.stran`) jako readonly =
neměnitelný
Při prvním uložení pošle e-mail.
"""
readonly_fields = ['cas', 'stran'] readonly_fields = ['cas', 'stran']
def get_readonly_fields(self, request, obj=None): def get_readonly_fields(self, request, obj=None):
""" Nevím, proč to tu je - Jidáš """
if obj: if obj:
return self.readonly_fields + ['pdf'] return self.readonly_fields + ['pdf']
return self.readonly_fields return self.readonly_fields
@ -26,6 +44,9 @@ class KorekturovanePDFAdmin(VersionAdmin):
search_fields = [] search_fields = []
def save_model(self, request, obj, form, change): def save_model(self, request, obj, form, change):
"""
Pokud je soubor nový a se poslat e-mail, tak pošle e-mail o novém pdf.
"""
super().save_model(request, obj, form, change) super().save_model(request, obj, form, change)
if not change and obj.poslat_mail: # Je nový a má se poslat mail if not change and obj.poslat_mail: # Je nový a má se poslat mail
odkaz = request.build_absolute_uri(reverse('korektury', kwargs={'pdf': obj.id})) odkaz = request.build_absolute_uri(reverse('korektury', kwargs={'pdf': obj.id}))

11
korektury/forms.py

@ -1,6 +1,17 @@
"""
Formuláře (:class:`django.forms.Form`) umožňují jednoduchou tvorbu formulářů,
které lze pak jednoduše dát do frontendu i zpracovat na backendu.
Pro přidání políčka do formuláře je potřeba
- mít v modelu tu položku, kterou chci upravovat
- přidat do views (prihlaskaView, resitelEditView)
- přidat do forms
- includovat do html
"""
from django import forms from django import forms
class OpravaForm(forms.Form): class OpravaForm(forms.Form):
""" formulář k přidání opravy (:class:`korektury.models.Oprava`) """
text = forms.CharField(max_length=256) text = forms.CharField(max_length=256)
autor = forms.CharField(max_length=20) autor = forms.CharField(max_length=20)
x = forms.IntegerField() x = forms.IntegerField()

16
korektury/models.py

@ -1,4 +1,17 @@
# -*- coding: utf-8 -*- """
Tento soubor slouží k definici databázového modelu.
Třídy rozšiřují většinou :class:`django.db.models.Model` a jejich atributy jsou
většinou sloupce v databázi (tj. nastaví se na hodnotu něčeho z :mod:`django.db.models`).
Na výběr jsou:
- :class:`django.db.models.TextField`
- :class:`django.db.models.ForeignKey`
- :class:`django.db.models.DateField`
- :class:`django.db.models.DateTimeField`
- :class:`django.db.models.ImageField`
- :class:`django.db.models.CharField`
"""
import os import os
from django.db import models from django.db import models
from django.utils import timezone from django.utils import timezone
@ -16,6 +29,7 @@ from unidecode import unidecode
def generate_filename(self, filename): def generate_filename(self, filename):
""" vyrobí jméno souboru podle původního jména a času nahrátí """
clean = get_valid_filename( clean = get_valid_filename(
unidecode( unidecode(
filename.replace('/', '-').replace('\0', '').replace(":", "_") filename.replace('/', '-').replace('\0', '').replace(":", "_")

4
korektury/testutils.py

@ -1,3 +1,6 @@
"""
Soubor sloužící ke generování testdat.
"""
import logging import logging
import os import os
from shutil import copyfile, rmtree from shutil import copyfile, rmtree
@ -11,6 +14,7 @@ logger = logging.getLogger(__name__)
@transaction.atomic @transaction.atomic
def create_test_pdf(rnd, organizatori): def create_test_pdf(rnd, organizatori):
""" Vyrobí testovací pdf ke korekturování. Nevyrábí korektury! """
logger.info('Vyrábím testovací pdf ke korekturovani') logger.info('Vyrábím testovací pdf ke korekturovani')
try: try:
testpdfs = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'testpdfs') testpdfs = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'testpdfs')

8
korektury/urls.py

@ -1,3 +1,11 @@
"""
Soubor sloužící jako router, tj. zde se definují url adresy a na co ukazují:
- ``korektury/`` (korektury_list) :class:`~korektury.views.KorekturySeskupeneListView`
- ``korektury/neseskupene/`` (korektury_neseskupene_list) :class:`~korektury.views.KorekturyAktualniListView`
- ``korektury/zastarale/`` (korektury_stare_list) :class:`~korektury.views.KorekturyZastaraleListView`
- ``korektury/<int:pdf>/`` (korektury) :class:`~korektury.views.KorekturyView`
"""
from django.urls import path from django.urls import path
from seminar.utils import org_required from seminar.utils import org_required
from . import views from . import views

6
korektury/views.py

@ -1,4 +1,8 @@
# -*- coding: utf-8 -*- """
Soubor sloužící k deklaraci jednotlivých views (nejčastěji funkce beroucí request
a vracející :func:`django.shortcuts.render` respektive nějakou response, nebo
třídy většinou rozšiřující nějakou třídu z :mod:`django.views.generic`)
"""
from django.shortcuts import get_object_or_404, render from django.shortcuts import get_object_or_404, render
from django.views import generic from django.views import generic
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _

5
mamweb/admin.py

@ -1,3 +1,8 @@
"""
Soubor sloužící k úpravě základních vlastností adminu. Zde se do adminu přidává
CKEditor, nastavuje české řazení v adminu a preference (zobrazuje se v seznamu
jako první) adminu k Semináři.
"""
import locale import locale
from django.contrib import admin from django.contrib import admin
from django.contrib.admin import AdminSite from django.contrib.admin import AdminSite

17
mamweb/urls.py

@ -1,3 +1,20 @@
"""
Soubor sloužící jako základní router, tj. zde se includují veškeré ostatní urls:
- ``admin/`` :mod:`django.contrib.admin.site.urls`
- ``ckeditor/`` :mod:`ckeditor_uploader.urls`
- :mod:`seminar.urls`
- :mod:`odevzdavatko.urls`
- :mod:`korektury.urls`
- :mod:`prednasky.urls`
- :mod:`soustredeni.urls`
- :mod:`personalni.urls`
- :mod:`various.autentizace.urls`
- :mod:`api.urls`
- :mod:`treenode.urls`
- :mod:`aesop.urls`
- ``comments_dj/`` :mod:`django_comments.urls`
"""
from django.urls import path, include from django.urls import path, include
from django.contrib.staticfiles.urls import staticfiles_urlpatterns from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.contrib import admin from django.contrib import admin

6
odevzdavatko/admin.py

@ -1,3 +1,9 @@
"""
Soubor sloužící k definici toho, co bude v adminu. Většinou pouhým zavoláním
funkce :func:`django.contrib.admin.site.register`, v případě, že chceme něco
upravit, tak jako třída rozšiřující :class:`django.contrib.admin.ModelAdmin`
s dekorátorem :func:`django.contrib.admin.register`.
"""
from django.contrib import admin from django.contrib import admin
from django_reverse_admin import ReverseModelAdmin from django_reverse_admin import ReverseModelAdmin
import seminar.models as m import seminar.models as m

3
odevzdavatko/apps.py

@ -1,3 +1,6 @@
"""
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
"""
from django.apps import AppConfig from django.apps import AppConfig

14
odevzdavatko/urls.py

@ -1,3 +1,17 @@
"""
Soubor sloužící jako router, tj. zde se definují url adresy a na co ukazují:
- ``org/add_solution`` (seminar_vloz_reseni) :class:`~odevzdavatko.views.PosliReseniView`
- ``resitel/nahraj_reseni`` (seminar_nahraj_reseni) :class:`~odevzdavatko.views.NahrajReseniView`
- ``resitel/odevzdana_reseni/`` (seminar_resitel_odevzdana_reseni) :class:`~odevzdavatko.views.PrehledOdevzdanychReseni`
- ``org/reseni/`` (odevzdavatko_tabulka) :class:`~odevzdavatko.views.TabulkaOdevzdanychReseniView`
- ``org/reseni/rocnik/<int:rocnik>/`` (odevzdavatko_tabulka) :class:`~odevzdavatko.views.TabulkaOdevzdanychReseniView`
- ``org/reseni/<int:problem>/<int:resitel>/`` (odevzdavatko_reseni_resitele_k_problemu) :class:`~odevzdavatko.views.ReseniProblemuView`
- ``org/reseni/<int:pk>/`` (odevzdavatko_detail_reseni) :func:`~seminar.utils.viewMethodSwitch` + :class:`~odevzdavatko.views.DetailReseniView` + :func:`~odevzdavatko.views.hodnoceniReseniView`
- ``org/reseni/all`` :class:`~odevzdavatko.views.SeznamReseniView`
- ``org/reseni/akt`` :class:`~odevzdavatko.views.TabulkaOdevzdanychReseniView`
- ``resitel/reseni/<int:pk>`` (odevzdavatko_resitel_reseni) :class:`~odevzdavatko.views.ResitelReseniView`
"""
from django.urls import path from django.urls import path
from seminar.utils import org_required, resitel_required, viewMethodSwitch, \ from seminar.utils import org_required, resitel_required, viewMethodSwitch, \

3
personalni/apps.py

@ -1,3 +1,6 @@
"""
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
"""
from django.apps import AppConfig from django.apps import AppConfig

14
personalni/urls.py

@ -1,3 +1,17 @@
"""
Soubor sloužící jako router, tj. zde se definují url adresy a na co ukazují:
- ``org/add_solution`` (seminar_vloz_reseni) :class:`~odevzdavatko.views.PosliReseniView`
- ``resitel/nahraj_reseni`` (seminar_nahraj_reseni) :class:`~odevzdavatko.views.NahrajReseniView`
- ``resitel/odevzdana_reseni/`` (seminar_resitel_odevzdana_reseni) :class:`~odevzdavatko.views.PrehledOdevzdanychReseni`
- ``org/reseni/`` (odevzdavatko_tabulka) :class:`~odevzdavatko.views.TabulkaOdevzdanychReseniView`
- ``org/reseni/rocnik/<int:rocnik>/`` (odevzdavatko_tabulka) :class:`~odevzdavatko.views.TabulkaOdevzdanychReseniView`
- ``org/reseni/<int:problem>/<int:resitel>/`` (odevzdavatko_reseni_resitele_k_problemu) :class:`~odevzdavatko.views.ReseniProblemuView`
- ``org/reseni/<int:pk>/`` (odevzdavatko_detail_reseni) :func:`~seminar.utils.viewMethodSwitch` + :class:`~odevzdavatko.views.DetailReseniView` + :func:`~odevzdavatko.views.hodnoceniReseniView`
- ``org/reseni/all`` :class:`~odevzdavatko.views.SeznamReseniView`
- ``org/reseni/akt`` :class:`~odevzdavatko.views.TabulkaOdevzdanychReseniView`
- ``resitel/reseni/<int:pk>`` (odevzdavatko_resitel_reseni) :class:`~odevzdavatko.views.ResitelReseniView`
"""
from django.urls import path from django.urls import path
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from . import views from . import views

9
prednasky/urls.py

@ -1,3 +1,12 @@
"""
Soubor sloužící jako router, tj. zde se definují url adresy a na co ukazují:
- ``prednasky/`` :func:`~prednasky.views.newPrednaska`
- ``prednasky/hotovo`` :func:`~prednasky.views.Prednaska_hotovo`
- ``prednasky/metaseznam_prednasek`` (metaseznam-list) :class:`~prednasky.views.MetaSeznamListView`
- ``prednasky/seznam_prednasek/<int:seznam>/export`` (seznam-export) :func:`~prednasky.views.SeznamExportView`
- ``prednasky/seznam_prednasek/<int:seznam>/`` (seznam-list) :class:`~prednasky.views.SeznamListView`
"""
from django.urls import path from django.urls import path
from seminar.utils import org_required, resitel_required from seminar.utils import org_required, resitel_required
from . import views from . import views

6
seminar/__init__.py

@ -0,0 +1,6 @@
"""
Zde bývalo vše. Teď tu zbývají všechny modely a části webu jako archiv,
přehled orgů, aktuální (k aktuálnímu číslu) věci, titulka a jak řešit.
Také je tu generování testovacích (lokálních) dat.
"""

34
seminar/urls.py

@ -1,3 +1,35 @@
"""
Soubor sloužící jako router, tj. zde se definují url adresy a na co ukazují:
- Organizátoři
- ``o-nas/organizatori/`` (organizatori) :class:`~seminar.views.views_all.CojemamOrganizatoriView`
- ``o-nas/organizatori/organizovali/`` (stari_organizatori) :class:`~seminar.views.views_all.CojemamOrganizatoriStariView`
- Archiv
- ``archiv/rocniky/`` (seminar_archiv_rocniky) :class:`~seminar.views.views_all.ArchivView`
- ``archiv/temata/`` (seminar_archiv_temata) :class:`~seminar.views.views_all.ArchivTemataView`
- ``rocnik/<int:rocnik>/`` (seminar_rocnik) :class:`~seminar.views.views_all.RocnikView`
- ``cislo/<int:rocnik>.<str:cislo>/`` (seminar_cislo) :class:`~seminar.views.views_all.CisloView`
- ``problem/<int:pk>/`` (seminar_problem) :func:`~seminar.views.views_all.problemView`
- Zadání
- ``aktualni/zadani/`` (seminar_aktualni_zadani) :func:`~seminar.views.views_all.AktualniZadaniView`
- ``aktualni/vysledkova-listina/`` (seminar_aktualni_vysledky) :func:`~seminar.views.views_all.ZadaniAktualniVysledkovkaView`
- ``aktualni/rocnik/`` (seminar_aktualni_rocnik) :class:`~seminar.views.views_all.AktualniRocnikRedirectView`
- Články
- ``archiv/clanky/`` (clanky_resitel) :class:`~seminar.views.views_all.ClankyResitelView`
- Orgovské stránky
- ``rocnik/<int:rocnik>/vysledkovka.tex`` (seminar_rocnik_vysledkovka) :class:`~seminar.views.views_all.RocnikVysledkovkaView`
- ``rocnik/<int:rocnik>/resitele.csv`` (seminar_rocnik_resitele_csv) :func:`~seminar.views.views_all.resiteleRocnikuCsvExportView`
- ``cislo/<int:rocnik>.<str:cislo>/vysledkovka.tex`` (seminar_cislo_vysledkovka) :class:`~seminar.views.views_all.CisloVysledkovkaView`
- ``cislo/<int:rocnik>.<str:cislo>/obalky.pdf`` (seminar_cislo_obalky) :func:`~seminar.views.views_all.cisloObalkyView`
- ``cislo/<int:rocnik>.<str:cislo>/tituly.tex`` (seminar_cislo_titul) :func:`~seminar.views.views_all.TitulyView`
- ``stav`` (stav_databaze) :func:`~seminar.views.views_all.StavDatabazeView`
- ``cislo/<int:rocnik>.<str:cislo>/obalkovani`` (seminar_cislo_resitel_obalkovani) :class:`~seminar.views.views_all.ObalkovaniView`
- ``cislo/<int:trocnik>.<str:tcislo>/odmeny/<int:frocnik>.<str:fcislo>/`` (seminar_archiv_odmeny) :class:`~seminar.views.views_all.OdmenyView`
- Další
- `` `` (titulni_strana) :class:`~seminar.views.views_all.TitulniStranaView`
- ``jak-resit/`` (jak_resit) :class:`~seminar.views.views_all.JakResitView`
- ``stare-novinky/`` (stare_novinky) :class:`~seminar.views.views_all.StareNovinkyView`
"""
from django.urls import path, include, re_path from django.urls import path, include, re_path
from . import views from . import views
from .utils import org_required from .utils import org_required
@ -24,7 +56,6 @@ urlpatterns = [
#path('aktualni/temata/', views.ZadaniTemataView, name='seminar_temata'), #path('aktualni/temata/', views.ZadaniTemataView, name='seminar_temata'),
path('aktualni/vysledkova-listina/', views.ZadaniAktualniVysledkovkaView, name='seminar_aktualni_vysledky'), path('aktualni/vysledkova-listina/', views.ZadaniAktualniVysledkovkaView, name='seminar_aktualni_vysledky'),
path('aktualni/rocnik/', views.AktualniRocnikRedirectView.as_view(), name='seminar_aktualni_rocnik'), path('aktualni/rocnik/', views.AktualniRocnikRedirectView.as_view(), name='seminar_aktualni_rocnik'),
path('stare-novinky/', views.StareNovinkyView.as_view(), name='stare_novinky'),
# Clanky # Clanky
path('archiv/clanky/', views.ClankyResitelView.as_view(), name='clanky_resitel'), path('archiv/clanky/', views.ClankyResitelView.as_view(), name='clanky_resitel'),
@ -73,4 +104,5 @@ urlpatterns = [
path('', views.TitulniStranaView.as_view(), name='titulni_strana'), path('', views.TitulniStranaView.as_view(), name='titulni_strana'),
path('jak-resit/', views.JakResitView.as_view(), name='jak_resit'), path('jak-resit/', views.JakResitView.as_view(), name='jak_resit'),
path('stare-novinky/', views.StareNovinkyView.as_view(), name='stare_novinky'),
] ]

3
soustredeni/apps.py

@ -1,3 +1,6 @@
"""
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
"""
from django.apps import AppConfig from django.apps import AppConfig

3
treenode/apps.py

@ -1,3 +1,6 @@
"""
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
"""
from django.apps import AppConfig from django.apps import AppConfig

5
treenode/urls.py

@ -1,3 +1,8 @@
"""
Soubor sloužící jako router, tj. zde se definují url adresy a na co ukazují:
- Zatím tu nic moc není
"""
from django.urls import path, re_path from django.urls import path, re_path
from . import views from . import views

3
various/apps.py

@ -1,3 +1,6 @@
"""
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
"""
from django.apps import AppConfig from django.apps import AppConfig

13
various/autentizace/urls.py

@ -1,3 +1,16 @@
"""
Soubor sloužící jako router, tj. zde se definují url adresy a na co ukazují:
- ``prihlasit/`` (login) :class:`~various.autentizace.views.LoginView`
- ``login/`` :class:`django.views.generic.base.RedirectView` předchozího
- ``odhlasit/`` (logout) :class:`~various.autentizace.views.LogoutView`
- ``logout/`` :class:`django.views.generic.base.RedirectView` předchozího
- ``reset-hesla/`` (reset_password) :class:`~various.autentizace.views.PasswordResetView`
- ``zmena-hesla/`` (change_password) :class:`~various.autentizace.views.PasswordChangeView`
- ``zmena-hesla/2/`` (reset_password_done) :class:`~various.autentizace.views.PasswordResetDoneView`
- ``reset-hesla/potvrzeni/<uidb64>/<token>/`` (reset_password_confirm) :class:`~various.autentizace.views.PasswordResetConfirmView`
- ``reset-hesla/hotovo/`` (reset_password_complete) :class:`~various.autentizace.views.PasswordResetCompleteView`
"""
from django.urls import path from django.urls import path
from . import views from . import views
from django.views.generic.base import RedirectView from django.views.generic.base import RedirectView

3
vysledkovky/apps.py

@ -1,3 +1,6 @@
"""
Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace.
"""
from django.apps import AppConfig from django.apps import AppConfig

Loading…
Cancel
Save