Velká revize stylů (a některých JS) #44
					 219 changed files with 499 additions and 809 deletions
				
			
		
							
								
								
									
										12
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							|  | @ -31,9 +31,15 @@ TODO | |||
| # reversion kvůli historii objektů v reversion | ||||
| **/reversion | ||||
| 
 | ||||
| # dokumentace | ||||
| docs/_build | ||||
| docs/modules | ||||
| 
 | ||||
| # logy týracího skriptu (./checklinks.sh) | ||||
| /wget.log.* | ||||
| 
 | ||||
| # pro lidi, co programují v nástrojích od JetBrains | ||||
| .idea | ||||
| 
 | ||||
| # dokumentace | ||||
| docs/_build | ||||
| docs/modules | ||||
| # Mac users | ||||
| .DS_Store | ||||
|  |  | |||
|  | @ -1,16 +0,0 @@ | |||
| git hooks | ||||
| ========= | ||||
| 
 | ||||
| Kontrola stylu pythoních zdrojáků pomocí flake8. Kontrolujeme jen změny, | ||||
| abychom nenutili lidi dělat nesouvisející úpravy, které by rozbíjely historii | ||||
| (git blame). | ||||
| 
 | ||||
| pre-commit | ||||
| ---------- | ||||
| * kontrola změn před commitnutím | ||||
| * instalace: lokálně zkopírovat do .git/hooks (musí být spustitelný) | ||||
| 
 | ||||
| update | ||||
| ------ | ||||
| * kontrola změn přicházejících s pushem | ||||
| * instalace: na atreyi zkopírovat do /akce/MaM/MaMweb/mamweb.git/hooks | ||||
|  | @ -1,30 +0,0 @@ | |||
| #!/bin/sh | ||||
| # | ||||
| # Git hook script to verify what is about to be committed. | ||||
| # Checks that the changes don't introduce new flake8 errors. | ||||
| 
 | ||||
| TMPDIFF=`tempfile` | ||||
| FLAKE8="`git rev-parse --show-toplevel`/bin/flake8" | ||||
| 
 | ||||
| status=0 | ||||
| 
 | ||||
| # select only changed python files which are not migrations | ||||
| changed=`git diff --cached --name-only | grep 'py$' | grep -v 'migrations/[0-9]'` | ||||
| if [ -z $changed ] ; then | ||||
|     # Nothing to check. Note the exit is necessary -- we would not pass any | ||||
|     # paths to git diff below and it would output the diff unfiltered. | ||||
|     exit 0 | ||||
| fi | ||||
| 
 | ||||
| git diff --unified=1 --cached HEAD -- $changed > $TMPDIFF | ||||
| 
 | ||||
| # only do the check when there are some changes to be commited | ||||
| # otherwise flake8 would hang waiting for input | ||||
| if [ -s $TMPDIFF ] ; then | ||||
|     cat $TMPDIFF | $FLAKE8 --diff | ||||
|     status=$? | ||||
| fi | ||||
| 
 | ||||
| rm -f $TMPDIFF | ||||
| 
 | ||||
| exit $status | ||||
|  | @ -1,61 +0,0 @@ | |||
| #!/bin/sh | ||||
| 
 | ||||
| # git update hook to check that pushed changes don't introduce new flake8 | ||||
| # errors | ||||
| 
 | ||||
| # --- Command line | ||||
| refname="$1" | ||||
| oldrev="$2" | ||||
| newrev="$3" | ||||
| 
 | ||||
| # --- Safety check | ||||
| if [ -z "$GIT_DIR" ]; then | ||||
| 	echo "Don't run this script from the command line." >&2 | ||||
| 	echo " (if you want, you could supply GIT_DIR then run" >&2 | ||||
| 	echo "  $0 <ref> <oldrev> <newrev>)" >&2 | ||||
| 	exit 1 | ||||
| fi | ||||
| 
 | ||||
| if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then | ||||
| 	echo "usage: $0 <ref> <oldrev> <newrev>" >&2 | ||||
| 	exit 1 | ||||
| fi | ||||
| 
 | ||||
| 
 | ||||
| TMPDIR=`mktemp -d` | ||||
| TMPDIFF=`tempfile` | ||||
| 
 | ||||
| [ $refname != "refs/heads/master" -a $refname != "refs/heads/stable" ] && exit 0 | ||||
| 
 | ||||
| # select only changed python files which are not migrations | ||||
| changed=`git diff --name-only $oldrev $newrev | grep 'py$' | grep -v 'migrations/[0-9]'` | ||||
| if [ -z $changed ] ; then | ||||
|     # Nothing to check. Note the exit is necessary -- we would not pass any | ||||
|     # paths to git diff below and it would output the diff unfiltered. | ||||
|     exit 0 | ||||
| fi | ||||
| 
 | ||||
| git diff --unified=1 $oldrev $newrev -- $changed >${TMPDIFF} | ||||
| 
 | ||||
| # there is no working tree in bare git repository, so we recreate it for flake8 | ||||
| git archive $newrev | tar -x -C ${TMPDIR} | ||||
| 
 | ||||
| cd ${TMPDIR} | ||||
| # report only errors on lines in diff | ||||
| # (if threre was flake8 installed on atrey, we could just call flake8) | ||||
| /akce/MaM/WWW/mamweb-test/bin/flake8 --diff <${TMPDIFF} | ||||
| status=$? | ||||
| if [ $status != 0 ] ; then | ||||
|     echo | ||||
|     echo -n "Změny, které se snažíte pushnout, obsahují kód v pythonu " | ||||
|     echo -n "nevyhovující flake8 (viz výše). Opravte je a zkuste to znovu. " | ||||
|     echo -n "Nezapomeňte, že můžete editovat historii (git commit --amend, " | ||||
|     echo -n "git rebase -i). Pokud byste chybu příště raději odhalili už při " | ||||
|     echo "commitu, zkopírujte si pre-commit hook z _git_hooks do .git/hooks." | ||||
|     echo | ||||
| fi | ||||
| 
 | ||||
| rm -rf ${TMPDIR} | ||||
| rm -f ${TMPDIFF} | ||||
| 
 | ||||
| exit $status | ||||
|  | @ -1,8 +1,5 @@ | |||
| """ | ||||
| Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace. | ||||
| """ | ||||
| from django.apps import AppConfig | ||||
| 
 | ||||
| 
 | ||||
| class AesopConfig(AppConfig): | ||||
|     name = 'aesop' | ||||
|     verbose_name = 'Export do AESOPa' | ||||
|  |  | |||
|  | @ -1,10 +1,3 @@ | |||
| """ | ||||
| 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 | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,8 +1,3 @@ | |||
| """ | ||||
| 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 | ||||
|  |  | |||
|  | @ -1,8 +1,6 @@ | |||
| """ | ||||
| Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace. | ||||
| """ | ||||
| from django.apps import AppConfig | ||||
| 
 | ||||
| 
 | ||||
| class ApiConfig(AppConfig): | ||||
|     name = 'api' | ||||
|     verbose_name = 'Různá webová API' | ||||
|  |  | |||
							
								
								
									
										12
									
								
								api/urls.py
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								api/urls.py
									
									
									
									
									
								
							|  | @ -1,15 +1,3 @@ | |||
