Browse Source

Merge branch 'sphinx_test' into develop

okenkove_obalky
Jonas Havelka 3 years ago
parent
commit
7956a88568
  1. 4
      .gitignore
  2. 3
      aesop/apps.py
  3. 7
      aesop/urls.py
  4. 5
      aesop/views.py
  5. 3
      api/apps.py
  6. 12
      api/urls.py
  7. 5
      api/views/__init__.py
  8. 6
      api/views/autocomplete.py
  9. 3
      api/views/exports.py
  10. 3
      api/views/helpers.py
  11. 21
      docs/Makefile
  12. 8
      docs/_templates/module.rst_t
  13. 57
      docs/_templates/package.rst_t
  14. 7
      docs/_templates/toc.rst_t
  15. 87
      docs/conf.py
  16. 92
      docs/dalsi_soubory.rst
  17. 55
      docs/default_doc.rst
  18. 26
      docs/index.rst
  19. 37
      docs/sphinx.rst
  20. 20
      docs/vyvoj.rst
  21. 5
      docs/zapisy/zapisy.rst
  22. 9
      galerie/urls.py
  23. 6
      header_fotky/__init__.py
  24. 15
      header_fotky/admin.py
  25. 3
      header_fotky/apps.py
  26. 16
      header_fotky/context_processors.py
  27. 28
      header_fotky/models.py
  28. 5
      korektury/__init__.py
  29. 21
      korektury/admin.py
  30. 11
      korektury/forms.py
  31. 16
      korektury/models.py
  32. 4
      korektury/testutils.py
  33. 8
      korektury/urls.py
  34. 6
      korektury/views.py
  35. 5
      mamweb/admin.py
  36. 17
      mamweb/urls.py
  37. 6
      odevzdavatko/admin.py
  38. 3
      odevzdavatko/apps.py
  39. 14
      odevzdavatko/urls.py
  40. 3
      personalni/apps.py
  41. 14
      personalni/urls.py
  42. 9
      prednasky/urls.py
  43. 5
      requirements.txt
  44. 6
      seminar/__init__.py
  45. 34
      seminar/urls.py
  46. 3
      soustredeni/apps.py
  47. 3
      treenode/apps.py
  48. 5
      treenode/urls.py
  49. 3
      various/apps.py
  50. 13
      various/autentizace/urls.py
  51. 3
      vysledkovky/apps.py

4
.gitignore

@ -33,3 +33,7 @@ TODO
# pro lidi, co programují v nástrojích od JetBrains
.idea
# dokumentace
docs/_build
docs/modules

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

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 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
from django.shortcuts import get_object_or_404
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

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 . import views
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 .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 django.shortcuts import get_object_or_404
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)
class SkolaAutocomplete(autocomplete.Select2QuerySetView):
""" View k :mod:`dal.autocomplete` pro vyhledávání škol hlavně při registraci. """
def get_queryset(self):
# Don't forget to filter out results depending on the visitor !
qs = m.Skola.objects.all()
@ -25,6 +29,7 @@ class SkolaAutocomplete(autocomplete.Select2QuerySetView):
return qs
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):
qs = m.Resitel.objects.all()
if self.q:
@ -40,6 +45,7 @@ class ResitelAutocomplete(LoginRequiredAjaxMixin,autocomplete.Select2QuerySetVie
return qs
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):
nastaveni = get_object_or_404(m.Nastaveni)
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.http import HttpResponse
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.
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

3
api/views/helpers.py

@ -2,6 +2,9 @@ from django.http import JsonResponse
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):
#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:

21
docs/Makefile

