Merge branch 'master' into static-files-upgrade
This commit is contained in:
		
						commit
						05e6e5fb59
					
				
					 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 kvůli historii objektů v reversion | ||||||
| **/reversion | **/reversion | ||||||
| 
 | 
 | ||||||
| # pro lidi, co programují v nástrojích od JetBrains |  | ||||||
| .idea |  | ||||||
| 
 |  | ||||||
| # dokumentace | # dokumentace | ||||||
| docs/_build | docs/_build | ||||||
| docs/modules | docs/modules | ||||||
|  | 
 | ||||||
|  | # logy týracího skriptu (./checklinks.sh) | ||||||
|  | /wget.log.* | ||||||
|  | 
 | ||||||
|  | # pro lidi, co programují v nástrojích od JetBrains | ||||||
|  | .idea | ||||||
|  | 
 | ||||||
|  | # 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 | from django.apps import AppConfig | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| class AesopConfig(AppConfig): | class AesopConfig(AppConfig): | ||||||
|     name = 'aesop' |     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 django.urls import path | ||||||
| from aesop import views | 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 | import django | ||||||
| from django.shortcuts import get_object_or_404 | from django.shortcuts import get_object_or_404 | ||||||
| from django.http import HttpResponse | from django.http import HttpResponse | ||||||
|  |  | ||||||
|  | @ -1,8 +1,6 @@ | ||||||
| """ |  | ||||||
| Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace. |  | ||||||
| """ |  | ||||||
| from django.apps import AppConfig | from django.apps import AppConfig | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class ApiConfig(AppConfig): | class ApiConfig(AppConfig): | ||||||
|     name = 'api' |     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 django.urls import path | ||||||
| from . import views | from . import views | ||||||
| from seminar.utils import org_required | 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 .autocomplete import * | ||||||
| from .exports import * | from .exports import * | ||||||
|  |  | ||||||
|  | @ -1079,5 +1079,29 @@ | ||||||
| 		}, | 		}, | ||||||
| 		"model": "sitetree.treeitem", | 		"model": "sitetree.treeitem", | ||||||
| 		"pk": 53 | 		"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", | 		"codename": "add_novinky", | ||||||
| 		"ct_app_label": "seminar", | 		"ct_app_label": "novinky", | ||||||
| 		"ct_model": "novinky" | 		"ct_model": "novinky" | ||||||
| 	}, | 	}, | ||||||
| 	{ | 	{ | ||||||
| 		"codename": "change_novinky", | 		"codename": "change_novinky", | ||||||
| 		"ct_app_label": "seminar", | 		"ct_app_label": "novinky", | ||||||
| 		"ct_model": "novinky" | 		"ct_model": "novinky" | ||||||
| 	}, | 	}, | ||||||
| 	{ | 	{ | ||||||
| 		"codename": "delete_novinky", | 		"codename": "delete_novinky", | ||||||
| 		"ct_app_label": "seminar", | 		"ct_app_label": "novinky", | ||||||
| 		"ct_model": "novinky" | 		"ct_model": "novinky" | ||||||
| 	}, | 	}, | ||||||
| 	{ | 	{ | ||||||
| 		"codename": "view_novinky", | 		"codename": "view_novinky", | ||||||
| 		"ct_app_label": "seminar", | 		"ct_app_label": "novinky", | ||||||
| 		"ct_model": "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``. | 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 | data | ||||||
| ---- | ---- | ||||||
| Obsahuje data, která patří do databáze, ale jsou přímo součástí webu jako | 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: | Přidání obrázků do odměn: | ||||||
| admin -> flatpage odměn -> ikona přidat obrázek | admin -> flatpage odměn -> ikona přidat obrázek | ||||||
| záložka odeslat, vybrat obrázek, odeslat | 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 galerie.models import Obrazek, Galerie | ||||||
| from django.contrib import admin | from django.contrib import admin | ||||||
| from django.http import HttpResponseRedirect | 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 django import forms | ||||||
| from seminar.models import Soustredeni | from seminar.models import Soustredeni | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import models, migrations | from django.db import models, migrations | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import models, migrations | from django.db import models, migrations | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import models, migrations | from django.db import models, migrations | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import models, migrations | from django.db import models, migrations | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import models, migrations | from django.db import models, migrations | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import models, migrations | from django.db import models, migrations | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import models, migrations | 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 | # Generated by Django 1.11.20 on 2019-04-30 21:40 | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| # Generated by Django 1.11.21 on 2019-06-10 21:58 | # Generated by Django 1.11.21 on 2019-06-10 21:58 | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,5 +1,3 @@ | ||||||
| # coding: utf-8 |  | ||||||
| 
 |  | ||||||
| from django.db import models | from django.db import models | ||||||
| #from django.db.models import Q | #from django.db.models import Q | ||||||
| from imagekit.models import ImageSpecField | 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 django.urls import path | ||||||
| from seminar.utils import org_required | from seminar.utils import org_required | ||||||
| from . import views | from . import views | ||||||
|  |  | ||||||
|  | @ -1,5 +1,3 @@ | ||||||
| # coding: utf-8 |  | ||||||
| 
 |  | ||||||
| import random | import random | ||||||
| 
 | 
 | ||||||
| from django.http import HttpResponse, Http404 | 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 import admin | ||||||
| from django.contrib.admin import ModelAdmin | from django.contrib.admin import ModelAdmin | ||||||
| import header_fotky.models as m | import header_fotky.models as m | ||||||
|  |  | ||||||
|  | @ -1,8 +1,6 @@ | ||||||
| """ |  | ||||||
| Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace. |  | ||||||
| """ |  | ||||||
| from django.apps import AppConfig | from django.apps import AppConfig | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class HeaderFotkyConfig(AppConfig): | class HeaderFotkyConfig(AppConfig): | ||||||
|     name = 'header_fotky' |     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.core.exceptions import ValidationError | ||||||
| from django.db import models | from django.db import models | ||||||
| from django.utils import timezone | 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 django.contrib import admin | ||||||
| from reversion.admin import VersionAdmin | from reversion.admin import VersionAdmin | ||||||
| from korektury.models import KorekturovanePDF | from korektury.models import KorekturovanePDF | ||||||
|  | @ -15,7 +5,6 @@ from korektury.models import KorekturovanePDF | ||||||
| from django.core.mail import EmailMessage | from django.core.mail import EmailMessage | ||||||
| from django.urls import reverse | from django.urls import reverse | ||||||
| 
 | 
 | ||||||
| # Register your models here. |  | ||||||
| class KorekturovanePDFAdmin(VersionAdmin): | class KorekturovanePDFAdmin(VersionAdmin): | ||||||
| 	""" | 	""" | ||||||
| 	nastaví čas vložení (:attr:`~koretkury.models.KorekturovanePDF.cas`) a počet | 	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 | from django import forms | ||||||
| 
 | 
 | ||||||
| class OpravaForm(forms.Form): | class OpravaForm(forms.Form): | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import models, migrations | from django.db import models, migrations | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import models, migrations | from django.db import models, migrations | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import models, migrations | from django.db import models, migrations | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import models, migrations | from django.db import models, migrations | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import models, migrations | from django.db import models, migrations | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import models, migrations | from django.db import models, migrations | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import models, migrations | from django.db import models, migrations | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import models, migrations | from django.db import models, migrations | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import migrations, models | 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 | # Generated by Django 1.11.20 on 2019-04-30 21:40 | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| # Generated by Django 1.11.21 on 2019-06-10 21:58 | # Generated by Django 1.11.21 on 2019-06-10 21:58 | ||||||
| from __future__ import unicode_literals | 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 | import os | ||||||
| from django.db import models | from django.db import models | ||||||
| from django.utils import timezone | 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 django.urls import path | ||||||
| from seminar.utils import org_required | from seminar.utils import org_required | ||||||
| from . import views | 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.shortcuts import get_object_or_404, render | ||||||
| from django.views import generic | from django.views import generic | ||||||
| from django.conf import settings | from django.conf import settings | ||||||
|  | @ -199,13 +194,6 @@ class KorekturyView(generic.TemplateView): | ||||||
| 		if email: | 		if email: | ||||||
| 			emails.discard(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( | 		EmailMessage( | ||||||
| 			subject=subject, | 			subject=subject, | ||||||
| 			body=text, | 			body=text, | ||||||
|  |  | ||||||
|  | @ -7,5 +7,5 @@ make/install_web | ||||||
| ensure_venv | ensure_venv | ||||||
| ./manage.py testdata | ./manage.py testdata | ||||||
| ./manage.py loaddata data/* | ./manage.py loaddata data/* | ||||||
| make/sync_prod_flatpages | #make/sync_prod_flatpages | ||||||
| ./manage.py load_org_permissions deploy_v2/admin_org_prava.json | ./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) | 	app_dict = self._build_app_dict(request, label=app_label) | ||||||
| 	# Sort the apps alphabetically. | 	aplikace_nahore = [ | ||||||
| 	app_list = sorted(app_dict.values(), key=lambda x: locale.strxfrm('!') if (x['name'] == "Seminar") else locale.strxfrm(x['name'].lower())) | 		'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. | 	# Sort the models alphabetically within each app. | ||||||
| 	for app in app_list: | 	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.contrib.sessions.middleware.SessionMiddleware', | ||||||
| 	'django.middleware.common.CommonMiddleware', | 	'django.middleware.common.CommonMiddleware', | ||||||
| 	'django.middleware.csrf.CsrfViewMiddleware', | 	'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.auth.middleware.AuthenticationMiddleware', | ||||||
| 	'django.contrib.messages.middleware.MessageMiddleware', | 	'django.contrib.messages.middleware.MessageMiddleware', | ||||||
| 	'django.middleware.clickjacking.XFrameOptionsMiddleware', | 	'django.middleware.clickjacking.XFrameOptionsMiddleware', | ||||||
|  | @ -149,6 +146,7 @@ INSTALLED_APPS = ( | ||||||
| 	'treenode', | 	'treenode', | ||||||
| 	'vyroci', | 	'vyroci', | ||||||
| 	'sifrovacka', | 	'sifrovacka', | ||||||
|  | 	'novinky', | ||||||
| 
 | 
 | ||||||
| 	# Admin upravy: | 	# Admin upravy: | ||||||
| 
 | 
 | ||||||
|  | @ -344,10 +342,6 @@ KOREKTURY_IMG_DIR = os.path.join('korektury', 'img') | ||||||
| CISLO_IMG_DIR = os.path.join('cislo', 'img') | CISLO_IMG_DIR = os.path.join('cislo', 'img') | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # E-MAIL NOTIFICATIONS |  | ||||||
| POSLI_MAILOVOU_NOTIFIKACI = False |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
| # Logování chyb | # Logování chyb | ||||||
| class InvalidTemplateVariable(str): | class InvalidTemplateVariable(str): | ||||||
|  |  | ||||||
|  | @ -1,5 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| 
 |  | ||||||
| import os.path | import os.path | ||||||
| 
 | 
 | ||||||
| # | # | ||||||
|  | @ -70,5 +68,4 @@ LOGGING['handlers']['registration_error_log']['filename'] = '/home/mam-web/logs/ | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # E-MAIL NOTIFICATIONS | # E-MAIL NOTIFICATIONS | ||||||
| POSLI_MAILOVOU_NOTIFIKACI = True |  | ||||||
| LOCAL_TEST_PROD = "prod" | LOCAL_TEST_PROD = "prod" | ||||||
|  |  | ||||||
|  | @ -1,5 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| 
 |  | ||||||
| import os.path | import os.path | ||||||
| 
 | 
 | ||||||
| # | # | ||||||
|  | @ -74,7 +72,6 @@ LOGGING['handlers']['registration_error_log']['filename'] = '/home/mam-web/logs/ | ||||||
| FILE_UPLOAD_PERMISSIONS = 0o440 | FILE_UPLOAD_PERMISSIONS = 0o440 | ||||||
| 
 | 
 | ||||||
| # Testování e-mailů | # Testování e-mailů | ||||||
| POSLI_MAILOVOU_NOTIFIKACI = True |  | ||||||
| EMAIL_BACKEND = 'various.mail_prefixer.PrefixingMailBackend' | EMAIL_BACKEND = 'various.mail_prefixer.PrefixingMailBackend' | ||||||
| # TODO Pouze na otestování testu… Zvolit konferu! | # TODO Pouze na otestování testu… Zvolit konferu! | ||||||
| # XXX: Je to pole, protože implementační detail backendu. | # 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: | 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` |  | ||||||
| """ | """ | ||||||
| from django.urls import path, include | from django.urls import path, include | ||||||
| from django.contrib.staticfiles.urls import staticfiles_urlpatterns | from django.contrib.staticfiles.urls import staticfiles_urlpatterns | ||||||
|  |  | ||||||
							
								
								
									
										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 = 'Novinka' | ||||||
| 		verbose_name_plural = 'Novinky' | 		verbose_name_plural = 'Novinky' | ||||||
| 		ordering = ['-datum'] | 		ordering = ['-datum'] | ||||||
|  | 		db_table = 'seminar_novinky' | ||||||
| 
 | 
 | ||||||
| 	datum = models.DateField(auto_now_add=True) | 	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.contrib import admin | ||||||
| from django_reverse_admin import ReverseModelAdmin | from django_reverse_admin import ReverseModelAdmin | ||||||
| import seminar.models as m | import seminar.models as m | ||||||
|  |  | ||||||
|  | @ -1,8 +1,6 @@ | ||||||
| """ |  | ||||||
| Soubor sloužící k pojmenování a jiným nastavením djangovské aplikace. |  | ||||||
| """ |  | ||||||
| from django.apps import AppConfig | from django.apps import AppConfig | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class OdevzdavatkoConfig(AppConfig): | class OdevzdavatkoConfig(AppConfig): | ||||||
|     name = 'odevzdavatko' |     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 django.urls import path | ||||||
| 
 | 
 | ||||||
| from seminar.utils import org_required, resitel_required, viewMethodSwitch, \ | from seminar.utils import org_required, resitel_required, viewMethodSwitch, \ | ||||||
|  |  | ||||||
|  | @ -504,7 +504,7 @@ class NahrajReseniView(LoginRequiredMixin, CreateView): | ||||||
| 
 | 
 | ||||||
| 		EmailMessage( | 		EmailMessage( | ||||||
| 			subject="Nové řešení k " + seznam_do_subjectu, | 			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í? | 			from_email="submitovatko@mam.mff.cuni.cz", # FIXME: Chceme to mít radši tady, nebo v nastavení? | ||||||
| 			to=list(prijemci), | 			to=list(prijemci), | ||||||
| 		).send() | 		).send() | ||||||
|  |  | ||||||
|  | @ -5,10 +5,52 @@ from django.contrib.messages import WARNING, ERROR, SUCCESS | ||||||
| import seminar.models as m | import seminar.models as m | ||||||
| from datetime import datetime | 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) | @admin.register(m.Osoba) | ||||||
| class OsobaAdmin(admin.ModelAdmin): | class OsobaAdmin(admin.ModelAdmin): | ||||||
| 	actions = ['synchronizuj_maily', 'udelej_orgem'] | 	actions = ['synchronizuj_maily', udelej_orgem, sjednot_telefony] | ||||||
| 	search_fields = ['jmeno', 'prijmeni', 'prezdivka'] | 	search_fields = ['jmeno', 'prijmeni', 'prezdivka'] | ||||||
| 
 | 
 | ||||||
| 	def synchronizuj_maily(self, request, queryset): | 	def synchronizuj_maily(self, request, queryset): | ||||||
|  | @ -20,27 +62,6 @@ class OsobaAdmin(admin.ModelAdmin): | ||||||
| 		self.message_user(request, "E-maily synchronizovány.") | 		self.message_user(request, "E-maily synchronizovány.") | ||||||
| 	synchronizuj_maily.short_description = "Synchronizuj vybraným osobám e-maily do uživatelů" | 	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): | class OsobaInline(admin.TabularInline): | ||||||
| 	model = m.Osoba | 	model = m.Osoba | ||||||
| 
 | 
 | ||||||
|  | @ -53,9 +74,16 @@ class OrganizatorAdmin(ReverseModelAdmin): | ||||||
| @admin.register(m.Resitel) | @admin.register(m.Resitel) | ||||||
| class ResitelAdmin(ReverseModelAdmin): | class ResitelAdmin(ReverseModelAdmin): | ||||||
| 	search_fields = ['osoba__jmeno', 'osoba__prijmeni', 'osoba__prezdivka'] | 	search_fields = ['osoba__jmeno', 'osoba__prijmeni', 'osoba__prezdivka'] | ||||||
|  | 	list_filter = ['zasilat', 'zasilat_cislo_papirove', 'zasilat_cislo_emailem', 'rok_maturity'] | ||||||
| 	ordering = ('osoba__prijmeni', 'osoba__jmeno') | 	ordering = ('osoba__prijmeni', 'osoba__jmeno') | ||||||
| 	inline_type = 'stacked' | 	inline_type = 'stacked' | ||||||
| 	inline_reverse = ['osoba'] | 	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.Skola) | ||||||
| admin.site.register(m.Prijemce) | 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 | from django.apps import AppConfig | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class PersonalniConfig(AppConfig): | class PersonalniConfig(AppConfig): | ||||||
|     name = 'personalni' |     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) | 	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) | 	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) | 	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) | 	email = forms.EmailField(label='E-mail', max_length=256, required=True) | ||||||
| 	telefon = forms.CharField(widget=TelInput(), label='Telefon', max_length=256, required=False) | 	telefon = forms.CharField(widget=TelInput(), label='Telefon', max_length=256, required=False) | ||||||
| 	datum_narozeni = forms.DateField(widget=DateInput(), label='Datum narození', 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 | import logging | ||||||
| 
 | 
 | ||||||
| from django.db import models | from django.db import models | ||||||
|  | @ -38,8 +37,16 @@ class Osoba(SeminarModelBase): | ||||||
| 	user = models.OneToOneField(settings.AUTH_USER_MODEL, blank=True, null=True,  | 	user = models.OneToOneField(settings.AUTH_USER_MODEL, blank=True, null=True,  | ||||||
| 				verbose_name='uživatel', on_delete=models.DO_NOTHING) | 				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í) | 	# Pohlaví nás prakticky nezajímá, reálně. | ||||||
| 	pohlavi_muz = models.BooleanField('pohlaví (muž)', default=False) | 	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='') | 	email = models.EmailField('e-mail', max_length=256, blank=True, default='') | ||||||
| 
 | 
 | ||||||
|  | @ -246,11 +253,19 @@ class Resitel(SeminarModelBase): | ||||||
| 
 | 
 | ||||||
| 	def export_row(self): | 	def export_row(self): | ||||||
| 		"Slovnik pro pouziti v AESOP exportu" | 		"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 { | 		return { | ||||||
| 			'id': self.id, | 			'id': self.id, | ||||||
| 			'name': self.osoba.jmeno, | 			'name': self.osoba.jmeno, | ||||||
| 			'surname': self.osoba.prijmeni, | 			'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 '', | 			'born': self.osoba.datum_narozeni.isoformat() if self.osoba.datum_narozeni else '', | ||||||
| 			'email': self.osoba.email, | 			'email': self.osoba.email, | ||||||
| 			'end-year': self.rok_maturity or '', | 			'end-year': self.rok_maturity or '', | ||||||
|  |  | ||||||
|  | @ -13,18 +13,18 @@ | ||||||
| 		<li>soustředění</li> | 		<li>soustředění</li> | ||||||
| 	</ul> | 	</ul> | ||||||
| 	</li> | 	</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> | </ul> | ||||||
| 
 | 
 | ||||||
| <hr /> | <hr /> | ||||||
| <h2><strong>Tvorba čísla</strong></h2> | <h2><strong>Tvorba čísla</strong></h2> | ||||||
| 
 | 
 | ||||||
| <ul> | <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> | 	<li><strong>korektury</strong> | ||||||
| 	<ul> | 	<ul> | ||||||
| 		<li><a href="/korektury/">korekturování</a></li> | 		<li><a href="{% url 'korektury_list' %}">korekturování</a></li> | ||||||
| 		<li><a href="/admin/korektury/korekturovanepdf/add/">přidat pdf k opravám</a></li> | 		<li><a href="{% url 'admin:korektury_korekturovanepdf_add' %}">přidat pdf k opravám</a></li> | ||||||
| 	</ul> | 	</ul> | ||||||
| 	</li> | 	</li> | ||||||
| 	<li> | 	<li> | ||||||
|  | @ -70,15 +70,15 @@ | ||||||
| <h2><strong>Soustředění</strong></h2> | <h2><strong>Soustředění</strong></h2> | ||||||
| 
 | 
 | ||||||
| <ul> | <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> | 	<li><strong>přednášky</strong> | ||||||
| 
 | 
 | ||||||
| 	<ul> | 	<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> | 		<li>hlasování o přednáškách</li> | ||||||
| 	</ul> | 	</ul> | ||||||
| 	</li> | 	</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> | 	<ul> | ||||||
| 		<li>vytvoření galerie</li> | 		<li>vytvoření galerie</li> | ||||||
| 		<li>stažení seznamu účastníků</li> | 		<li>stažení seznamu účastníků</li> | ||||||
|  | @ -91,7 +91,7 @@ | ||||||
| <h2><strong>Můj profil</strong></h2> | <h2><strong>Můj profil</strong></h2> | ||||||
| 
 | 
 | ||||||
| <ul> | <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> | </ul> | ||||||
| 
 | 
 | ||||||
| <hr/> | <hr/> | ||||||
|  | @ -108,6 +108,6 @@ | ||||||
| </ul> | </ul> | ||||||
| 
 | 
 | ||||||
| <hr /> | <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 %} | {% 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.jmeno %} | ||||||
|   {% include "personalni/udaje/prihlaska_field.html" with field=form.prezdivka_resitele %} |   {% 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.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.email %} | ||||||
|   {% include "personalni/udaje/prihlaska_field.html" with field=form.telefon %} |   {% include "personalni/udaje/prihlaska_field.html" with field=form.telefon %} | ||||||
|   {% include "personalni/udaje/prihlaska_field.html" with field=form.datum_narozeni %} |   {% 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.urls import path | ||||||
| from django.contrib.auth.decorators import login_required | from django.contrib.auth.decorators import login_required | ||||||
| from . import views | from . import views | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ from django.views import generic | ||||||
| from django.db.models import Q, Count, Min | from django.db.models import Q, Count, Min | ||||||
| from django.views.decorators.debug import sensitive_post_parameters | from django.views.decorators.debug import sensitive_post_parameters | ||||||
| from django.views.generic.base import TemplateView | 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.contrib.auth.mixins import LoginRequiredMixin | ||||||
| from django.db import transaction | from django.db import transaction | ||||||
| from django.http import HttpResponse | 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 | 			form_logger.info("EDIT:" + str(fcd) + str(form_hash))  # TODO možná logovat jinak | ||||||
| 			osoba_edit.jmeno = fcd['jmeno'] | 			osoba_edit.jmeno = fcd['jmeno'] | ||||||
| 			osoba_edit.prijmeni = fcd['prijmeni'] | 			osoba_edit.prijmeni = fcd['prijmeni'] | ||||||
| 			osoba_edit.pohlavi_muz = fcd['pohlavi_muz'] | 			osoba_edit.osloveni = fcd['osloveni'] | ||||||
| 			osoba_edit.email = fcd['email'] | 			osoba_edit.email = fcd['email'] | ||||||
| 			osoba_edit.telefon = fcd['telefon'] | 			osoba_edit.telefon = fcd['telefon'] | ||||||
| 			osoba_edit.ulice = fcd['ulice'] | 			osoba_edit.ulice = fcd['ulice'] | ||||||
|  | @ -209,7 +209,7 @@ def prihlaskaView(request): | ||||||
| 				o = s.Osoba( | 				o = s.Osoba( | ||||||
| 					jmeno = fcd['jmeno'], | 					jmeno = fcd['jmeno'], | ||||||
| 					prijmeni = fcd['prijmeni'], | 					prijmeni = fcd['prijmeni'], | ||||||
| 					pohlavi_muz = fcd['pohlavi_muz'], | 					osloveni = fcd['osloveni'], | ||||||
| 					email = fcd['email'], | 					email = fcd['email'], | ||||||
| 					telefon = fcd.get('telefon',''), | 					telefon = fcd.get('telefon',''), | ||||||
| 					datum_narozeni = fcd.get('datum_narozeni',None), | 					datum_narozeni = fcd.get('datum_narozeni',None), | ||||||
|  | @ -242,7 +242,7 @@ def prihlaskaView(request): | ||||||
| 
 | 
 | ||||||
| 				# Porovnání údajů | 				# Porovnání údajů | ||||||
| 				assert orig_osoba.user is None, "Právě-registrující-se osoba už má Uživatele!" | 				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 = [] | 				diffattrs = [] | ||||||
| 				for attr in osoba_attrs: | 				for attr in osoba_attrs: | ||||||
| 					new = getattr(o, attr) | 					new = getattr(o, attr) | ||||||
|  | @ -318,6 +318,12 @@ def prihlaskaView(request): | ||||||
| # Jen hloupé rozhazovátko | # Jen hloupé rozhazovátko | ||||||
| def profilView(request): | def profilView(request): | ||||||
| 	user = request.user | 	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'): | 	if user.has_perm('auth.org'): | ||||||
| 		return OrgoRozcestnikView.as_view()(request) | 		return OrgoRozcestnikView.as_view()(request) | ||||||
| 	if user.has_perm('auth.resitel'): | 	if user.has_perm('auth.resitel'): | ||||||
|  | @ -339,7 +345,7 @@ def dataResiteluCsvResponse(queryset, columns=None, with_header=True): | ||||||
| 		'osoba__telefon', | 		'osoba__telefon', | ||||||
| 		'osoba__user__username', | 		'osoba__user__username', | ||||||
| 		'osoba__datum_narozeni', | 		'osoba__datum_narozeni', | ||||||
| 		'osoba__pohlavi_muz', | 		'osoba__osloveni', | ||||||
| 		'osoba__ulice', | 		'osoba__ulice', | ||||||
| 		'osoba__mesto', | 		'osoba__mesto', | ||||||
| 		'osoba__psc', | 		'osoba__psc', | ||||||
|  | @ -367,7 +373,7 @@ def dataResiteluCsvResponse(queryset, columns=None, with_header=True): | ||||||
| 		'osoba__telefon':                'telefon', | 		'osoba__telefon':                'telefon', | ||||||
| 		'osoba__user__username':         'user', | 		'osoba__user__username':         'user', | ||||||
| 		'osoba__datum_narozeni':         'datum_narozeni', | 		'osoba__datum_narozeni':         'datum_narozeni', | ||||||
| 		'osoba__pohlavi_muz':            'pohlavi_muz', | 		'osoba__osloveni':               'osloveni', | ||||||
| 		'osoba__ulice':                  'ulice', | 		'osoba__ulice':                  'ulice', | ||||||
| 		'osoba__mesto':                  'mesto', | 		'osoba__mesto':                  'mesto', | ||||||
| 		'osoba__psc':                    'psc', | 		'osoba__psc':                    'psc', | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from django.contrib import admin | from django.contrib import admin | ||||||
| from django.contrib import messages | from django.contrib import messages | ||||||
| from reversion.admin import VersionAdmin | from reversion.admin import VersionAdmin | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # coding: utf-8 |  | ||||||
| from django import forms | from django import forms | ||||||
| 
 | 
 | ||||||
| class NewPrednaskyForm(forms.Form): | class NewPrednaskyForm(forms.Form): | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
|  |  | ||||||
|  | @ -1,4 +1,3 @@ | ||||||
| # -*- coding: utf-8 -*- |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
| 
 | 
 | ||||||
| from django.db import migrations, models | 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