| """ | ||||
| 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 | ||||
|  |  | |||
|  | @ -1,7 +1,2 @@ | |||
| """ | ||||
| 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 * | ||||
|  |  | |||
|  | @ -1079,5 +1079,29 @@ | |||
| 		}, | ||||
| 		"model": "sitetree.treeitem", | ||||
| 		"pk": 53 | ||||
| 	}, | ||||
| 	{ | ||||
| 		"fields": { | ||||
| 			"access_guest": false, | ||||
| 			"access_loggedin": false, | ||||
| 			"access_perm_type": 1, | ||||
| 			"access_permissions": [], | ||||
| 			"access_restricted": true, | ||||
| 			"alias": null, | ||||
| 			"description": "", | ||||
| 			"hidden": false, | ||||
| 			"hint": "", | ||||
| 			"inbreadcrumbs": true, | ||||
| 			"inmenu": true, | ||||
| 			"insitetree": true, | ||||
| 			"parent": 20, | ||||
| 			"sort_order": 54, | ||||
| 			"title": "Export do abstraktů sousu {{ soustredeni.id }}", | ||||
| 			"tree": 1, | ||||
| 			"url": "seminar_soustredeni_abstrakty soustredeni.id", | ||||
| 			"urlaspattern": true | ||||
| 		}, | ||||
| 		"model": "sitetree.treeitem", | ||||
| 		"pk": 54 | ||||
| 	} | ||||
| ] | ||||
|  |  | |||
|  | @ -331,22 +331,22 @@ | |||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "add_novinky", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "novinky", | ||||
| 		"ct_model": "novinky" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "change_novinky", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "novinky", | ||||
| 		"ct_model": "novinky" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "delete_novinky", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "novinky", | ||||
| 		"ct_model": "novinky" | ||||
| 	}, | ||||
| 	{ | ||||
| 		"codename": "view_novinky", | ||||
| 		"ct_app_label": "seminar", | ||||
| 		"ct_app_label": "novinky", | ||||
| 		"ct_model": "novinky" | ||||
| 	}, | ||||
| 	{ | ||||
|  |  | |||
|  | @ -9,12 +9,6 @@ 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 | ||||
|  |  | |||
|  | @ -1,3 +1,4 @@ | |||
| FIXME přepsat do rst, přidat i další věci a případně přesunout na wiki | ||||
| Přidání obrázků do odměn: | ||||
| admin -> flatpage odměn -> ikona přidat obrázek | ||||
| záložka odeslat, vybrat obrázek, odeslat | ||||
							
								
								
									
										25
									
								
								galerie/TODO
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								galerie/TODO
									
									
									
									
									
								
							|  | @ -1,25 +0,0 @@ | |||
| ======== | ||||
| | TODO | | ||||
| |======| | ||||
| 
 | ||||
| Aktualni | ||||
| * co s titulni fotkou | ||||
| * do CSS | ||||
|   * nahledy | ||||
|     * nastylovat tabulku s nahledy | ||||
|     * komentare uz na nahledy? | ||||
|   * detail | ||||
|     * nahledy pred a po | ||||
|     * opravit prechodove sipky | ||||
|     * vyrobit prechodove sipky ve M&M-stylu | ||||
| 
 | ||||
| Dlouhodobe | ||||
| * sipky na prechazeni mezi fotkami | ||||
| * hromadne PRIDANI fotek do jiz existujici galerie | ||||
| 
 | ||||
| Fylozoficke | ||||
| * zvolit velikosti velke a male fotky | ||||
| * je potreba i jine razeni nez automaticky podle casu nebo staci podgalerie? | ||||
|   * napr. dve hry na dvou ruznych mistech ve stejny cas | ||||
|   * fotky od ucastniku ze hry (skupinky se pohybuji ve stejny cas, ale maji sled fotek) -- nestaci to pripadne vrazit do podgalerii? | ||||
| 
 | ||||
|  | @ -1,5 +1,3 @@ | |||
| #coding: utf-8 | ||||
| 
 | ||||
| from galerie.models import Obrazek, Galerie | ||||
| from django.contrib import admin | ||||
| from django.http import HttpResponseRedirect | ||||
|  |  | |||
|  | @ -1,47 +0,0 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| 
 | ||||
| from autocomplete_light import shortcuts as autocomplete_light | ||||
| 
 | ||||
| from .models import Obrazek, Galerie | ||||
| from .views import cesta_od_korene | ||||
| 
 | ||||
| 
 | ||||
| class ObrazekAutocomplete(autocomplete_light.AutocompleteModelBase): | ||||
| 
 | ||||
|     model = Obrazek | ||||
|     search_fields = ['nazev', 'popis'] | ||||
|     split_words = True | ||||
|     limit_choices = 15 | ||||
|     attrs = { | ||||
|         # This will set the input placeholder attribute: | ||||
|         'placeholder': u'Obrázek', | ||||
|         # This will set the yourlabs.Autocomplete.minimumCharacters | ||||
|         # options, the naming conversion is handled by jQuery | ||||
|         'data-autocomplete-minimum-characters': 1, | ||||
|     } | ||||
| 
 | ||||
|     choice_html_format = ''' | ||||
|         <span class="block" data-value="{}"> | ||||
|             <span class="block"> | ||||
|                 {} | ||||
|                 <span class="block">{}</span> | ||||
|             </span> | ||||
|         </span> | ||||
|     ''' | ||||
| 
 | ||||
|     def choice_label(self, obrazek): | ||||
|         cesta = "/".join(g.nazev for g in cesta_od_korene(obrazek.galerie)) | ||||
|         popis = "{}<br>".format(obrazek.popis) if obrazek.popis else "" | ||||
|         return '{}<br>{}{}'.format(obrazek.nazev, popis, cesta) | ||||
| 
 | ||||
|     def choice_html(self, obrazek): | ||||
|         """Vrátí kus html i s obrázkem, které se pak ukazuje v nabídce""" | ||||
|         return self.choice_html_format.format(self.choice_value(obrazek), | ||||
|             obrazek.obrazek_maly_tag(), self.choice_label(obrazek)) | ||||
| 
 | ||||
|     widget_attrs={ | ||||
|         'data-widget-maximum-values': 15, | ||||
|         'class': 'modern-style', | ||||
|     } | ||||
| 
 | ||||
| autocomplete_light.register(ObrazekAutocomplete) | ||||
|  | @ -1,5 +1,3 @@ | |||
| #coding: utf-8 | ||||
| 
 | ||||
| from django import forms | ||||
| from seminar.models import Soustredeni | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| # Generated by Django 1.11.20 on 2019-04-30 21:40 | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| # Generated by Django 1.11.21 on 2019-06-10 21:58 | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,5 +1,3 @@ | |||
| # coding: utf-8 | ||||
| 
 | ||||
| from django.db import models | ||||
| #from django.db.models import Q | ||||
| from imagekit.models import ImageSpecField | ||||
|  |  | |||
|  | @ -1,12 +1,3 @@ | |||
| """ | ||||
| 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 | ||||
|  |  | |||
|  | @ -1,5 +1,3 @@ | |||
| # coding: utf-8 | ||||
| 
 | ||||
| import random | ||||
| 
 | ||||
| from django.http import HttpResponse, Http404 | ||||
|  |  | |||
|  | @ -1,14 +1,3 @@ | |||
| """ | ||||
| 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 | ||||
|  | @ -22,4 +11,4 @@ class FotkaPozadiAdmin(ModelAdmin): | |||
|     readonly_fields = ['cas'] | ||||
| 
 | ||||
| admin.site.register(m.FotkaHeader, FotkaPozadiAdmin) | ||||
| admin.site.register(m.FotkaUrlVazba) | ||||
| admin.site.register(m.FotkaUrlVazba) | ||||
|  |  | |||
|  | @ -1,8 +1,6 @@ | |||
| """ | ||||
| Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace. | ||||
| """ | ||||
| from django.apps import AppConfig | ||||
| 
 | ||||
| 
 | ||||
| class HeaderFotkyConfig(AppConfig): | ||||
|     name = 'header_fotky' | ||||
|     verbose_name = 'Fotky v záhlaví' | ||||
|  |  | |||
|  | @ -1,17 +1,3 @@ | |||
| """ | ||||
| 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 | ||||
|  |  | |||
|  | @ -1,11 +0,0 @@ | |||
| - korektura potrebuje reakci | ||||
| + komentáře fixně na username | ||||
|   - používat skutečné jméno? | ||||
| - vyžádat pozornost autora obsahu | ||||
| - zvednout upload limit na 5MB | ||||
| - sbalit a rozbalit korekturu | ||||
| - nahrávání jiných věcí než PDF - kontrolovat? | ||||
| - stylování | ||||
| - seznam PDF - co zobrazovat? | ||||
| 
 | ||||
| 
 | ||||
|  | @ -1,13 +1,3 @@ | |||
| """ | ||||
| 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 | ||||
|  | @ -15,7 +5,6 @@ from korektury.models import KorekturovanePDF | |||
| from django.core.mail import EmailMessage | ||||
| from django.urls import reverse | ||||
| 
 | ||||
| # Register your models here. | ||||
| class KorekturovanePDFAdmin(VersionAdmin): | ||||
| 	""" | ||||
| 	nastaví čas vložení (:attr:`~koretkury.models.KorekturovanePDF.cas`) a počet | ||||
|  |  | |||
|  | @ -1,13 +1,3 @@ | |||
| """ | ||||
| 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): | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import models, migrations | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| # Generated by Django 1.11.20 on 2019-04-30 21:40 | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| # Generated by Django 1.11.21 on 2019-06-10 21:58 | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,17 +1,3 @@ | |||
| """ | ||||
| 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 | ||||
|  |  | |||
|  | @ -1,3 +0,0 @@ | |||
| from django.test import TestCase | ||||
| 
 | ||||
| # Create your tests here. | ||||
|  | @ -1,11 +1,3 @@ | |||
| """ | ||||
| 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 | ||||
|  |  | |||
|  | @ -1,8 +1,3 @@ | |||
| """ | ||||
| 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.conf import settings | ||||
|  | @ -199,13 +194,6 @@ class KorekturyView(generic.TemplateView): | |||
| 		if email: | ||||
| 			emails.discard(email) | ||||
| 
 | ||||
| 		if not settings.POSLI_MAILOVOU_NOTIFIKACI: | ||||
| 			print("Poslal bych upozornění na tyto adresy: ", " ".join(emails)) | ||||
| 			print("---- Upozornění:") | ||||
| 			print(text) | ||||
| 			print("---- Konec upozornění") | ||||
| 			return | ||||
| 
 | ||||
| 		EmailMessage( | ||||
| 			subject=subject, | ||||
| 			body=text, | ||||
|  |  | |||
|  | @ -7,5 +7,5 @@ make/install_web | |||
| ensure_venv | ||||
| ./manage.py testdata | ||||
| ./manage.py loaddata data/* | ||||
| make/sync_prod_flatpages | ||||
| #make/sync_prod_flatpages | ||||
| ./manage.py load_org_permissions deploy_v2/admin_org_prava.json | ||||
|  |  | |||
|  | @ -42,8 +42,18 @@ def get_app_list(self, request, app_label=None): | |||
| 	""" | ||||
| 
 | ||||