@ -0,0 +1,21 @@
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
sphinx-apidoc --module-first -o modules .. ../*/migrations --templatedir _templates -f
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

8
docs/_templates/module.rst_t

@ -0,0 +1,8 @@
{%- if show_headings %}
{{- [basename, ".py"] | join('') | e | heading }}
{% endif -%}
.. automodule:: {{ qualname }}
{%- for option in automodule_options %}
:{{ option }}:
{%- endfor %}

57
docs/_templates/package.rst_t

@ -0,0 +1,57 @@
{%- macro automodule(modname, options) -%}
.. automodule:: {{ modname }}
{%- for option in options %}
:{{ option }}:
{%- endfor %}
{%- endmacro %}
{%- macro toctree(docnames) -%}
.. toctree::
:maxdepth: {{ maxdepth }}
{% for docname in docnames %}
{{ docname }}
{%- endfor %}
{%- endmacro %}
{%- if is_namespace %}
{{- pkgname | e | heading }}
{% else %}
{{- pkgname | e | heading }}
{% endif %}
{%- if is_namespace %}
.. py:module:: {{ pkgname }}
{% endif %}
{%- if modulefirst and not is_namespace %}
{{ automodule(pkgname, automodule_options) }}
{% endif %}
{%- if subpackages %}
{# Subpackages #}
{# ----------- #}
{{ toctree(subpackages) }}
{% endif %}
{%- if submodules %}
{# Submodules #}
{# ---------- #}
{% if separatemodules %}
{{ toctree(submodules) }}
{% else %}
{%- for submodule in submodules %}
{% if show_headings %}
{{- submodule | e | heading(2) }}
{% endif %}
{{ automodule(submodule, automodule_options) }}
{% endfor %}
{%- endif %}
{%- endif %}
{%- if not modulefirst and not is_namespace %}
Module contents
---------------
{{ automodule(pkgname, automodule_options) }}
{% endif %}

7
docs/_templates/toc.rst_t

@ -0,0 +1,7 @@
{{ "Seznam aplikací" | heading }}
.. toctree::
:maxdepth: {{ maxdepth }}
{% for docname in docnames %}
{{ docname }}
{%- endfor %}

87
docs/conf.py

@ -0,0 +1,87 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
import django
sys.path.insert(0, os.path.abspath('..'))
os.environ['DJANGO_SETTINGS_MODULE'] = 'mamweb.settings'
django.setup()
# -- Project information -----------------------------------------------------
project = 'Web M&M'
copyright = '2022, Orgové'
author = 'Orgové'
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.viewcode',
'sphinx.ext.intersphinx',
'sphinx.ext.autosectionlabel',
'myst_parser',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
language = 'cs'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
import sphinx_rtd_theme
html_theme = 'sphinx_rtd_theme'
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']
# Provázání s jinými dokumentacemi
intersphinx_mapping = {'python': ('https://docs.python.org/3', None),
'django': ('http://docs.djangoproject.com/en/3.2/',
'http://docs.djangoproject.com/en/3.2/_objects/'),}
# Generování tříd/funkcí/atributů v pořádí jak jsou naprogramované
autodoc_member_order = "bysource"
# Nezobrazování zděděné (ze super tříd) dokumentace TODO nefunguje?
autodoc_inherit_docstrings = False
source_suffix = {
'.rst': 'restructuredtext',
'.md': 'markdown',
}

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
--------

26
docs/index.rst

@ -0,0 +1,26 @@
.. Web M&M documentation master file, created by
sphinx-quickstart on Mon Jan 31 21:56:04 2022.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Vítejte v dokumentaci M&Mího webu!
===================================
.. toctree::
:caption: M&M web
:maxdepth: 2
vyvoj
sphinx
dalsi_soubory
modules/modules
zapisy/zapisy
Rejstříky a vyhledávání
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`

37
docs/sphinx.rst

@ -0,0 +1,37 @@
Sphinx na našem webu
====================
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!**)
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`_ `Cheat sheet`_
.. _Návod na syntaxi rst: https://sphinx-tutorial.readthedocs.io/step-1/#sections
.. _Cheat sheet: https://sphinx-tutorial.readthedocs.io/cheatsheet/
make html
---------
Make html dělá následující: Vygenerují se rst soubory do modules z pythoní dokumentace pomocí::
sphinx-apidoc --module-first -o modules .. ../*/migrations --templatedir _templates -f
- ``--module-first`` říká, že dokumentace modulu má být dřív než to, co obsahuje,
- ``-o`` je výstupní složka příkazu,
- ``..`` prochází složku mamweb,
- ``../*/migrations`` ignoruje migrace
- ``--templatedir _templates`` určuje templaty, podle kterých se vyrábí rst z Pythoní dokumentace a struktury složek a souborů,
- ``-f`` donutí phinx znovu přegenerovat soubory, protože nepozná, že se nějaká dokumentace změnila)
Poté se spustí „samotný sphinx“ a vygenerují se soubory v ``_build/html``.
Templates
---------
Templaty jsou originální s pár změnami:
- Změnil jsem nadpisy
- Odstranil jsem některá slova v nadpisech (module, package, …)
- Odstranil jsem nadpis Subpackages
přišlo mi to takhle lepší. Ale stále nejsem moc spokojen, protože je to pořád nepřehledné.

20
docs/vyvoj.rst

@ -0,0 +1,20 @@
Lokální vývoj mamwebu
=====================
Stačí spustit::
## Nahradte svym gimli username
git clone USER@gimli.ms.mff.cuni.cz:/akce/mam/git/mamweb.git mamweb
cd mamweb
## Instalace je trochu magická, spusť následující posloupnost příkazů:
make install_venv
. env/bin/activate
make install_web
## Vygeneruje nejaka testovaci data (spis chuda)
./manage.py testdata
## Nahraje statické stránky, menu a obrázky v pozadí menu
./manage.py loaddata data/*
## Spusti testovaci server na http://127.0.0.1:8000/
./manage.py runserver
Když si lokálně spustíte web, běží na http://127.0.0.1:8000/, admin najdete na http://127.0.0.1:8000/admin/ (admin/admin) Až skončíš s vývojem webu, spusť “deactivate”. Tím zmizí ‘(env)’ ze začátku promptu.

5
docs/zapisy/zapisy.rst

@ -0,0 +1,5 @@
Zápisy
======
.. toctree::
2021-12-06-testovani_dokumentace_codereview

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 seminar.utils import org_required
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.admin import ModelAdmin
import header_fotky.models as m
class FotkaPozadiAdmin(ModelAdmin):
"""
Nastaví čas vložení (:attr:`~header_fotky.models.FotkaHeader.cas`) jako
readonly = neměnitelný
"""
readonly_fields = ['cas']
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

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
import random
@ -8,7 +12,15 @@ from header_fotky.models import FotkaUrlVazba
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
if (hodin <= 6) or (hodin >= 20):
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.db import models
from django.utils import timezone
class FotkaHeader(models.Model):
""" fotka pro :mod:`fotka_header`, konkrétně :class:`~fotka_header.models.FotkaUrlVazba` """
class Meta:
ordering = ['-cas']
db_table = 'fotky_header'
@ -11,27 +26,34 @@ class FotkaHeader(models.Model):
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')
""" čas vložení fotky """
nazev = models.CharField(
u'název fotky', null=False, blank=False, unique=True, primary_key=True,
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)
""" soubor fotky (Nahrává se automaticky do složky ``media``.) """
def __str__(self):
return self.nazev
def clean(self):
""" kontroluje, zda sedí poměr stran """
if not self.fotka:
raise ValidationError("Chybí obrázek")
""" Kontroluje, zda sedí poměr stran """
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.")
super().clean()
class FotkaUrlVazba(models.Model):
"""
spojení :class:`~fotka_header.models.FotkaHeader` a url
(resp. prefixu url), na které být zobrazována
"""
class Meta:
ordering = ['url']
db_table = 'fotky_url_vazby'
@ -42,11 +64,13 @@ class FotkaUrlVazba(models.Model):
u'URL', blank=True, null=False, max_length=100,
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(
FotkaHeader, blank=False, null=False, verbose_name='fotka',
on_delete=models.CASCADE
)
""" :class:`~fotka_header.models.FotkaHeader`, která má být zobrazována """
DOBA_DEN = 'den'
DOBA_NOC = 'noc'
@ -57,9 +81,11 @@ class FotkaUrlVazba(models.Model):
(DOBA_OBOJI, 'Zobrazovat pořád')]
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):
return self.url
def url_fotky(self):
""" vrací url fotky (tj. url, kde reálně získám soubor fotky) """
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 reversion.admin import VersionAdmin
from korektury.models import KorekturovanePDF
@ -7,10 +17,18 @@ from django.urls import reverse
# Register your models here.
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']
def get_readonly_fields(self, request, obj=None):
""" Nevím, proč to tu je - Jidáš """
if obj:
return self.readonly_fields + ['pdf']
return self.readonly_fields
@ -26,6 +44,9 @@ class KorekturovanePDFAdmin(VersionAdmin):
search_fields = []
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)
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}))

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
class OpravaForm(forms.Form):
""" formulář k přidání opravy (:class:`korektury.models.Oprava`) """
text = forms.CharField(max_length=256)
autor = forms.CharField(max_length=20)
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
from django.db import models
from django.utils import timezone
@ -17,6 +30,7 @@ from unidecode import unidecode
def generate_filename(self, filename):
""" vyrobí jméno souboru podle původního jména a času nahrátí """
clean = get_valid_filename(
unidecode(
filename.replace('/', '-').replace('\0', '').replace(":", "_")

4
korektury/testutils.py

@ -1,3 +1,6 @@
"""
Soubor sloužící ke generování testdat.
"""
import logging
import os
from shutil import copyfile, rmtree
@ -11,6 +14,7 @@ logger = logging.getLogger(__name__)
@transaction.atomic
def create_test_pdf(rnd, organizatori):
""" Vyrobí testovací pdf ke korekturování. Nevyrábí korektury! """
logger.info('Vyrábím testovací pdf ke korekturovani')
try:
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 seminar.utils import org_required
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.views import generic
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
from django.contrib import admin
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.contrib.staticfiles.urls import staticfiles_urlpatterns
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_reverse_admin import ReverseModelAdmin
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

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 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

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.contrib.auth.decorators import login_required
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 seminar.utils import org_required, resitel_required
from . import views

5
requirements.txt

@ -57,3 +57,8 @@ uWSGI
# Potřeba pro test data
lorem
# pro dokumentaci
sphinx
sphinx_rtd_theme

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 . import views
from .utils import org_required
@ -24,7 +56,6 @@ urlpatterns = [
#path('aktualni/temata/', views.ZadaniTemataView, name='seminar_temata'),
path('aktualni/vysledkova-listina/', views.ZadaniAktualniVysledkovkaView, name='seminar_aktualni_vysledky'),
path('aktualni/rocnik/', views.AktualniRocnikRedirectView.as_view(), name='seminar_aktualni_rocnik'),
path('stare-novinky/', views.StareNovinkyView.as_view(), name='stare_novinky'),
# Clanky
path('archiv/clanky/', views.ClankyResitelView.as_view(), name='clanky_resitel'),
@ -73,4 +104,5 @@ urlpatterns = [
path('', views.TitulniStranaView.as_view(), name='titulni_strana'),
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

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

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 . 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

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 . import views
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

Loading…
Cancel
Save