| 	app_dict = self._build_app_dict(request, label=app_label) | ||||
| 	# Sort the apps alphabetically. | ||||
| 	app_list = sorted(app_dict.values(), key=lambda x: locale.strxfrm('!') if (x['name'] == "Seminar") else locale.strxfrm(x['name'].lower())) | ||||
| 	aplikace_nahore = [ | ||||
| 		'seminar', | ||||
| 		'personalni', | ||||
| 		'novinky', | ||||
| 		'korektury', | ||||
| 		'various', | ||||
| 		'prednasky', | ||||
| 		'soustredeni', | ||||
| 		] | ||||
| 	# Odhlášený admin má prázdný app_dict :-/ | ||||
| 	app_list = [app_dict[label] for label in aplikace_nahore if label in app_dict] + [app_dict[label] for label in app_dict if label not in aplikace_nahore] | ||||
| 
 | ||||
| 
 | ||||
| 	# Sort the models alphabetically within each app. | ||||
| 	for app in app_list: | ||||
|  |  | |||
|  | @ -1,88 +0,0 @@ | |||
| from datetime import datetime, date | ||||
| 
 | ||||
| from django.conf import settings | ||||
| from django.http import HttpResponse, HttpResponseRedirect | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| class LoggedInHintCookieMiddleware(object): | ||||
| 	"""Middleware to securely help with 'logged-in' detection for dual HTTP/HTTPS sites. | ||||
| 	 | ||||
| 	On insecure requests: Checks for a (non-secure) cookie settings.LOGGED_IN_HINT_COOKIE_NAME | ||||
| 	and if present, redirects to HTTPS (same adress). | ||||
| 	Note this usually breaks non-GET (POST) requests. | ||||
| 
 | ||||
| 	On secure requests: Updates cookie settings.LOGGED_IN_HINT_COOKIE_NAME to reflect | ||||
| 	whether an user is logged in in the current session (cookie set to 'True' or cleared). | ||||
| 	The cookie is set to expire at the same time as the sessionid cookie. | ||||
| 
 | ||||
| 	By default, LOGGED_IN_HINT_COOKIE_NAME = 'logged_in_hint'. | ||||
| 	""" | ||||
| 
 | ||||
| 	def __init__(self): | ||||
| 		if hasattr(settings, 'LOGGED_IN_HINT_COOKIE_NAME'): | ||||
| 			self.cookie_name = settings.LOGGED_IN_HINT_COOKIE_NAME | ||||
| 		else: self.cookie_name = 'logged_in_hint' | ||||
| 		self.cookie_value = 'True' | ||||
| 
 | ||||
| 	def cookie_correct(self, request): | ||||
| 		return self.cookie_name in request.COOKIES and request.COOKIES[self.cookie_name] == self.cookie_value | ||||
| 
 | ||||
| 	def process_request(self, request): | ||||
| 		if not request.is_secure(): | ||||
| 			if self.cookie_correct(request): | ||||
| 				# redirect insecure (assuming http) requests with hint cookie to https | ||||
| 				url = request.build_absolute_uri() | ||||
| 				assert url[:5] == 'http:' | ||||
| 				return HttpResponseRedirect('https:' + url[5:]) | ||||
| 		return None | ||||
| 
 | ||||
| 	def process_response(self, request, response): | ||||
| 		if request.is_secure(): | ||||
| 			# assuming full session info (as the conn. is secure) | ||||
| 			try: | ||||
| 				user = request.user | ||||
| 			except AttributeError: # no user - ajax or other special request | ||||
| 				return response | ||||
| 			if user.is_authenticated(): | ||||
| 				if not self.cookie_correct(request): | ||||
| 					expiry = None if request.session.get_expire_at_browser_close() else request.session.get_expiry_date() | ||||
| 					response.set_cookie(self.cookie_name, value=self.cookie_value, expires=expiry, secure=False) | ||||
| 			else: | ||||
| 				if self.cookie_name in request.COOKIES: | ||||
| 					response.delete_cookie(self.cookie_name) | ||||
| 		return response | ||||
| 
 | ||||
| 
 | ||||
| class vzhled: | ||||
| 
 | ||||
| 	def process_request(self, request): | ||||
| 		return None | ||||
| 
 | ||||
| 	def process_view(self, request, view_func, view_args, view_kwargs): | ||||
| 		#print "====== process_request ======" | ||||
| 		#print view_func | ||||
| 		#print view_args | ||||
| 		#print view_kwargs | ||||
| 		#print "=============================" | ||||
| 		return None | ||||
| 
 | ||||
| 	def process_template_response(self, request, response): | ||||
| 		hodin = datetime.now().hour | ||||
| 		if (hodin <= 6) or (hodin >= 14): # TODO 20 | ||||
| 			response.context_data['noc'] = True | ||||
| 		else: | ||||
| 			response.context_data['noc'] = False | ||||
| 		return response | ||||
| 
 | ||||
| 	def process_response(self, request, response): | ||||
| 		#hodin = datetime.now().hour | ||||
| 		#if (hodin <= 6) or (hodin >= 14): # TODO 20 | ||||
| 			#response.context_data['noc'] = True | ||||
| 		#else: | ||||
| 			#response.context_data['noc'] = False | ||||
| 		return response | ||||
| 		 | ||||
| 
 | ||||
| 	##def process_exception(request, exception): | ||||
| 		#pass | ||||
|  | @ -68,9 +68,6 @@ MIDDLEWARE = ( | |||
| 	'django.contrib.sessions.middleware.SessionMiddleware', | ||||
| 	'django.middleware.common.CommonMiddleware', | ||||
| 	'django.middleware.csrf.CsrfViewMiddleware', | ||||
| #	FIXME: rozbilo se při přechodu na Django 2.0, nevím, jestli  | ||||
| #	se to dá zahodit bez náhrady | ||||
| #    'mamweb.middleware.LoggedInHintCookieMiddleware', | ||||
| 	'django.contrib.auth.middleware.AuthenticationMiddleware', | ||||
| 	'django.contrib.messages.middleware.MessageMiddleware', | ||||
| 	'django.middleware.clickjacking.XFrameOptionsMiddleware', | ||||
|  | @ -149,6 +146,7 @@ INSTALLED_APPS = ( | |||
| 	'treenode', | ||||
| 	'vyroci', | ||||
| 	'sifrovacka', | ||||
| 	'novinky', | ||||
| 
 | ||||
| 	# Admin upravy: | ||||
| 
 | ||||
|  | @ -344,10 +342,6 @@ KOREKTURY_IMG_DIR = os.path.join('korektury', 'img') | |||
| CISLO_IMG_DIR = os.path.join('cislo', 'img') | ||||
| 
 | ||||
| 
 | ||||
| # E-MAIL NOTIFICATIONS | ||||
| POSLI_MAILOVOU_NOTIFIKACI = False | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| # Logování chyb | ||||
| class InvalidTemplateVariable(str): | ||||
|  |  | |||
|  | @ -1,5 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| 
 | ||||
| import os.path | ||||
| 
 | ||||
| # | ||||
|  | @ -70,5 +68,4 @@ LOGGING['handlers']['registration_error_log']['filename'] = '/home/mam-web/logs/ | |||
| 
 | ||||
| 
 | ||||
| # E-MAIL NOTIFICATIONS | ||||
| POSLI_MAILOVOU_NOTIFIKACI = True | ||||
| LOCAL_TEST_PROD = "prod" | ||||
|  |  | |||
|  | @ -1,5 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| 
 | ||||
| import os.path | ||||
| 
 | ||||
| # | ||||
|  | @ -74,7 +72,6 @@ LOGGING['handlers']['registration_error_log']['filename'] = '/home/mam-web/logs/ | |||
| FILE_UPLOAD_PERMISSIONS = 0o440 | ||||
| 
 | ||||
| # Testování e-mailů | ||||
| POSLI_MAILOVOU_NOTIFIKACI = True | ||||
| EMAIL_BACKEND = 'various.mail_prefixer.PrefixingMailBackend' | ||||
| # TODO Pouze na otestování testu… Zvolit konferu! | ||||
| # XXX: Je to pole, protože implementační detail backendu. | ||||
|  |  | |||
|  | @ -1,18 +1,5 @@ | |||
| """ | ||||
| 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` | ||||
| Soubor sloužící jako základní „router“, tj. zde se includují veškeré ostatní urls. | ||||
| """ | ||||
| from django.urls import path, include | ||||
| from django.contrib.staticfiles.urls import staticfiles_urlpatterns | ||||
|  |  | |||
							
								
								
									
										0
									
								
								novinky/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								novinky/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										5
									
								
								novinky/admin.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								novinky/admin.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | |||
| from django.contrib import admin | ||||
| 
 | ||||
| from .models import Novinky | ||||
| 
 | ||||
| admin.site.register(Novinky) | ||||
							
								
								
									
										5
									
								
								novinky/apps.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								novinky/apps.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | |||
| from django.apps import AppConfig | ||||
| 
 | ||||
| class NovinkyConfig(AppConfig): | ||||
|     name = 'novinky' | ||||
|     verbose_name = 'Novinky' | ||||
							
								
								
									
										45
									
								
								novinky/migrations/0001_initial.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								novinky/migrations/0001_initial.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,45 @@ | |||
| # Generated by Django 4.2.13 on 2024-05-13 20:43 | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
| 
 | ||||
| def nastav_nove_contenttypes(apps, schema_editor): | ||||
|     ContentType = apps.get_model('contenttypes', 'ContentType') | ||||
|     for m in ('novinka'): | ||||
|         oct = ContentType.objects.filter(app_label='seminar', model=m) | ||||
|         oct.update(app_label='novinky') | ||||
| 
 | ||||
| def nastav_stare_contenttypes(apps, schema_editor): | ||||
|     ContentType = apps.get_model('contenttypes', 'ContentType') | ||||
|     for m in ('novinka'): | ||||
|         nct = ContentType.objects.filter(app_label='novinky', model=m) | ||||
|         nct.update(app_label='seminar') | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     initial = True | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('seminar', '0127_unmanage_novinky'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.RunPython(nastav_nove_contenttypes, nastav_stare_contenttypes), | ||||
|         migrations.CreateModel( | ||||
|             name='Novinky', | ||||
|             fields=[ | ||||
|                 ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | ||||
|                 ('datum', models.DateField(auto_now_add=True)), | ||||
|                 ('text', models.TextField(blank=True, null=True, verbose_name='Text novinky')), | ||||
|                 ('obrazek', models.ImageField(blank=True, null=True, upload_to='image_novinky/%Y/%m/%d/', verbose_name='Obrázek')), | ||||
|                 ('autor', models.ForeignKey(to='personalni.organizator', verbose_name='Autor novinky', null=True, on_delete=models.SET_NULL)), | ||||
|                 ('zverejneno', models.BooleanField(default=False, verbose_name='Zveřejněno')), | ||||
|             ], | ||||
|             options={ | ||||
|                 'verbose_name': 'Novinka', | ||||
|                 'verbose_name_plural': 'Novinky', | ||||
|                 'db_table': 'seminar_novinky', | ||||
|                 'ordering': ['-datum'], | ||||
|                 'managed': False, | ||||
|             }, | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										18
									
								
								novinky/migrations/0002_manage_novinky.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								novinky/migrations/0002_manage_novinky.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | |||
| # Generated by Django 4.2.13 on 2024-05-13 20:58 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('novinky', '0001_initial'), | ||||
|         ('seminar', '0128_delete_novinky'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.AlterModelOptions( | ||||
|             name='novinky', | ||||
|             options={'ordering': ['-datum'], 'verbose_name': 'Novinka', 'verbose_name_plural': 'Novinky'}, | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										13
									
								
								novinky/migrations/0003_novinky_post.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								novinky/migrations/0003_novinky_post.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| # Generated by Django 4.2.13 on 2024-05-13 21:00 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('novinky', '0002_manage_novinky'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
							
								
								
									
										0
									
								
								novinky/migrations/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								novinky/migrations/__init__.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -13,6 +13,7 @@ class Novinky(models.Model): | |||
| 		verbose_name = 'Novinka' | ||||
| 		verbose_name_plural = 'Novinky' | ||||
| 		ordering = ['-datum'] | ||||
| 		db_table = 'seminar_novinky' | ||||
| 
 | ||||
| 	datum = models.DateField(auto_now_add=True) | ||||
| 
 | ||||
							
								
								
									
										0
									
								
								novinky/views.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								novinky/views.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -1,9 +1,3 @@ | |||
| """ | ||||
| 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 | ||||
|  |  | |||
|  | @ -1,8 +1,6 @@ | |||
| """ | ||||
| Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace. | ||||
| """ | ||||
| from django.apps import AppConfig | ||||
| 
 | ||||
| 
 | ||||
| class OdevzdavatkoConfig(AppConfig): | ||||
|     name = 'odevzdavatko' | ||||
|     verbose_name = 'Odevzdávátko' | ||||
|  |  | |||
|  | @ -1,17 +1,3 @@ | |||
| """ | ||||
| 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, \ | ||||
|  |  | |||
|  | @ -504,7 +504,7 @@ class NahrajReseniView(LoginRequiredMixin, CreateView): | |||
| 
 | ||||
| 		EmailMessage( | ||||
| 			subject="Nové řešení k " + seznam_do_subjectu, | ||||
| 			body=f"Řešitel{ '' if resitel.pohlavi_muz else 'ka' } { resitel } právě nahrál{'' if resitel.pohlavi_muz else 'a' } nové řešení k { seznam }.\n\nHurá do opravování: { self.object.absolute_url() }", | ||||
| 			body=f"{resitel} posílá nové řešení k { seznam }.\n\nHurá do opravování: { self.object.absolute_url() }", | ||||
| 			from_email="submitovatko@mam.mff.cuni.cz", # FIXME: Chceme to mít radši tady, nebo v nastavení? | ||||
| 			to=list(prijemci), | ||||
| 		).send() | ||||
|  |  | |||
|  | @ -5,10 +5,52 @@ from django.contrib.messages import WARNING, ERROR, SUCCESS | |||
| import seminar.models as m | ||||
| from datetime import datetime | ||||
| 
 | ||||
| @admin.action(description="Sjednoť telefony") | ||||
| def sjednot_telefony(admin, request, queryset): | ||||
| 	for o in queryset: | ||||
| 		if o.telefon == '': | ||||
| 			continue | ||||
| 		try: | ||||
| 			telefon = int(o.telefon.replace(" ", "").replace("+", "")) | ||||
| 			# 6 míst | ||||
| 			if len(str(telefon)) == 9: | ||||
| 				o.telefon = "+420 " + str(telefon)[0:3] + " " + str(telefon)[3:6] + " " + str(telefon)[6:9] | ||||
| 				o.save() | ||||
| 			# 12 míst | ||||
| 			elif len(str(telefon)) == 12: | ||||
| 				o.telefon = "+" + str(telefon)[0:3] + " " + str(telefon)[3:6] + " " + str(telefon)[6:9] + " " + str(telefon)[9:12] | ||||
| 				o.save() | ||||
| 			else: | ||||
| 				raise ValueError | ||||
| 		except: | ||||
| 			admin.message_user(request, f"{o.jmeno} {o.prijmeni} (id: {o.id}) má divný telefon: {o.telefon}", level=ERROR) | ||||
| 	admin.message_user(request, "Telefony sjednoceny.", level=SUCCESS) | ||||
| 
 | ||||
| # Tohle chceme umět použít i z ResitelAdmin | ||||
| @admin.action(description="Udělej z vybraných osob organizátory") | ||||
| def udelej_orgem(admin, request, queryset): | ||||
| 	org_group = Group.objects.get(name='org') | ||||
| 	uspesne_vytvoreni_orgove = 0 | ||||
| 	for o in queryset: | ||||
| 		if m.Organizator.objects.filter(osoba=o).exists(): | ||||
| 			# Ref: https://docs.djangoproject.com/en/3.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin.message_user | ||||
| 			admin.message_user(request, f"Osoba {o} už je org, přeskakuji.", level=WARNING) | ||||
| 			continue | ||||
| 		user = o.user | ||||
| 		if user is None: | ||||
| 			admin.message_user(request, f"Osoba {o} nemá uživatele! Přeskakuji.", level=ERROR) | ||||
| 			continue | ||||
| 		user.groups.add(org_group) | ||||
| 		user.is_staff = True | ||||
| 		user.save() | ||||
| 		org = m.Organizator.objects.create(osoba=o, organizuje_od=datetime.now()) | ||||
| 		org.save() | ||||
| 		uspesne_vytvoreni_orgove += 1 | ||||
| 	admin.message_user(request, f'Úspěšně vytvořeno {uspesne_vytvoreni_orgove} orgů.', level=SUCCESS) | ||||
| 
 | ||||
| @admin.register(m.Osoba) | ||||
| class OsobaAdmin(admin.ModelAdmin): | ||||
| 	actions = ['synchronizuj_maily', 'udelej_orgem'] | ||||
| 	actions = ['synchronizuj_maily', udelej_orgem, sjednot_telefony] | ||||
| 	search_fields = ['jmeno', 'prijmeni', 'prezdivka'] | ||||
| 
 | ||||
| 	def synchronizuj_maily(self, request, queryset): | ||||
|  | @ -20,27 +62,6 @@ class OsobaAdmin(admin.ModelAdmin): | |||
| 		self.message_user(request, "E-maily synchronizovány.") | ||||
| 	synchronizuj_maily.short_description = "Synchronizuj vybraným osobám e-maily do uživatelů" | ||||
| 
 | ||||
| 	def udelej_orgem(self,request,queryset): | ||||
| 		org_group = Group.objects.get(name='org') | ||||
| 		uspesne_vytvoreni_orgove = 0 | ||||
| 		for o in queryset: | ||||
| 			if m.Organizator.objects.filter(osoba=o).exists(): | ||||
| 				# Ref: https://docs.djangoproject.com/en/3.2/ref/contrib/admin/#django.contrib.admin.ModelAdmin.message_user | ||||
| 				self.message_user(request, f"Osoba {o} už je org, přeskakuji.", level=WARNING) | ||||
| 				continue | ||||
| 			user = o.user | ||||
| 			if user is None: | ||||
| 				self.message_user(request, f"Osoba {o} nemá uživatele! Přeskakuji.", level=ERROR) | ||||
| 				continue | ||||
| 			user.groups.add(org_group) | ||||
| 			user.is_staff = True | ||||
| 			user.save() | ||||
| 			org = m.Organizator.objects.create(osoba=o, organizuje_od=datetime.now()) | ||||
| 			org.save() | ||||
| 			uspesne_vytvoreni_orgove += 1 | ||||
| 		self.message_user(request, f'Úspěšně vytvořeno {uspesne_vytvoreni_orgove} orgů.', level=SUCCESS) | ||||
| 	udelej_orgem.short_description = "Udělej z vybraných osob organizátory" | ||||
| 
 | ||||
| class OsobaInline(admin.TabularInline): | ||||
| 	model = m.Osoba | ||||
| 
 | ||||
|  | @ -53,9 +74,16 @@ class OrganizatorAdmin(ReverseModelAdmin): | |||
| @admin.register(m.Resitel) | ||||
| class ResitelAdmin(ReverseModelAdmin): | ||||
| 	search_fields = ['osoba__jmeno', 'osoba__prijmeni', 'osoba__prezdivka'] | ||||
| 	list_filter = ['zasilat', 'zasilat_cislo_papirove', 'zasilat_cislo_emailem', 'rok_maturity'] | ||||
| 	ordering = ('osoba__prijmeni', 'osoba__jmeno') | ||||
| 	inline_type = 'stacked' | ||||
| 	inline_reverse = ['osoba'] | ||||
| 
 | ||||
| 	actions = ['udelej_resitele_orgem'] | ||||
| 	@admin.action(description="Udělej z řešitelů organizátory") | ||||
| 	def udelej_resitele_orgem(self, req, qs): | ||||
| 		osoby = m.Osoba.objects.filter(resitel__in=qs) | ||||
| 		udelej_orgem(self, req, osoby) | ||||
| 
 | ||||
| admin.site.register(m.Skola) | ||||
| admin.site.register(m.Prijemce) | ||||
|  |  | |||
|  | @ -1,8 +1,6 @@ | |||
| """ | ||||
| Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace. | ||||
| """ | ||||
| from django.apps import AppConfig | ||||
| 
 | ||||
| 
 | ||||
| class PersonalniConfig(AppConfig): | ||||
|     name = 'personalni' | ||||
|     verbose_name = 'Personální' # Má to nějaký použitelnější název? | ||||
|  |  | |||
|  | @ -32,7 +32,7 @@ class UdajeForm(forms.Form): | |||
| 	jmeno = forms.CharField(label='Jméno', max_length=256, required=True) | ||||
| 	prezdivka_resitele = forms.CharField(label='Přezdívka (veřejná)', max_length=256, required=False) | ||||
| 	prijmeni = forms.CharField(label='Příjmení', max_length=256, required=True) | ||||
| 	pohlavi_muz = forms.ChoiceField(label='Pohlaví', choices=((True, 'muž'), (False, 'žena')), required=True) | ||||
| 	osloveni = forms.ChoiceField(label='Oslovení', choices=Osoba.OSLOVENI_CHOICES, required=False) | ||||
| 	email = forms.EmailField(label='E-mail', max_length=256, required=True) | ||||
| 	telefon = forms.CharField(widget=TelInput(), label='Telefon', max_length=256, required=False) | ||||
| 	datum_narozeni = forms.DateField(widget=DateInput(), label='Datum narození', required=False) | ||||
|  |  | |||
							
								
								
									
										14
									
								
								personalni/migrations/0007_post_split_soustredeni.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								personalni/migrations/0007_post_split_soustredeni.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| # Generated by Django 4.2.11 on 2024-04-30 21:53 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('personalni', '0006_pre_split_soustredeni'), | ||||
|         ('soustredeni', '0003_post_split_soustredeni'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
							
								
								
									
										40
									
								
								personalni/migrations/0008_reforma_pohlavi.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								personalni/migrations/0008_reforma_pohlavi.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,40 @@ | |||
| # Generated by Django 4.2.11 on 2024-04-12 14:03 | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
| 
 | ||||
| # V migracích nemáme Osoba.OSLOVENI_*, tak si to sem nakopíruji. | ||||
| OSLOVENI_MUZSKE = 'resitel' | ||||
| OSLOVENI_ZENSKE = 'resitelka' | ||||
| OSLOVENI_ZADNE = '' | ||||
| 
 | ||||
| def pohlavi_to_osloveni(apps, schema_editor): | ||||
|     Osoba = apps.get_model('personalni', 'Osoba') | ||||
|     Osoba.objects.filter(pohlavi_muz=True).update(osloveni=OSLOVENI_MUZSKE) | ||||
|     Osoba.objects.filter(pohlavi_muz=False).update(osloveni=OSLOVENI_ZENSKE) | ||||
| 
 | ||||
| def osloveni_to_pohlavi(apps, schema_editor): | ||||
|     Osoba = apps.get_model('personalni', 'Osoba') | ||||
|     nebinarni = Osoba.objects.filter(osloveni=OSLOVENI_ZADNE) | ||||
|     if nebinarni.count() > 0: | ||||
|         raise Exception("Nelze odmigrovat: v databázi jsou nebinární osoby, které starý model nereprezentuje správně.") | ||||
|     Osoba.objects.filter(osloveni=OSLOVENI_MUZSKE).update(pohlavi_muz=True) | ||||
|     Osoba.objects.filter(osloveni=OSLOVENI_MUZSKE).update(pohlavi_muz=False) | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('personalni', '0007_post_split_soustredeni'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.AddField( | ||||
|             model_name='osoba', | ||||
|             name='osloveni', | ||||
|             field=models.CharField(blank=True, choices=[('resitel', 'Řešitel'), ('resitelka', 'Řešitelka')], max_length=32, verbose_name='Oslovení'), | ||||
|         ), | ||||
|         migrations.RunPython(pohlavi_to_osloveni, osloveni_to_pohlavi), | ||||
|         migrations.RemoveField( | ||||
|             model_name='osoba', | ||||
|             name='pohlavi_muz', | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										13
									
								
								personalni/migrations/0009_novinky_pre.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								personalni/migrations/0009_novinky_pre.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,13 @@ | |||
| # Generated by Django 4.2.13 on 2024-05-13 20:35 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('personalni', '0008_reforma_pohlavi'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
							
								
								
									
										14
									
								
								personalni/migrations/0010_novinky_post.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								personalni/migrations/0010_novinky_post.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,14 @@ | |||
| # Generated by Django 4.2.13 on 2024-05-13 20:59 | ||||
| 
 | ||||
| from django.db import migrations | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('personalni', '0009_novinky_pre'), | ||||
|         ('novinky', '0003_novinky_post'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|     ] | ||||
							
								
								
									
										18
									
								
								personalni/migrations/0011_osloveni_vsechny_choices.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								personalni/migrations/0011_osloveni_vsechny_choices.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,18 @@ | |||
| # Generated by Django 4.2.13 on 2024-06-03 14:31 | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
| 
 | ||||
| 
 | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ('personalni', '0010_novinky_post'), | ||||
|     ] | ||||
| 
 | ||||
|     operations = [ | ||||
|         migrations.AlterField( | ||||
|             model_name='osoba', | ||||
|             name='osloveni', | ||||
|             field=models.CharField(blank=True, choices=[('resitel', 'Řešitel'), ('resitelka', 'Řešitelka'), ('', 'Cokoliv jiného')], max_length=32, verbose_name='Oslovení'), | ||||
|         ), | ||||
|     ] | ||||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| import logging | ||||
| 
 | ||||
| from django.db import models | ||||
|  | @ -38,8 +37,16 @@ class Osoba(SeminarModelBase): | |||
| 	user = models.OneToOneField(settings.AUTH_USER_MODEL, blank=True, null=True,  | ||||
| 				verbose_name='uživatel', on_delete=models.DO_NOTHING) | ||||
| 
 | ||||
| 	# Pohlaví. Že ho neznáme se snad nestane (a ušetří to práci při programování) | ||||
| 	pohlavi_muz = models.BooleanField('pohlaví (muž)', default=False) | ||||
| 	# Pohlaví nás prakticky nezajímá, reálně. | ||||
| 	OSLOVENI_MUZSKE = 'resitel' | ||||
| 	OSLOVENI_ZENSKE = 'resitelka' | ||||
| 	OSLOVENI_ZADNE = '' | ||||
| 	OSLOVENI_CHOICES = [ | ||||
| 			(OSLOVENI_MUZSKE, 'Řešitel'), | ||||
| 			(OSLOVENI_ZENSKE, 'Řešitelka'), | ||||
| 			(OSLOVENI_ZADNE, 'Cokoliv jiného'), # Reálně nás u nikoho jiného oslovení nezajímá? (A pohlaví už vůbec) | ||||
| 		] | ||||
| 	osloveni = models.CharField('Oslovení', choices=OSLOVENI_CHOICES, max_length=32, blank=True) | ||||
| 
 | ||||
| 	email = models.EmailField('e-mail', max_length=256, blank=True, default='') | ||||
| 
 | ||||
|  | @ -246,11 +253,19 @@ class Resitel(SeminarModelBase): | |||
| 
 | ||||
| 	def export_row(self): | ||||
| 		"Slovnik pro pouziti v AESOP exportu" | ||||
| 		# Ref: https://opmk.mff.cuni.cz/wiki/aesop/import#telo | ||||
| 
 | ||||
| 		# FUJ: Oslovení nemusí souviset s genderem. | ||||
| 		gender = { | ||||
| 			Osoba.OSLOVENI_MUZSKE: 'M', | ||||
| 			Osoba.OSLOVENI_ZENSKE: 'F', | ||||
| 			Osoba.OSLOVENI_ZADNE: '', | ||||
| 			}[self.osoba.osloveni] | ||||
| 		return { | ||||
| 			'id': self.id, | ||||
| 			'name': self.osoba.jmeno, | ||||
| 			'surname': self.osoba.prijmeni, | ||||
| 			'gender': 'M' if self.osoba.pohlavi_muz else 'F', | ||||
| 			'gender': gender, | ||||
| 			'born': self.osoba.datum_narozeni.isoformat() if self.osoba.datum_narozeni else '', | ||||
| 			'email': self.osoba.email, | ||||
| 			'end-year': self.rok_maturity or '', | ||||
|  |  | |||
|  | @ -13,18 +13,18 @@ | |||
| 		<li>soustředění</li> | ||||
| 	</ul> | ||||
| 	</li> | ||||
| 	<li><a href="/admin/seminar/novinky/add/"><strong>přidat novinku</strong></a> na web</li> | ||||
| 	<li><a href="{% url 'admin:novinky_novinky_add' %}"><strong>přidat novinku</strong></a> na web</li> | ||||
| </ul> | ||||
| 
 | ||||
| <hr /> | ||||
| <h2><strong>Tvorba čísla</strong></h2> | ||||
| 
 | ||||
| <ul> | ||||
| 	<li><a href="/admin/seminar/problem/add/"><strong>přidat téma</strong></a></li> | ||||
| 	<li><a href="{% url 'admin:seminar_problem_add' %}"><strong>přidat téma</strong></a></li> | ||||
| 	<li><strong>korektury</strong> | ||||
| 	<ul> | ||||
| 		<li><a href="/korektury/">korekturování</a></li> | ||||
| 		<li><a href="/admin/korektury/korekturovanepdf/add/">přidat pdf k opravám</a></li> | ||||
| 		<li><a href="{% url 'korektury_list' %}">korekturování</a></li> | ||||
| 		<li><a href="{% url 'admin:korektury_korekturovanepdf_add' %}">přidat pdf k opravám</a></li> | ||||
| 	</ul> | ||||
| 	</li> | ||||
| 	<li> | ||||
|  | @ -70,15 +70,15 @@ | |||
| <h2><strong>Soustředění</strong></h2> | ||||
| 
 | ||||
| <ul> | ||||
| 	<li><a href="/admin/seminar/soustredeni/add/">přidat soustředění</a></li> | ||||
| 	<li><a href="{% url 'admin:soustredeni_soustredeni_add' %}">přidat soustředění</a></li> | ||||
| 	<li><strong>přednášky</strong> | ||||
| 
 | ||||
| 	<ul> | ||||
| 		<li><a href="/admin/prednasky/prednaska/">vypisování přednášek</a></li> | ||||
| 		<li><a href="{% url 'admin:prednasky_prednaska_add' %}">vypisování přednášek</a></li> | ||||
| 		<li>hlasování o přednáškách</li> | ||||
| 	</ul> | ||||
| 	</li> | ||||
| 	<li><a href="/soustredeni/probehlo/">proběhlá soustředění</a> | ||||
| 	<li><a href="{% url 'seminar_seznam_soustredeni' %}">proběhlá soustředění</a> | ||||
| 	<ul> | ||||
| 		<li>vytvoření galerie</li> | ||||
| 		<li>stažení seznamu účastníků</li> | ||||
|  | @ -91,7 +91,7 @@ | |||
| <h2><strong>Můj profil</strong></h2> | ||||
| 
 | ||||
| <ul> | ||||
| 	<li><a href="/admin/seminar/organizator/{{ organizator.id }}/change/"><strong>upravit </strong></a></li> | ||||
| 	<li><a href="{% url 'admin:personalni_organizator_change' organizator.id %}"><strong>upravit </strong></a></li> | ||||
| </ul> | ||||
| 
 | ||||
| <hr/> | ||||
|  | @ -108,6 +108,6 @@ | |||
| </ul> | ||||
| 
 | ||||
| <hr /> | ||||
| <p>Nemůžeš najít, co hledáš? Může to být v <a href="/admin/">administračním rozhraní webu</a>.</p> | ||||
| <p>Nemůžeš najít, co hledáš? Může to být v <a href="{% url 'admin:index' %}">administračním rozhraní webu</a>.</p> | ||||
| {% endblock content %} | ||||
| 
 | ||||
|  |  | |||
|  | @ -24,7 +24,7 @@ | |||
|   {% include "personalni/udaje/prihlaska_field.html" with field=form.jmeno %} | ||||
|   {% include "personalni/udaje/prihlaska_field.html" with field=form.prezdivka_resitele %} | ||||
|   {% include "personalni/udaje/prihlaska_field.html" with field=form.prijmeni %} | ||||
|   {% include "personalni/udaje/prihlaska_field.html" with field=form.pohlavi_muz%} | ||||
|   {% include "personalni/udaje/prihlaska_field.html" with field=form.osloveni%} | ||||
|   {% include "personalni/udaje/prihlaska_field.html" with field=form.email %} | ||||
|   {% include "personalni/udaje/prihlaska_field.html" with field=form.telefon %} | ||||
|   {% include "personalni/udaje/prihlaska_field.html" with field=form.datum_narozeni %} | ||||
|  |  | |||
|  | @ -1,17 +1,3 @@ | |||
| """ | ||||
| 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 | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ from django.views import generic | |||
| from django.db.models import Q, Count, Min | ||||
| from django.views.decorators.debug import sensitive_post_parameters | ||||
| from django.views.generic.base import TemplateView | ||||
| from django.contrib.auth.models import User, Permission, Group | ||||
| from django.contrib.auth.models import User, Permission, Group, AnonymousUser | ||||
| from django.contrib.auth.mixins import LoginRequiredMixin | ||||
| from django.db import transaction | ||||
| from django.http import HttpResponse | ||||
|  | @ -139,7 +139,7 @@ def resitelEditView(request): | |||
| 			form_logger.info("EDIT:" + str(fcd) + str(form_hash))  # TODO možná logovat jinak | ||||
| 			osoba_edit.jmeno = fcd['jmeno'] | ||||
| 			osoba_edit.prijmeni = fcd['prijmeni'] | ||||
| 			osoba_edit.pohlavi_muz = fcd['pohlavi_muz'] | ||||
| 			osoba_edit.osloveni = fcd['osloveni'] | ||||
| 			osoba_edit.email = fcd['email'] | ||||
| 			osoba_edit.telefon = fcd['telefon'] | ||||
| 			osoba_edit.ulice = fcd['ulice'] | ||||
|  | @ -209,7 +209,7 @@ def prihlaskaView(request): | |||
| 				o = s.Osoba( | ||||
| 					jmeno = fcd['jmeno'], | ||||
| 					prijmeni = fcd['prijmeni'], | ||||
| 					pohlavi_muz = fcd['pohlavi_muz'], | ||||
| 					osloveni = fcd['osloveni'], | ||||
| 					email = fcd['email'], | ||||
| 					telefon = fcd.get('telefon',''), | ||||
| 					datum_narozeni = fcd.get('datum_narozeni',None), | ||||
|  | @ -242,7 +242,7 @@ def prihlaskaView(request): | |||
| 
 | ||||
| 				# Porovnání údajů | ||||
| 				assert orig_osoba.user is None, "Právě-registrující-se osoba už má Uživatele!" | ||||
| 				osoba_attrs = ['jmeno', 'prijmeni', 'pohlavi_muz', 'email', 'telefon', 'datum_narozeni', 'ulice', 'mesto', 'psc', 'stat', 'datum_souhlasu_udaje', 'datum_souhlasu_zasilani', 'datum_registrace'] | ||||
| 				osoba_attrs = ['jmeno', 'prijmeni', 'osloveni', 'email', 'telefon', 'datum_narozeni', 'ulice', 'mesto', 'psc', 'stat', 'datum_souhlasu_udaje', 'datum_souhlasu_zasilani', 'datum_registrace'] | ||||
| 				diffattrs = [] | ||||
| 				for attr in osoba_attrs: | ||||
| 					new = getattr(o, attr) | ||||
|  | @ -318,6 +318,12 @@ def prihlaskaView(request): | |||
| # Jen hloupé rozhazovátko | ||||
| def profilView(request): | ||||
| 	user = request.user | ||||
| 	if not isinstance(user, AnonymousUser) and m.Osoba.objects.filter(user=user).count() != 1: | ||||
| 		# m.Osoba.objects.get() v ostatních views selže | ||||
| 		return render(request, "universal.html", { | ||||
| 			'title': 'Krize identity.', | ||||
| 			'raw_html': r'<blockquote>Zvláštní pocit, že jo?<br>[…]<br>Co to znamená?<br>— Že ti MaMweb neumí říct, kdo jsi.<br>A <a href="/admin">Admin</a> ano?<br>— V tom je rozdíl.</blockquote> — Matrix (1999), parafrázováno', | ||||
| 			}) | ||||
| 	if user.has_perm('auth.org'): | ||||
| 		return OrgoRozcestnikView.as_view()(request) | ||||
| 	if user.has_perm('auth.resitel'): | ||||
|  | @ -339,7 +345,7 @@ def dataResiteluCsvResponse(queryset, columns=None, with_header=True): | |||
| 		'osoba__telefon', | ||||
| 		'osoba__user__username', | ||||
| 		'osoba__datum_narozeni', | ||||
| 		'osoba__pohlavi_muz', | ||||
| 		'osoba__osloveni', | ||||
| 		'osoba__ulice', | ||||
| 		'osoba__mesto', | ||||
| 		'osoba__psc', | ||||
|  | @ -367,7 +373,7 @@ def dataResiteluCsvResponse(queryset, columns=None, with_header=True): | |||
| 		'osoba__telefon':                'telefon', | ||||
| 		'osoba__user__username':         'user', | ||||
| 		'osoba__datum_narozeni':         'datum_narozeni', | ||||
| 		'osoba__pohlavi_muz':            'pohlavi_muz', | ||||
| 		'osoba__osloveni':               'osloveni', | ||||
| 		'osoba__ulice':                  'ulice', | ||||
| 		'osoba__mesto':                  'mesto', | ||||
| 		'osoba__psc':                    'psc', | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from django.contrib import admin | ||||
| from django.contrib import messages | ||||
| from reversion.admin import VersionAdmin | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # coding: utf-8 | ||||
| from django import forms | ||||
| 
 | ||||
| class NewPrednaskyForm(forms.Form): | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
|  |  | |||
|  | @ -1,4 +1,3 @@ | |||
| # -*- coding: utf-8 -*- | ||||
| from __future__ import unicode_literals | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
|  |  | |||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
		Reference in a new issue