Compare commits
No commits in common. "master" and "a9a426ca916b0f0e2d016709ea8ded74baa6c6c0" have entirely different histories.
master
...
a9a426ca91
623 changed files with 20672 additions and 32016 deletions
12
.gitignore
vendored
12
.gitignore
vendored
|
|
@ -31,15 +31,9 @@ TODO
|
||||||
# reversion kvůli historii objektů v reversion
|
# reversion kvůli historii objektů v reversion
|
||||||
**/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
|
# pro lidi, co programují v nástrojích od JetBrains
|
||||||
.idea
|
.idea
|
||||||
|
|
||||||
# Mac users
|
# dokumentace
|
||||||
.DS_Store
|
docs/_build
|
||||||
|
docs/modules
|
||||||
36
Dockerfile
36
Dockerfile
|
|
@ -1,36 +0,0 @@
|
||||||
FROM python:3.9.18-slim-bullseye
|
|
||||||
|
|
||||||
# set work directory
|
|
||||||
WORKDIR /usr/mamweb-docker
|
|
||||||
|
|
||||||
# set environment variables
|
|
||||||
ENV PIP_DISABLE_PIP_VERSION_CHECK 1
|
|
||||||
ENV PYTHONDONTWRITEBYTECODE 1
|
|
||||||
ENV PYTHONUNBUFFERED 1
|
|
||||||
|
|
||||||
# install dependencies
|
|
||||||
RUN apt-get update && apt-get install -y \
|
|
||||||
libpq-dev \
|
|
||||||
gcc \
|
|
||||||
locales \
|
|
||||||
imagemagick \
|
|
||||||
netcat \
|
|
||||||
postgresql-client
|
|
||||||
RUN pip install --upgrade pip
|
|
||||||
COPY ./requirements.txt .
|
|
||||||
COPY ./constraints.txt .
|
|
||||||
RUN pip install -r requirements.txt
|
|
||||||
|
|
||||||
# allow correct locales
|
|
||||||
RUN sed -i '/cs_CZ.UTF-8/s/^# //g' /etc/locale.gen && \
|
|
||||||
locale-gen
|
|
||||||
ENV LANG cs_CZ.UTF-8
|
|
||||||
ENV LANGUAGE en_US:en
|
|
||||||
ENV LC_ALL cs_CZ.UTF-8
|
|
||||||
|
|
||||||
# copy project
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
# create test data once db is ready
|
|
||||||
RUN chmod +x /usr/mamweb-docker/docker_entrypoint.sh
|
|
||||||
ENTRYPOINT ["/usr/mamweb-docker/docker_entrypoint.sh"]
|
|
||||||
16
_git_hooks/README.md
Normal file
16
_git_hooks/README.md
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
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
|
||||||
30
_git_hooks/pre-commit
Executable file
30
_git_hooks/pre-commit
Executable file
|
|
@ -0,0 +1,30 @@
|
||||||
|
#!/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
|
||||||
61
_git_hooks/update
Executable file
61
_git_hooks/update
Executable file
|
|
@ -0,0 +1,61 @@
|
||||||
|
#!/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,5 +1,8 @@
|
||||||
|
"""
|
||||||
|
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,5 +1,5 @@
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_text
|
||||||
|
|
||||||
|
|
||||||
class OvvpFile:
|
class OvvpFile:
|
||||||
|
|
@ -20,7 +20,7 @@ class OvvpFile:
|
||||||
yield '\t'.join(self.columns) + '\n'
|
yield '\t'.join(self.columns) + '\n'
|
||||||
# rows
|
# rows
|
||||||
for r in self.rows:
|
for r in self.rows:
|
||||||
yield '\t'.join([force_str(r[c]) for c in self.columns]) + '\n'
|
yield '\t'.join([force_text(r[c]) for c in self.columns]) + '\n'
|
||||||
|
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
return ''.join(self.to_lines())
|
return ''.join(self.to_lines())
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,10 @@
|
||||||
|
"""
|
||||||
|
Soubor sloužící jako „router“, tj. zde se definují url adresy a na co ukazují:
|
||||||
|
|
||||||
|
- ``aesop-export/mam-rocnik-<int:prvni_rok>.csv`` (seminar_export_rocnik) :class:`~aesop.views.ExportRocnikView`
|
||||||
|
- ``aesop-export/mam-sous-<str:datum_zacatku>.csv`` (seminar_export_sous) :class:`~aesop.views.ExportSousView`
|
||||||
|
- ``aesop-export/index.csv`` (seminar_export_index) :class:`~aesop.views.ExportIndexView`
|
||||||
|
"""
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
from aesop import views
|
from aesop import views
|
||||||
|
|
||||||
|
|
@ -5,16 +12,16 @@ urlpatterns = [
|
||||||
path(
|
path(
|
||||||
'aesop-export/mam-rocnik-<int:prvni_rok>.csv',
|
'aesop-export/mam-rocnik-<int:prvni_rok>.csv',
|
||||||
views.ExportRocnikView.as_view(),
|
views.ExportRocnikView.as_view(),
|
||||||
name='aesop_export_rocnik'
|
name='seminar_export_rocnik'
|
||||||
),
|
),
|
||||||
path(
|
path(
|
||||||
'aesop-export/mam-sous-<str:datum_zacatku>.csv',
|
'aesop-export/mam-sous-<str:datum_zacatku>.csv',
|
||||||
views.ExportSousView.as_view(),
|
views.ExportSousView.as_view(),
|
||||||
name='aesop_export_sous'
|
name='seminar_export_sous'
|
||||||
),
|
),
|
||||||
path(
|
path(
|
||||||
'aesop-export/index.csv',
|
'aesop-export/index.csv',
|
||||||
views.ExportIndexView.as_view(),
|
views.ExportIndexView.as_view(),
|
||||||
name='aesop_export_index'
|
name='seminar_export_index'
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_text
|
||||||
|
|
||||||
from aesop.ovvpfile import OvvpFile
|
from aesop.ovvpfile import OvvpFile
|
||||||
|
|
||||||
|
|
@ -9,7 +9,7 @@ def default_ovvpfile(event, rocnik):
|
||||||
of = OvvpFile()
|
of = OvvpFile()
|
||||||
of.headers['version'] = '1'
|
of.headers['version'] = '1'
|
||||||
of.headers['event'] = event
|
of.headers['event'] = event
|
||||||
of.headers['year'] = force_str(rocnik.prvni_rok)
|
of.headers['year'] = force_text(rocnik.prvni_rok)
|
||||||
of.headers['date'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
of.headers['date'] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
of.headers['id-scope'] = 'mam'
|
of.headers['id-scope'] = 'mam'
|
||||||
of.headers['id-generation'] = '1'
|
of.headers['id-generation'] = '1'
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,28 @@
|
||||||
|
"""
|
||||||
|
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
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from django.views import generic
|
from django.views import generic
|
||||||
from django.utils.encoding import force_str
|
from django.utils.encoding import force_text
|
||||||
|
|
||||||
from .utils import default_ovvpfile
|
from .utils import default_ovvpfile
|
||||||
from soustredeni.models import Soustredeni
|
from seminar.models import Rocnik, Soustredeni
|
||||||
from tvorba.models import Rocnik
|
|
||||||
from vysledkovky import utils
|
from vysledkovky import utils
|
||||||
from tvorba.utils import aktivniResitele
|
from seminar.utils import aktivniResitele
|
||||||
|
|
||||||
class ExportIndexView(generic.View):
|
class ExportIndexView(generic.View):
|
||||||
def get(self, request):
|
def get(self, request):
|
||||||
ls = []
|
ls = []
|
||||||
for r in Rocnik.objects.filter(exportovat = True):
|
for r in Rocnik.objects.filter(exportovat = True):
|
||||||
url = reverse('aesop_export_rocnik', kwargs={'prvni_rok': r.prvni_rok})
|
url = reverse('seminar_export_rocnik', kwargs={'prvni_rok': r.prvni_rok})
|
||||||
ls.append(url.split('/')[-1])
|
ls.append(url.split('/')[-1])
|
||||||
for s in Soustredeni.objects.filter(exportovat = True):
|
for s in Soustredeni.objects.filter(exportovat = True):
|
||||||
url = reverse('aesop_export_sous', kwargs={'datum_zacatku': s.datum_zacatku.isoformat()})
|
url = reverse('seminar_export_sous', kwargs={'datum_zacatku': s.datum_zacatku.isoformat()})
|
||||||
ls.append(url.split('/')[-1])
|
ls.append(url.split('/')[-1])
|
||||||
|
|
||||||
return HttpResponse('\n'.join(ls) + '\n', content_type='text/plain; charset=utf-8')
|
return HttpResponse('\n'.join(ls) + '\n', content_type='text/plain; charset=utf-8')
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
|
"""
|
||||||
|
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'
|
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
from django.test import TestCase, tag
|
from django.test import TestCase
|
||||||
from django.urls import reverse
|
from django.urls import reverse
|
||||||
from personalni.models import Skola
|
import seminar.models as m
|
||||||
from personalni.utils import sync_skoly
|
import seminar.views as v
|
||||||
|
from seminar.utils import sync_skoly
|
||||||
|
|
||||||
@tag('stejny-model-na-produkci')
|
|
||||||
class OrgSkolyAutocompleteTestCase(TestCase):
|
class OrgSkolyAutocompleteTestCase(TestCase):
|
||||||
@classmethod
|
@classmethod
|
||||||
def setUpClass(cls):
|
def setUpClass(cls):
|
||||||
|
|
@ -48,7 +48,7 @@ class OrgSkolyAutocompleteTestCase(TestCase):
|
||||||
"""Testuje, že pro každého orga je jeho škola ve výsledném QuerySetu"""
|
"""Testuje, že pro každého orga je jeho škola ve výsledném QuerySetu"""
|
||||||
for pfx, id in self.spravna_data:
|
for pfx, id in self.spravna_data:
|
||||||
with self.subTest(prefix=pfx, spravne_id=id):
|
with self.subTest(prefix=pfx, spravne_id=id):
|
||||||
spravna_skola = Skola.objects.get(id=id)
|
spravna_skola = m.Skola.objects.get(id=id)
|
||||||
# Zeptáme se view, co si myslí
|
# Zeptáme se view, co si myslí
|
||||||
resp = self.client.get(reverse('autocomplete_skola')+'?q='+pfx).json()
|
resp = self.client.get(reverse('autocomplete_skola')+'?q='+pfx).json()
|
||||||
ids = [int(x['id']) for x in resp['results']]
|
ids = [int(x['id']) for x in resp['results']]
|
||||||
|
|
|
||||||
16
api/urls.py
16
api/urls.py
|
|
@ -1,6 +1,18 @@
|
||||||
|
"""
|
||||||
|
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 personalni.utils import org_required
|
from seminar.utils import org_required
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
# Export škol
|
# Export škol
|
||||||
|
|
@ -17,5 +29,5 @@ urlpatterns = [
|
||||||
# Ceka na autocomplete v3
|
# Ceka na autocomplete v3
|
||||||
# path('autocomplete/organizatori/',
|
# path('autocomplete/organizatori/',
|
||||||
# org_member_required(views.OrganizatorAutocomplete.as_view()),
|
# org_member_required(views.OrganizatorAutocomplete.as_view()),
|
||||||
# name='autocomplete_organizator')
|
# name='seminar_autocomplete_organizator')
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,7 @@
|
||||||
|
"""
|
||||||
|
Soubory sloužící k deklaraci jednotlivých „views“ (nejčastěji funkce beroucí request
|
||||||
|
a vracející :func:`django.shortcuts.render` respektive nějakou response, nebo
|
||||||
|
třídy většinou rozšiřující nějakou třídu z :mod:`django.views.generic`)
|
||||||
|
"""
|
||||||
from .autocomplete import *
|
from .autocomplete import *
|
||||||
from .exports import *
|
from .exports import *
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,7 @@ from dal import autocomplete
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
|
|
||||||
from personalni.models import Skola, Resitel
|
import seminar.models as m
|
||||||
from tvorba.models import Problem
|
|
||||||
from various.models import Nastaveni
|
|
||||||
from .helpers import LoginRequiredAjaxMixin
|
from .helpers import LoginRequiredAjaxMixin
|
||||||
|
|
||||||
# TODO filosofie - zkratky, jak v databázi, tak ve vyhledávání (SPŠE, GASOŠ, Kpt., soukr)
|
# TODO filosofie - zkratky, jak v databázi, tak ve vyhledávání (SPŠE, GASOŠ, Kpt., soukr)
|
||||||
|
|
@ -15,7 +13,7 @@ class SkolaAutocomplete(autocomplete.Select2QuerySetView):
|
||||||
""" View k :mod:`dal.autocomplete` pro vyhledávání škol hlavně při registraci. """
|
""" View k :mod:`dal.autocomplete` pro vyhledávání škol hlavně při registraci. """
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
# Don't forget to filter out results depending on the visitor !
|
# Don't forget to filter out results depending on the visitor !
|
||||||
qs = Skola.objects.all()
|
qs = m.Skola.objects.all()
|
||||||
if self.q:
|
if self.q:
|
||||||
words = self.q.split(' ') #TODO re split podle bileho znaku
|
words = self.q.split(' ') #TODO re split podle bileho znaku
|
||||||
partq = Q()
|
partq = Q()
|
||||||
|
|
@ -33,7 +31,7 @@ class SkolaAutocomplete(autocomplete.Select2QuerySetView):
|
||||||
class ResitelAutocomplete(LoginRequiredAjaxMixin,autocomplete.Select2QuerySetView):
|
class ResitelAutocomplete(LoginRequiredAjaxMixin,autocomplete.Select2QuerySetView):
|
||||||
""" View k :mod:`dal.autocomplete` pro vyhledávání řešitelů především v odevzdávátku. """
|
""" View k :mod:`dal.autocomplete` pro vyhledávání řešitelů především v odevzdávátku. """
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
qs = Resitel.objects.all()
|
qs = m.Resitel.objects.all()
|
||||||
if self.q:
|
if self.q:
|
||||||
parts = self.q.split()
|
parts = self.q.split()
|
||||||
query = Q()
|
query = Q()
|
||||||
|
|
@ -53,8 +51,8 @@ class PublicResitelAutocomplete(LoginRequiredAjaxMixin, autocomplete.Select2Quer
|
||||||
především v odevzdávátku.
|
především v odevzdávátku.
|
||||||
"""
|
"""
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
letos = Nastaveni.get_solo().aktualni_rocnik
|
letos = m.Nastaveni.get_solo().aktualni_rocnik
|
||||||
qs = Resitel.objects.filter(
|
qs = m.Resitel.objects.filter(
|
||||||
rok_maturity__gte=letos.druhy_rok()
|
rok_maturity__gte=letos.druhy_rok()
|
||||||
).filter(
|
).filter(
|
||||||
prezdivka_resitele__isnull=False
|
prezdivka_resitele__isnull=False
|
||||||
|
|
@ -72,7 +70,7 @@ class PublicResitelAutocomplete(LoginRequiredAjaxMixin, autocomplete.Select2Quer
|
||||||
class OdevzdatelnyProblemAutocomplete(autocomplete.Select2QuerySetView):
|
class OdevzdatelnyProblemAutocomplete(autocomplete.Select2QuerySetView):
|
||||||
""" View k :mod:`dal.autocomplete` pro vyhledávání problémů především v odevzdávátku. """
|
""" View k :mod:`dal.autocomplete` pro vyhledávání problémů především v odevzdávátku. """
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
qs = Problem.objects.filter(stav=Problem.STAV_ZADANY)
|
qs = m.Problem.objects.filter(stav=m.Problem.STAV_ZADANY)
|
||||||
if self.q:
|
if self.q:
|
||||||
qs = qs.filter(
|
qs = qs.filter(
|
||||||
Q(nazev__icontains=self.q))
|
Q(nazev__icontains=self.q))
|
||||||
|
|
@ -89,12 +87,12 @@ class ProblemAutocomplete(autocomplete.Select2QuerySetView):
|
||||||
""" View k :mod:`dal.autocomplete` pro vyhledávání problémů především v odevzdávátku. """
|
""" View k :mod:`dal.autocomplete` pro vyhledávání problémů především v odevzdávátku. """
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
# FIXME i starší úlohy
|
# FIXME i starší úlohy
|
||||||
nastaveni = get_object_or_404(Nastaveni)
|
nastaveni = get_object_or_404(m.Nastaveni)
|
||||||
rocnik = nastaveni.aktualni_rocnik
|
rocnik = nastaveni.aktualni_rocnik
|
||||||
temaQ = Q(Tema___rocnik = rocnik)
|
temaQ = Q(Tema___rocnik = rocnik)
|
||||||
ulohaQ = Q(Uloha___cislo_zadani__rocnik=rocnik)
|
ulohaQ = Q(Uloha___cislo_zadani__rocnik=rocnik)
|
||||||
clanekQ = Q(Clanek___cislo__rocnik=rocnik)
|
clanekQ = Q(Clanek___cislo__rocnik=rocnik)
|
||||||
qs = Problem.objects.filter(temaQ | ulohaQ | clanekQ).order_by("-stav", "nazev")
|
qs = m.Problem.objects.filter(temaQ | ulohaQ | clanekQ).order_by("-stav", "nazev")
|
||||||
if self.q:
|
if self.q:
|
||||||
qs = qs.filter(
|
qs = qs.filter(
|
||||||
Q(nazev__icontains=self.q))
|
Q(nazev__icontains=self.q))
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import personalni.models as m
|
import seminar.models as m
|
||||||
from django.core import serializers as ser
|
from django.core import serializers as ser
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
def exportSkolView(request):
|
def exportSkolView(request):
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
655
data/groups.json
655
data/groups.json
|
|
@ -1,655 +0,0 @@
|
||||||
[
|
|
||||||
{
|
|
||||||
"fields": {
|
|
||||||
"name": "org",
|
|
||||||
"permissions": [
|
|
||||||
[
|
|
||||||
"org",
|
|
||||||
"auth",
|
|
||||||
"user"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_flatpage",
|
|
||||||
"flatpages",
|
|
||||||
"flatpage"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_flatpage",
|
|
||||||
"flatpages",
|
|
||||||
"flatpage"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_flatpage",
|
|
||||||
"flatpages",
|
|
||||||
"flatpage"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_flatpage",
|
|
||||||
"flatpages",
|
|
||||||
"flatpage"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_galerie",
|
|
||||||
"galerie",
|
|
||||||
"galerie"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_galerie",
|
|
||||||
"galerie",
|
|
||||||
"galerie"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_galerie",
|
|
||||||
"galerie",
|
|
||||||
"galerie"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_galerie",
|
|
||||||
"galerie",
|
|
||||||
"galerie"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_obrazek",
|
|
||||||
"galerie",
|
|
||||||
"obrazek"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_obrazek",
|
|
||||||
"galerie",
|
|
||||||
"obrazek"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_obrazek",
|
|
||||||
"galerie",
|
|
||||||
"obrazek"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_obrazek",
|
|
||||||
"galerie",
|
|
||||||
"obrazek"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_fotkaheader",
|
|
||||||
"header_fotky",
|
|
||||||
"fotkaheader"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_fotkaheader",
|
|
||||||
"header_fotky",
|
|
||||||
"fotkaheader"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_fotkaheader",
|
|
||||||
"header_fotky",
|
|
||||||
"fotkaheader"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_fotkaurlvazba",
|
|
||||||
"header_fotky",
|
|
||||||
"fotkaurlvazba"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_fotkaurlvazba",
|
|
||||||
"header_fotky",
|
|
||||||
"fotkaurlvazba"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_fotkaurlvazba",
|
|
||||||
"header_fotky",
|
|
||||||
"fotkaurlvazba"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_komentar",
|
|
||||||
"korektury",
|
|
||||||
"komentar"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_komentar",
|
|
||||||
"korektury",
|
|
||||||
"komentar"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_komentar",
|
|
||||||
"korektury",
|
|
||||||
"komentar"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_komentar",
|
|
||||||
"korektury",
|
|
||||||
"komentar"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_korekturovanepdf",
|
|
||||||
"korektury",
|
|
||||||
"korekturovanepdf"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_korekturovanepdf",
|
|
||||||
"korektury",
|
|
||||||
"korekturovanepdf"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_korekturovanepdf",
|
|
||||||
"korektury",
|
|
||||||
"korekturovanepdf"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_korekturovanepdf",
|
|
||||||
"korektury",
|
|
||||||
"korekturovanepdf"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_oprava",
|
|
||||||
"korektury",
|
|
||||||
"oprava"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_oprava",
|
|
||||||
"korektury",
|
|
||||||
"oprava"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_oprava",
|
|
||||||
"korektury",
|
|
||||||
"oprava"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_oprava",
|
|
||||||
"korektury",
|
|
||||||
"oprava"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_novinky",
|
|
||||||
"novinky",
|
|
||||||
"novinky"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_novinky",
|
|
||||||
"novinky",
|
|
||||||
"novinky"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_novinky",
|
|
||||||
"novinky",
|
|
||||||
"novinky"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_novinky",
|
|
||||||
"novinky",
|
|
||||||
"novinky"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_organizator",
|
|
||||||
"personalni",
|
|
||||||
"organizator"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_organizator",
|
|
||||||
"personalni",
|
|
||||||
"organizator"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_osoba",
|
|
||||||
"personalni",
|
|
||||||
"osoba"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_osoba",
|
|
||||||
"personalni",
|
|
||||||
"osoba"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_prijemce",
|
|
||||||
"personalni",
|
|
||||||
"prijemce"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_prijemce",
|
|
||||||
"personalni",
|
|
||||||
"prijemce"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_prijemce",
|
|
||||||
"personalni",
|
|
||||||
"prijemce"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_prijemce",
|
|
||||||
"personalni",
|
|
||||||
"prijemce"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_resitel",
|
|
||||||
"personalni",
|
|
||||||
"resitel"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_resitel",
|
|
||||||
"personalni",
|
|
||||||
"resitel"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_skola",
|
|
||||||
"personalni",
|
|
||||||
"skola"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_skola",
|
|
||||||
"personalni",
|
|
||||||
"skola"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_skola",
|
|
||||||
"personalni",
|
|
||||||
"skola"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_skola",
|
|
||||||
"personalni",
|
|
||||||
"skola"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_hlasovani",
|
|
||||||
"prednasky",
|
|
||||||
"hlasovani"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_hlasovanioznalostech",
|
|
||||||
"prednasky",
|
|
||||||
"hlasovanioznalostech"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_prednaska",
|
|
||||||
"prednasky",
|
|
||||||
"prednaska"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_prednaska",
|
|
||||||
"prednasky",
|
|
||||||
"prednaska"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_prednaska",
|
|
||||||
"prednasky",
|
|
||||||
"prednaska"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_prednaska",
|
|
||||||
"prednasky",
|
|
||||||
"prednaska"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_seznam",
|
|
||||||
"prednasky",
|
|
||||||
"seznam"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_seznam",
|
|
||||||
"prednasky",
|
|
||||||
"seznam"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_seznam",
|
|
||||||
"prednasky",
|
|
||||||
"seznam"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_seznam",
|
|
||||||
"prednasky",
|
|
||||||
"seznam"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_znalost",
|
|
||||||
"prednasky",
|
|
||||||
"znalost"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_znalost",
|
|
||||||
"prednasky",
|
|
||||||
"znalost"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_znalost",
|
|
||||||
"prednasky",
|
|
||||||
"znalost"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_znalost",
|
|
||||||
"prednasky",
|
|
||||||
"znalost"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_konfera",
|
|
||||||
"soustredeni",
|
|
||||||
"konfera"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_konfera",
|
|
||||||
"soustredeni",
|
|
||||||
"konfera"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_konfera",
|
|
||||||
"soustredeni",
|
|
||||||
"konfera"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_konfera",
|
|
||||||
"soustredeni",
|
|
||||||
"konfera"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_konfery_ucastnici",
|
|
||||||
"soustredeni",
|
|
||||||
"konfery_ucastnici"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_konfery_ucastnici",
|
|
||||||
"soustredeni",
|
|
||||||
"konfery_ucastnici"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_konfery_ucastnici",
|
|
||||||
"soustredeni",
|
|
||||||
"konfery_ucastnici"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_konfery_ucastnici",
|
|
||||||
"soustredeni",
|
|
||||||
"konfery_ucastnici"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_soustredeni",
|
|
||||||
"soustredeni",
|
|
||||||
"soustredeni"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_soustredeni",
|
|
||||||
"soustredeni",
|
|
||||||
"soustredeni"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_soustredeni",
|
|
||||||
"soustredeni",
|
|
||||||
"soustredeni"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_soustredeni",
|
|
||||||
"soustredeni",
|
|
||||||
"soustredeni"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_soustredeni_organizatori",
|
|
||||||
"soustredeni",
|
|
||||||
"soustredeni_organizatori"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_soustredeni_organizatori",
|
|
||||||
"soustredeni",
|
|
||||||
"soustredeni_organizatori"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_soustredeni_organizatori",
|
|
||||||
"soustredeni",
|
|
||||||
"soustredeni_organizatori"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_soustredeni_organizatori",
|
|
||||||
"soustredeni",
|
|
||||||
"soustredeni_organizatori"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_soustredeni_ucastnici",
|
|
||||||
"soustredeni",
|
|
||||||
"soustredeni_ucastnici"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_soustredeni_ucastnici",
|
|
||||||
"soustredeni",
|
|
||||||
"soustredeni_ucastnici"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_soustredeni_ucastnici",
|
|
||||||
"soustredeni",
|
|
||||||
"soustredeni_ucastnici"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_soustredeni_ucastnici",
|
|
||||||
"soustredeni",
|
|
||||||
"soustredeni_ucastnici"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_tag",
|
|
||||||
"taggit",
|
|
||||||
"tag"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_tag",
|
|
||||||
"taggit",
|
|
||||||
"tag"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_tag",
|
|
||||||
"taggit",
|
|
||||||
"tag"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_tag",
|
|
||||||
"taggit",
|
|
||||||
"tag"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_taggeditem",
|
|
||||||
"taggit",
|
|
||||||
"taggeditem"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_taggeditem",
|
|
||||||
"taggit",
|
|
||||||
"taggeditem"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_taggeditem",
|
|
||||||
"taggit",
|
|
||||||
"taggeditem"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_taggeditem",
|
|
||||||
"taggit",
|
|
||||||
"taggeditem"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_cislo",
|
|
||||||
"tvorba",
|
|
||||||
"cislo"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_cislo",
|
|
||||||
"tvorba",
|
|
||||||
"cislo"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_cislo",
|
|
||||||
"tvorba",
|
|
||||||
"cislo"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_cislo",
|
|
||||||
"tvorba",
|
|
||||||
"cislo"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_clanek",
|
|
||||||
"tvorba",
|
|
||||||
"clanek"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_clanek",
|
|
||||||
"tvorba",
|
|
||||||
"clanek"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_clanek",
|
|
||||||
"tvorba",
|
|
||||||
"clanek"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_clanek",
|
|
||||||
"tvorba",
|
|
||||||
"clanek"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_deadline",
|
|
||||||
"tvorba",
|
|
||||||
"deadline"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_deadline",
|
|
||||||
"tvorba",
|
|
||||||
"deadline"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_deadline",
|
|
||||||
"tvorba",
|
|
||||||
"deadline"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_pohadka",
|
|
||||||
"tvorba",
|
|
||||||
"pohadka"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_pohadka",
|
|
||||||
"tvorba",
|
|
||||||
"pohadka"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_pohadka",
|
|
||||||
"tvorba",
|
|
||||||
"pohadka"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_pohadka",
|
|
||||||
"tvorba",
|
|
||||||
"pohadka"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_problem",
|
|
||||||
"tvorba",
|
|
||||||
"problem"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_problem",
|
|
||||||
"tvorba",
|
|
||||||
"problem"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_problem",
|
|
||||||
"tvorba",
|
|
||||||
"problem"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_problem",
|
|
||||||
"tvorba",
|
|
||||||
"problem"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_rocnik",
|
|
||||||
"tvorba",
|
|
||||||
"rocnik"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_rocnik",
|
|
||||||
"tvorba",
|
|
||||||
"rocnik"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_rocnik",
|
|
||||||
"tvorba",
|
|
||||||
"rocnik"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_rocnik",
|
|
||||||
"tvorba",
|
|
||||||
"rocnik"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_tema",
|
|
||||||
"tvorba",
|
|
||||||
"tema"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_tema",
|
|
||||||
"tvorba",
|
|
||||||
"tema"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_tema",
|
|
||||||
"tvorba",
|
|
||||||
"tema"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_tema",
|
|
||||||
"tvorba",
|
|
||||||
"tema"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_uloha",
|
|
||||||
"tvorba",
|
|
||||||
"uloha"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_uloha",
|
|
||||||
"tvorba",
|
|
||||||
"uloha"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_uloha",
|
|
||||||
"tvorba",
|
|
||||||
"uloha"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_uloha",
|
|
||||||
"tvorba",
|
|
||||||
"uloha"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"add_nastaveni",
|
|
||||||
"various",
|
|
||||||
"nastaveni"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"change_nastaveni",
|
|
||||||
"various",
|
|
||||||
"nastaveni"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"delete_nastaveni",
|
|
||||||
"various",
|
|
||||||
"nastaveni"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"view_nastaveni",
|
|
||||||
"various",
|
|
||||||
"nastaveni"
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"model": "auth.group",
|
|
||||||
"pk": 1
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"fields": {
|
|
||||||
"name": "resitel",
|
|
||||||
"permissions": [
|
|
||||||
[
|
|
||||||
"resitel",
|
|
||||||
"auth",
|
|
||||||
"user"
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"model": "auth.group",
|
|
||||||
"pk": 2
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
@ -73,7 +73,7 @@
|
||||||
"sort_order": 3,
|
"sort_order": 3,
|
||||||
"title": "Aktuální<br/> ročník",
|
"title": "Aktuální<br/> ročník",
|
||||||
"tree": 1,
|
"tree": 1,
|
||||||
"url": "tvorba_aktualni_zadani",
|
"url": "seminar_aktualni_zadani",
|
||||||
"urlaspattern": true
|
"urlaspattern": true
|
||||||
},
|
},
|
||||||
"model": "sitetree.treeitem",
|
"model": "sitetree.treeitem",
|
||||||
|
|
@ -121,7 +121,7 @@
|
||||||
"sort_order": 5,
|
"sort_order": 5,
|
||||||
"title": "Archiv",
|
"title": "Archiv",
|
||||||
"tree": 1,
|
"tree": 1,
|
||||||
"url": "tvorba_archiv_rocniky",
|
"url": "seminar_archiv_rocniky",
|
||||||
"urlaspattern": true
|
"urlaspattern": true
|
||||||
},
|
},
|
||||||
"model": "sitetree.treeitem",
|
"model": "sitetree.treeitem",
|
||||||
|
|
@ -289,7 +289,7 @@
|
||||||
"sort_order": 43,
|
"sort_order": 43,
|
||||||
"title": "Výsledková listina",
|
"title": "Výsledková listina",
|
||||||
"tree": 1,
|
"tree": 1,
|
||||||
"url": "tvorba_aktualni_vysledky",
|
"url": "seminar_aktualni_vysledky",
|
||||||
"urlaspattern": true
|
"urlaspattern": true
|
||||||
},
|
},
|
||||||
"model": "sitetree.treeitem",
|
"model": "sitetree.treeitem",
|
||||||
|
|
@ -361,7 +361,7 @@
|
||||||
"sort_order": 20,
|
"sort_order": 20,
|
||||||
"title": "Proběhlo",
|
"title": "Proběhlo",
|
||||||
"tree": 1,
|
"tree": 1,
|
||||||
"url": "soustredeni_seznam",
|
"url": "seminar_seznam_soustredeni",
|
||||||
"urlaspattern": true
|
"urlaspattern": true
|
||||||
},
|
},
|
||||||
"model": "sitetree.treeitem",
|
"model": "sitetree.treeitem",
|
||||||
|
|
@ -409,7 +409,7 @@
|
||||||
"sort_order": 23,
|
"sort_order": 23,
|
||||||
"title": "Osobní údaje",
|
"title": "Osobní údaje",
|
||||||
"tree": 1,
|
"tree": 1,
|
||||||
"url": "personalni_resitel_edit",
|
"url": "seminar_resitel_edit",
|
||||||
"urlaspattern": true
|
"urlaspattern": true
|
||||||
},
|
},
|
||||||
"model": "sitetree.treeitem",
|
"model": "sitetree.treeitem",
|
||||||
|
|
@ -439,7 +439,7 @@
|
||||||
"sort_order": 36,
|
"sort_order": 36,
|
||||||
"title": "Nahrát řešení",
|
"title": "Nahrát řešení",
|
||||||
"tree": 1,
|
"tree": 1,
|
||||||
"url": "odevzdavatko_nahraj_reseni",
|
"url": "seminar_nahraj_reseni",
|
||||||
"urlaspattern": true
|
"urlaspattern": true
|
||||||
},
|
},
|
||||||
"model": "sitetree.treeitem",
|
"model": "sitetree.treeitem",
|
||||||
|
|
@ -463,7 +463,7 @@
|
||||||
"sort_order": 35,
|
"sort_order": 35,
|
||||||
"title": "Témata",
|
"title": "Témata",
|
||||||
"tree": 1,
|
"tree": 1,
|
||||||
"url": "tvorba_archiv_temata",
|
"url": "seminar_archiv_temata",
|
||||||
"urlaspattern": true
|
"urlaspattern": true
|
||||||
},
|
},
|
||||||
"model": "sitetree.treeitem",
|
"model": "sitetree.treeitem",
|
||||||
|
|
@ -589,7 +589,7 @@
|
||||||
"sort_order": 15,
|
"sort_order": 15,
|
||||||
"title": "Aktuální číslo",
|
"title": "Aktuální číslo",
|
||||||
"tree": 1,
|
"tree": 1,
|
||||||
"url": "tvorba_aktualni_zadani",
|
"url": "seminar_aktualni_zadani",
|
||||||
"urlaspattern": true
|
"urlaspattern": true
|
||||||
},
|
},
|
||||||
"model": "sitetree.treeitem",
|
"model": "sitetree.treeitem",
|
||||||
|
|
@ -613,7 +613,7 @@
|
||||||
"sort_order": 24,
|
"sort_order": 24,
|
||||||
"title": "Čísla",
|
"title": "Čísla",
|
||||||
"tree": 1,
|
"tree": 1,
|
||||||
"url": "tvorba_archiv_rocniky",
|
"url": "seminar_archiv_rocniky",
|
||||||
"urlaspattern": true
|
"urlaspattern": true
|
||||||
},
|
},
|
||||||
"model": "sitetree.treeitem",
|
"model": "sitetree.treeitem",
|
||||||
|
|
@ -721,7 +721,7 @@
|
||||||
"sort_order": 36,
|
"sort_order": 36,
|
||||||
"title": "Vložit řešení",
|
"title": "Vložit řešení",
|
||||||
"tree": 1,
|
"tree": 1,
|
||||||
"url": "odevzdavatko_vloz_reseni",
|
"url": "seminar_vloz_reseni",
|
||||||
"urlaspattern": true
|
"urlaspattern": true
|
||||||
},
|
},
|
||||||
"model": "sitetree.treeitem",
|
"model": "sitetree.treeitem",
|
||||||
|
|
@ -804,7 +804,7 @@
|
||||||
"sort_order": 37,
|
"sort_order": 37,
|
||||||
"title": "Moje řešení",
|
"title": "Moje řešení",
|
||||||
"tree": 1,
|
"tree": 1,
|
||||||
"url": "odevzdavatko_resitel_odevzdana_reseni",
|
"url": "seminar_resitel_odevzdana_reseni",
|
||||||
"urlaspattern": true
|
"urlaspattern": true
|
||||||
},
|
},
|
||||||
"model": "sitetree.treeitem",
|
"model": "sitetree.treeitem",
|
||||||
|
|
@ -828,7 +828,7 @@
|
||||||
"sort_order": 33,
|
"sort_order": 33,
|
||||||
"title": "Aktuální ročník",
|
"title": "Aktuální ročník",
|
||||||
"tree": 1,
|
"tree": 1,
|
||||||
"url": "tvorba_aktualni_rocnik",
|
"url": "seminar_aktualni_rocnik",
|
||||||
"urlaspattern": true
|
"urlaspattern": true
|
||||||
},
|
},
|
||||||
"model": "sitetree.treeitem",
|
"model": "sitetree.treeitem",
|
||||||
|
|
@ -900,7 +900,7 @@
|
||||||
"sort_order": 46,
|
"sort_order": 46,
|
||||||
"title": "Ročník {{rocnik.rocnik}}",
|
"title": "Ročník {{rocnik.rocnik}}",
|
||||||
"tree": 1,
|
"tree": 1,
|
||||||
"url": "tvorba_rocnik rocnik.rocnik",
|
"url": "seminar_rocnik rocnik.rocnik",
|
||||||
"urlaspattern": true
|
"urlaspattern": true
|
||||||
},
|
},
|
||||||
"model": "sitetree.treeitem",
|
"model": "sitetree.treeitem",
|
||||||
|
|
@ -924,7 +924,7 @@
|
||||||
"sort_order": 47,
|
"sort_order": 47,
|
||||||
"title": "Číslo {{ cislo.rocnik.rocnik }}.{{ cislo.poradi }}",
|
"title": "Číslo {{ cislo.rocnik.rocnik }}.{{ cislo.poradi }}",
|
||||||
"tree": 1,
|
"tree": 1,
|
||||||
"url": "tvorba_cislo cislo.rocnik.rocnik cislo.poradi",
|
"url": "seminar_cislo cislo.rocnik.rocnik cislo.poradi",
|
||||||
"urlaspattern": true
|
"urlaspattern": true
|
||||||
},
|
},
|
||||||
"model": "sitetree.treeitem",
|
"model": "sitetree.treeitem",
|
||||||
|
|
@ -1007,18 +1007,7 @@
|
||||||
"access_guest": false,
|
"access_guest": false,
|
||||||
"access_loggedin": false,
|
"access_loggedin": false,
|
||||||
"access_perm_type": 1,
|
"access_perm_type": 1,
|
||||||
"access_permissions": [
|
"access_permissions": [],
|
||||||
[
|
|
||||||
"org",
|
|
||||||
"auth",
|
|
||||||
"user"
|
|
||||||
],
|
|
||||||
[
|
|
||||||
"resitel",
|
|
||||||
"auth",
|
|
||||||
"user"
|
|
||||||
]
|
|
||||||
],
|
|
||||||
"access_restricted": true,
|
"access_restricted": true,
|
||||||
"alias": null,
|
"alias": null,
|
||||||
"description": "",
|
"description": "",
|
||||||
|
|
@ -1061,7 +1050,7 @@
|
||||||
"sort_order": 52,
|
"sort_order": 52,
|
||||||
"title": "Nahrát řešení k nadproblému {{nadproblem_id}}",
|
"title": "Nahrát řešení k nadproblému {{nadproblem_id}}",
|
||||||
"tree": 1,
|
"tree": 1,
|
||||||
"url": "odevzdavatko_nahraj_reseni nadproblem_id",
|
"url": "seminar_nahraj_reseni nadproblem_id",
|
||||||
"urlaspattern": true
|
"urlaspattern": true
|
||||||
},
|
},
|
||||||
"model": "sitetree.treeitem",
|
"model": "sitetree.treeitem",
|
||||||
|
|
@ -1090,29 +1079,5 @@
|
||||||
},
|
},
|
||||||
"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": false,
|
|
||||||
"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": "soustredeni_abstrakty soustredeni.id",
|
|
||||||
"urlaspattern": true
|
|
||||||
},
|
|
||||||
"model": "sitetree.treeitem",
|
|
||||||
"pk": 54
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
||||||
622
deploy_v2/admin_org_prava.json
Normal file
622
deploy_v2/admin_org_prava.json
Normal file
|
|
@ -0,0 +1,622 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"codename": "org",
|
||||||
|
"ct_app_label": "auth",
|
||||||
|
"ct_model": "user"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_flatpage",
|
||||||
|
"ct_app_label": "flatpages",
|
||||||
|
"ct_model": "flatpage"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_flatpage",
|
||||||
|
"ct_app_label": "flatpages",
|
||||||
|
"ct_model": "flatpage"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_flatpage",
|
||||||
|
"ct_app_label": "flatpages",
|
||||||
|
"ct_model": "flatpage"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_flatpage",
|
||||||
|
"ct_app_label": "flatpages",
|
||||||
|
"ct_model": "flatpage"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_galerie",
|
||||||
|
"ct_app_label": "galerie",
|
||||||
|
"ct_model": "galerie"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_galerie",
|
||||||
|
"ct_app_label": "galerie",
|
||||||
|
"ct_model": "galerie"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_galerie",
|
||||||
|
"ct_app_label": "galerie",
|
||||||
|
"ct_model": "galerie"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_galerie",
|
||||||
|
"ct_app_label": "galerie",
|
||||||
|
"ct_model": "galerie"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_obrazek",
|
||||||
|
"ct_app_label": "galerie",
|
||||||
|
"ct_model": "obrazek"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_obrazek",
|
||||||
|
"ct_app_label": "galerie",
|
||||||
|
"ct_model": "obrazek"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_obrazek",
|
||||||
|
"ct_app_label": "galerie",
|
||||||
|
"ct_model": "obrazek"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_obrazek",
|
||||||
|
"ct_app_label": "galerie",
|
||||||
|
"ct_model": "obrazek"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_fotkaheader",
|
||||||
|
"ct_app_label": "header_fotky",
|
||||||
|
"ct_model": "fotkaheader"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_fotkaheader",
|
||||||
|
"ct_app_label": "header_fotky",
|
||||||
|
"ct_model": "fotkaheader"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_fotkaheader",
|
||||||
|
"ct_app_label": "header_fotky",
|
||||||
|
"ct_model": "fotkaheader"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_fotkaurlvazba",
|
||||||
|
"ct_app_label": "header_fotky",
|
||||||
|
"ct_model": "fotkaurlvazba"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_fotkaurlvazba",
|
||||||
|
"ct_app_label": "header_fotky",
|
||||||
|
"ct_model": "fotkaurlvazba"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_fotkaurlvazba",
|
||||||
|
"ct_app_label": "header_fotky",
|
||||||
|
"ct_model": "fotkaurlvazba"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_komentar",
|
||||||
|
"ct_app_label": "korektury",
|
||||||
|
"ct_model": "komentar"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_komentar",
|
||||||
|
"ct_app_label": "korektury",
|
||||||
|
"ct_model": "komentar"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_komentar",
|
||||||
|
"ct_app_label": "korektury",
|
||||||
|
"ct_model": "komentar"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_komentar",
|
||||||
|
"ct_app_label": "korektury",
|
||||||
|
"ct_model": "komentar"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_korekturovanepdf",
|
||||||
|
"ct_app_label": "korektury",
|
||||||
|
"ct_model": "korekturovanepdf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_korekturovanepdf",
|
||||||
|
"ct_app_label": "korektury",
|
||||||
|
"ct_model": "korekturovanepdf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_korekturovanepdf",
|
||||||
|
"ct_app_label": "korektury",
|
||||||
|
"ct_model": "korekturovanepdf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_korekturovanepdf",
|
||||||
|
"ct_app_label": "korektury",
|
||||||
|
"ct_model": "korekturovanepdf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_oprava",
|
||||||
|
"ct_app_label": "korektury",
|
||||||
|
"ct_model": "oprava"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_oprava",
|
||||||
|
"ct_app_label": "korektury",
|
||||||
|
"ct_model": "oprava"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_oprava",
|
||||||
|
"ct_app_label": "korektury",
|
||||||
|
"ct_model": "oprava"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_oprava",
|
||||||
|
"ct_app_label": "korektury",
|
||||||
|
"ct_model": "oprava"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_hlasovani",
|
||||||
|
"ct_app_label": "prednasky",
|
||||||
|
"ct_model": "hlasovani"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_hlasovani",
|
||||||
|
"ct_app_label": "prednasky",
|
||||||
|
"ct_model": "hlasovani"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_hlasovani",
|
||||||
|
"ct_app_label": "prednasky",
|
||||||
|
"ct_model": "hlasovani"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_hlasovani",
|
||||||
|
"ct_app_label": "prednasky",
|
||||||
|
"ct_model": "hlasovani"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_prednaska",
|
||||||
|
"ct_app_label": "prednasky",
|
||||||
|
"ct_model": "prednaska"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_prednaska",
|
||||||
|
"ct_app_label": "prednasky",
|
||||||
|
"ct_model": "prednaska"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_prednaska",
|
||||||
|
"ct_app_label": "prednasky",
|
||||||
|
"ct_model": "prednaska"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_prednaska",
|
||||||
|
"ct_app_label": "prednasky",
|
||||||
|
"ct_model": "prednaska"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_seznam",
|
||||||
|
"ct_app_label": "prednasky",
|
||||||
|
"ct_model": "seznam"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_seznam",
|
||||||
|
"ct_app_label": "prednasky",
|
||||||
|
"ct_model": "seznam"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_seznam",
|
||||||
|
"ct_app_label": "prednasky",
|
||||||
|
"ct_model": "seznam"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_seznam",
|
||||||
|
"ct_app_label": "prednasky",
|
||||||
|
"ct_model": "seznam"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_cislo",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "cislo"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_cislo",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "cislo"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_cislo",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "cislo"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_cislo",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "cislo"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_clanek",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "clanek"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_clanek",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "clanek"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_clanek",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "clanek"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_clanek",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "clanek"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_deadline",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "deadline"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_deadline",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "deadline"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_deadline",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "deadline"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_konfera",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "konfera"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_konfera",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "konfera"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_konfera",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "konfera"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_konfera",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "konfera"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_konfery_ucastnici",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "konfery_ucastnici"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_konfery_ucastnici",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "konfery_ucastnici"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_konfery_ucastnici",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "konfery_ucastnici"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_konfery_ucastnici",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "konfery_ucastnici"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_nastaveni",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "nastaveni"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_nastaveni",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "nastaveni"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_nastaveni",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "nastaveni"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_nastaveni",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "nastaveni"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_novinky",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "novinky"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_novinky",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "novinky"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_novinky",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "novinky"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_novinky",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "novinky"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_organizator",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "organizator"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_organizator",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "organizator"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_osoba",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "osoba"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_osoba",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "osoba"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_pohadka",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "pohadka"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_pohadka",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "pohadka"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_pohadka",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "pohadka"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_pohadka",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "pohadka"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_prijemce",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "prijemce"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_prijemce",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "prijemce"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_prijemce",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "prijemce"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_prijemce",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "prijemce"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_problem",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "problem"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_problem",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "problem"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_problem",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "problem"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_problem",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "problem"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_resitel",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "resitel"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_resitel",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "resitel"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_rocnik",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "rocnik"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_rocnik",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "rocnik"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_rocnik",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "rocnik"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_rocnik",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "rocnik"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_skola",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "skola"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_skola",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "skola"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_skola",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "skola"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_skola",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "skola"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_soustredeni",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "soustredeni"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_soustredeni",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "soustredeni"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_soustredeni",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "soustredeni"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_soustredeni",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "soustredeni"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_soustredeni_organizatori",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "soustredeni_organizatori"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_soustredeni_organizatori",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "soustredeni_organizatori"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_soustredeni_organizatori",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "soustredeni_organizatori"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_soustredeni_organizatori",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "soustredeni_organizatori"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_soustredeni_ucastnici",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "soustredeni_ucastnici"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_soustredeni_ucastnici",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "soustredeni_ucastnici"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_soustredeni_ucastnici",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "soustredeni_ucastnici"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_soustredeni_ucastnici",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "soustredeni_ucastnici"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_tema",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "tema"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_tema",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "tema"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_tema",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "tema"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_tema",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "tema"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_uloha",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "uloha"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_uloha",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "uloha"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_uloha",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "uloha"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_uloha",
|
||||||
|
"ct_app_label": "seminar",
|
||||||
|
"ct_model": "uloha"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_tag",
|
||||||
|
"ct_app_label": "taggit",
|
||||||
|
"ct_model": "tag"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_tag",
|
||||||
|
"ct_app_label": "taggit",
|
||||||
|
"ct_model": "tag"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_tag",
|
||||||
|
"ct_app_label": "taggit",
|
||||||
|
"ct_model": "tag"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_tag",
|
||||||
|
"ct_app_label": "taggit",
|
||||||
|
"ct_model": "tag"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "add_taggeditem",
|
||||||
|
"ct_app_label": "taggit",
|
||||||
|
"ct_model": "taggeditem"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "change_taggeditem",
|
||||||
|
"ct_app_label": "taggit",
|
||||||
|
"ct_model": "taggeditem"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "delete_taggeditem",
|
||||||
|
"ct_app_label": "taggit",
|
||||||
|
"ct_model": "taggeditem"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "view_taggeditem",
|
||||||
|
"ct_app_label": "taggit",
|
||||||
|
"ct_model": "taggeditem"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
@ -13,6 +13,7 @@ make install_venv
|
||||||
make install
|
make install
|
||||||
deploy_v2/pre_migration.py
|
deploy_v2/pre_migration.py
|
||||||
make deploy_test
|
make deploy_test
|
||||||
|
./manage.py load_org_permissions admin_org_prava.json
|
||||||
./manage.py loaddata data/*
|
./manage.py loaddata data/*
|
||||||
systemctl --user start mamweb-test.service
|
systemctl --user start mamweb-test.service
|
||||||
./manage.py generate_thumbnails
|
./manage.py generate_thumbnails
|
||||||
|
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
|
|
||||||
services:
|
|
||||||
web:
|
|
||||||
build: .
|
|
||||||
command: python manage.py runserver 0.0.0.0:8000
|
|
||||||
volumes:
|
|
||||||
- .:/usr/mamweb-docker
|
|
||||||
ports:
|
|
||||||
- 8000:8000
|
|
||||||
depends_on:
|
|
||||||
- db
|
|
||||||
|
|
||||||
db:
|
|
||||||
image: postgres:13-bullseye
|
|
||||||
volumes:
|
|
||||||
- postgres_data:/var/lib/postgresql/data/
|
|
||||||
environment:
|
|
||||||
- POSTGRES_USER=mam-web
|
|
||||||
- POSTGRES_PASSWORD=RoEGG5g7&b # Random generated string corresponding with Django settings
|
|
||||||
- POSTGRES_DB=mam_docker
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
postgres_data:
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
echo "Waiting for Postgres..."
|
|
||||||
|
|
||||||
while ! nc -z "db" "5432"; do
|
|
||||||
sleep 0.1
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "PostgreSQL started"
|
|
||||||
|
|
||||||
PGPASSWORD="RoEGG5g7&b" # Random generated, corresponds to the one in docker-compose.yml
|
|
||||||
if psql "postgresql://mam-web:$PGPASSWORD@db:5432/mam_docker" -t -c '\dt' | cut -d \| -f 2 | grep -qw "seminar_cisla"; then
|
|
||||||
echo "\nExistuje tabulka 'seminar_cisla' v db, testdata pravděpodobně byla vygenerována.\n"
|
|
||||||
else
|
|
||||||
python ./manage.py testdata
|
|
||||||
python ./manage.py loaddata data/*
|
|
||||||
fi
|
|
||||||
|
|
||||||
exec "$@"
|
|
||||||
|
|
@ -13,7 +13,6 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import django
|
import django
|
||||||
from django.utils.version import get_docs_version
|
|
||||||
sys.path.insert(0, os.path.abspath('..'))
|
sys.path.insert(0, os.path.abspath('..'))
|
||||||
os.environ['DJANGO_SETTINGS_MODULE'] = 'mamweb.settings'
|
os.environ['DJANGO_SETTINGS_MODULE'] = 'mamweb.settings'
|
||||||
django.setup()
|
django.setup()
|
||||||
|
|
@ -37,7 +36,6 @@ extensions = [
|
||||||
'sphinx.ext.intersphinx',
|
'sphinx.ext.intersphinx',
|
||||||
'sphinx.ext.autosectionlabel',
|
'sphinx.ext.autosectionlabel',
|
||||||
'myst_parser',
|
'myst_parser',
|
||||||
'sphinxcontrib_django',
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
|
|
@ -74,8 +72,8 @@ html_static_path = ['_static']
|
||||||
|
|
||||||
# Provázání s jinými dokumentacemi
|
# Provázání s jinými dokumentacemi
|
||||||
intersphinx_mapping = {'python': ('https://docs.python.org/3', None),
|
intersphinx_mapping = {'python': ('https://docs.python.org/3', None),
|
||||||
'django': (f'http://docs.djangoproject.com/en/{get_docs_version()}/',
|
'django': ('http://docs.djangoproject.com/en/3.2/',
|
||||||
f'http://docs.djangoproject.com/en/{get_docs_version()}/_objects/'),}
|
'http://docs.djangoproject.com/en/3.2/_objects/'),}
|
||||||
|
|
||||||
# Generování tříd/funkcí/atributů v pořádí jak jsou naprogramované
|
# Generování tříd/funkcí/atributů v pořádí jak jsou naprogramované
|
||||||
autodoc_member_order = "bysource"
|
autodoc_member_order = "bysource"
|
||||||
|
|
|
||||||
27
docs/css.rst
27
docs/css.rst
|
|
@ -1,27 +0,0 @@
|
||||||
CSS (a další styly na webu)
|
|
||||||
===========================
|
|
||||||
|
|
||||||
Inspirován `css-trick článkem <https://css-tricks.com/methods-organize-css/>`_ jsem se rozhodl rozdělit
|
|
||||||
CSSka do
|
|
||||||
|
|
||||||
- Konstant (``constants.css``), které jsou využívány na mnoha místech CSSek
|
|
||||||
- Nastylování html tagů (``base.css``)
|
|
||||||
- Layoutu (``layout.css``), což je to, co určuje celkové rozložení stránky
|
|
||||||
- Jednotlivých prvků (``modules.css``)
|
|
||||||
|
|
||||||
Dále jsem separoval CSSka pro **galerii** (potřebuje hodně specifických stylů). Stejně tak **korekturovátko** má styly separátně.
|
|
||||||
|
|
||||||
Dále web (asi) používá externí frameworky (v separátních složkách – mají k sobě i JS a podobné věci):
|
|
||||||
|
|
||||||
- bootstrap: dělá nějaké basic stylování, *web je na něm hodně závislý* (například jsem zjistil, že bootstrap kdysi přidával ``font-size:14px``, bez čehož se web úplně rozpadnul) (také na něm běží mobilní meníčko, které navíc vyžaduje Popper, tedy bootstrap.bundle.js místo bootstrap.js)
|
|
||||||
|
|
||||||
Pak jsou tu ``mamweb-dev.css`` a ``printtable.css``, co jsem si ještě nerozmyslel, co s tím.
|
|
||||||
|
|
||||||
Pár myšlenek
|
|
||||||
------------
|
|
||||||
|
|
||||||
- Až na pár výjimek (galerii a korekturovátko) bych styly držel v jedné složce a málo souborech,
|
|
||||||
protože CSS šíleně dědí všechno možné
|
|
||||||
- Chce to dobře pojmenovávat třídy (speciálně aby bylo vidět, co ta třída dělá nebo kde se používá)
|
|
||||||
- Chce to hodně komentovat kód (speciálně tam, kde není splněn předchozí bod)
|
|
||||||
|
|
||||||
|
|
@ -9,6 +9,12 @@ 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,15 +0,0 @@
|
||||||
Lokální vývoj pomocí dockeru
|
|
||||||
============================
|
|
||||||
|
|
||||||
Přijde vám standardní zprovoznění painful? Docker comes to the rescue. Stačí mít nainstalovaný ``docker`` a spustit ``docker compose up``.
|
|
||||||
|
|
||||||
Co se děje under the hood
|
|
||||||
-------------------------
|
|
||||||
|
|
||||||
- ``docker-compose.yml`` specifikuje, že chceme kontejner pro web, který je závislý na kontejneru s PostgreSQL db
|
|
||||||
- ``web`` se buildí z ``Dockerfilu``, mountuje si kořen repa jako svůj volume (takže vidí změny), na konci spouští webserver a vysatvuje ho na port 8000 localhosta
|
|
||||||
- ``db`` je z ``postgres:13-bullseye`` a má nastavené nějaké parametry, svoje data ukládá jako docker volume
|
|
||||||
- ``Dockerfile`` staví ``web`` na pythonu3.9 a debianu bullseye (mělo by odpovídat gimlimu) - nainstaluje dependencies, nastaví locale a entrypoint (co se má vykonat při spouštění kontejneru)
|
|
||||||
- ``docker_entrypoint.sh`` počká na Postgres ready v ``db``, podívá se jestli jsou v něm testdata a když ne, tak je vygeneruje, pak spustí command z compose (i.e. webserver)
|
|
||||||
- ``mamweb/settings.py`` vybere django settings podle cesty (jako doteď), vybere ``mamweb/settings_docker.py``, které importuje všechno z ``mamweb/settings_local.py``, přepíše jen ``DATABASES`` a ``SECRET_KEY``, aby se jako DB Engine používal Postgres ve vedlejším kontejneru, aby se celý web choval stejně jako ``_test`` a ``_prod`` (``_local`` aktuálně používá DB Engine sqlite3, které se v něčem chová trochu rozdílně)
|
|
||||||
- kontejner ``web`` se musí nějak připojovat k postgresu v ``db``, k tomu slouží user ``mam-web``, náhodně vygenerované heslo (v ``docker-compose.yml`` a ``docker_entrypoint.sh``, musí se shodovat), db se jmenuje ``mam_docker``
|
|
||||||
|
|
@ -30,7 +30,6 @@ Dokumentace (jak v ``docs/``, tak přímo v kódu) je psaná ve
|
||||||
zavislosti
|
zavislosti
|
||||||
sphinx
|
sphinx
|
||||||
skripty
|
skripty
|
||||||
zkratky
|
|
||||||
modules/modules
|
modules/modules
|
||||||
dalsi_soubory
|
dalsi_soubory
|
||||||
zapisy/zapisy
|
zapisy/zapisy
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,13 @@
|
||||||
Sphinx na našem webu
|
Sphinx na našem webu
|
||||||
====================
|
====================
|
||||||
|
|
||||||
Dokumentace se zkompiluje příkazem ``make html`` ve složce ``docs``. (Musíte mít zapnutý virtualenv)
|
Dokumentace se zkompiluje příkazem ``make html`` ve složce ``doc``.
|
||||||
|
|
||||||
Složka ``modules`` je automaticiky generována a přegenerovávána. (**Nic v ní neupravovat!**)
|
Složka ``modules`` je automaticiky generována a přegenerovávána. (**Nic v ní neupravovat!**)
|
||||||
Jinak všechny rst, co jsou ve složce ``docs`` a jejích podsložkách nezačínajících podtržítkem, budou v dokumentaci a to je přesně to, co editovat pro změnu dokumentace (kromě dokumentace přímo v Pythonu).
|
Jinak všechny rst, co jsou ve složce ``doc`` a jejích podsložkách nezačínajících podtržítkem, budou v dokumentaci a to je přesně to, co editovat pro změnu dokumentace (kromě dokumentace přímo v Pythonu).
|
||||||
|
|
||||||
Sphinx se píše v rst: `Návod na syntaxi rst`_ `Cheat sheet`_
|
Sphinx se píše v rst: `Návod na syntaxi rst`_ `Cheat sheet`_
|
||||||
|
|
||||||
Pokud něco chcete protlačit do bočního meníčka, je potřeba to připsat do souboru ``docs/index.rst`` (Zatím není úplně konsensus nad tím, co tam má a nemá být, takže pokud si nejste jistí, cpěte tam *všechno* ☺)
|
|
||||||
|
|
||||||
To je snad vše, co je potřeba vědět k dokumentaci mamwebu. Následující sekce jsou o tom, co jsem provedl Sphinxu, aby to fungovalo:
|
To je snad vše, co je potřeba vědět k dokumentaci mamwebu. Následující sekce jsou o tom, co jsem provedl Sphinxu, aby to fungovalo:
|
||||||
|
|
||||||
.. _Návod na syntaxi rst: https://sphinx-tutorial.readthedocs.io/step-1/#sections
|
.. _Návod na syntaxi rst: https://sphinx-tutorial.readthedocs.io/step-1/#sections
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,11 @@ věci jako chybové hlášky a vzhled M&M stránek (menu, patička, atd.). Aktu
|
||||||
i veškeré csv.
|
i veškeré csv.
|
||||||
|
|
||||||
Další jsou pak jednotlivé aplikace (pokud něco hledáte, tak zřejmě chcete najít
|
Další jsou pak jednotlivé aplikace (pokud něco hledáte, tak zřejmě chcete najít
|
||||||
tu aplikaci, která tomu odpovídá, respektive se k ní dostat přes url).
|
tu aplikaci, která tomu odpovídá, respektive se k ní dostat přes url), za
|
||||||
|
zmínku stojí seminar, kde jsou takové ty věci, co zbyly. Plus jsou tam aktuálně
|
||||||
|
téměř všechny modely, protože je těžké je přesunout jinam.
|
||||||
|
|
||||||
**TLDR: Nevšímejte si složek data/ seminar/ a souborů přímo v kořenové složce.**
|
**TLDR: Nevšímejte si složky data/ a souborů přímo v kořenové složce.**
|
||||||
Kromě věcí potřebných ke gitu, :doc:`ke spuštění <vyvoj>` a fukci djanga,
|
Kromě věcí potřebných ke gitu, :doc:`ke spuštění <vyvoj>` a fukci djanga,
|
||||||
dalších drobností, lokální databáze a již zmíněných aplikací jsou tu ``data``,
|
dalších drobností, lokální databáze a již zmíněných aplikací jsou tu ``data``,
|
||||||
kde je takový ten obsah webu, co by se měl dát snadno měnit (tudíž musí být v
|
kde je takový ten obsah webu, co by se měl dát snadno měnit (tudíž musí být v
|
||||||
|
|
@ -20,9 +22,6 @@ databázi), tj. statické stránky, menu a obrázky v pozadí menu. Ten je třeb
|
||||||
měnit hlavně na produkci a sekundárně tady (může to dělat i newebař a nechcete
|
měnit hlavně na produkci a sekundárně tady (může to dělat i newebař a nechcete
|
||||||
přepsat jeho práci). Vše, co nejsou aplikace je popsáno :doc:`tady <dalsi_soubory>`.
|
přepsat jeho práci). Vše, co nejsou aplikace je popsáno :doc:`tady <dalsi_soubory>`.
|
||||||
|
|
||||||
Ještě je tu aplikace ``seminar/``, kde bylo původně skoro všechno, a tak nám
|
|
||||||
tam zbývá spoustu historických migrací (čehož se jen tak nezbavíme).
|
|
||||||
|
|
||||||
Základy djanga
|
Základy djanga
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ Aktuálně: Jakýsi coding style zhruba existuje, není popsaný, šíří se li
|
||||||
- Nesmí být striktně vynucovaný
|
- Nesmí být striktně vynucovaný
|
||||||
- Musel by být hodně nastavitelný
|
- Musel by být hodně nastavitelný
|
||||||
- Nechceme mít kód plný `#NOQA: WTF42`
|
- Nechceme mít kód plný `#NOQA: WTF42`
|
||||||
- Nejspíš vždycky bude mít false positives (`tvorba.utils.roman_numerals`) i false negatives (`tvorba.models.Cislo.posli_cislo_mailem`)
|
- Nejspíš vždycky bude mít false positives (`seminar.utils.roman_numerals`) i false negatives (`seminar.models.tvorba.Cislo.posli_cislo_mailem`)
|
||||||
- Možná dobrý sluha, ale určitě špatný pán (also: špatná zkušenost ☺)
|
- Možná dobrý sluha, ale určitě špatný pán (also: špatná zkušenost ☺)
|
||||||
- __Důsledek:__ Hrozí, že těch falešných varování bude moc, čímž to ztratí smysl úplně
|
- __Důsledek:__ Hrozí, že těch falešných varování bude moc, čímž to ztratí smysl úplně
|
||||||
- Potenciálně by šlo aplikovat jen lokálně na změny?
|
- Potenciálně by šlo aplikovat jen lokálně na změny?
|
||||||
|
|
|
||||||
|
|
@ -91,7 +91,7 @@ TODO: tabulka není úplná. Pokud na něco narazíte, tak ji prosím doplňte.
|
||||||
|
|
||||||
Ubuntu 22.10, ??, ``python3-venv``, ``python3-dev``, ``libpq-dev``, "Je potřeba zapnout zdroj ``universe`` a nainstalovat kompilátor C (``gcc``)?"
|
Ubuntu 22.10, ??, ``python3-venv``, ``python3-dev``, ``libpq-dev``, "Je potřeba zapnout zdroj ``universe`` a nainstalovat kompilátor C (``gcc``)?"
|
||||||
Linux Mint 21, ??, ``python3-venv``, ``python3-dev``, ``libpq-dev``, ""
|
Linux Mint 21, ??, ``python3-venv``, ``python3-dev``, ``libpq-dev``, ""
|
||||||
Archlinux 2022.11.01, AUR, vestavěný, vestavěné, ``postgresql-libs``, "Je potřeba céčkový kompilátor (``gcc``); nezapomenout vygenerovat locale ``cs_CZ.UTF-8``"
|
Archlinux 2022.11.01, AUR, vestavěný, vestavěné, ``postgresql-libs``, "Je potřeba céčkový kompilátor (``gcc``)"
|
||||||
openSUSE Leap 15.4, oficiální (``python39``), předinstalovaný?, ``python39-devel``, ??FIXME!!, "Výchozí verze pythonu je 3.6 a ta je moc stará, potřeba instalovat ``gcc``. Nevím jak sehnat pg_config."
|
openSUSE Leap 15.4, oficiální (``python39``), předinstalovaný?, ``python39-devel``, ??FIXME!!, "Výchozí verze pythonu je 3.6 a ta je moc stará, potřeba instalovat ``gcc``. Nevím jak sehnat pg_config."
|
||||||
Debian 11, "oficiální, výchozí", ??, ??, ??, "Určitě to tam rozběhat jde, protože Gimli. Nejspíš bude relativně podobné Ubuntu."
|
Debian 11, "oficiální, výchozí", ??, ??, ??, "Určitě to tam rozběhat jde, protože Gimli. Nejspíš bude relativně podobné Ubuntu."
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,86 +0,0 @@
|
||||||
Zkratky aplikací ve zdrojácích
|
|
||||||
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
|
|
||||||
|
|
||||||
Ve zdrojácích (zejména různé ``models.py``, ``views.py`` ap.) používáme spoustu
|
|
||||||
modelů. Někdy je praktičtější / někdo preferuje importovat celou aplikaci jako
|
|
||||||
jedno jméno a používat modely bez explicitních importů, tj::
|
|
||||||
|
|
||||||
# „hromadné“ importy:
|
|
||||||
import personalni.models as p
|
|
||||||
...
|
|
||||||
p.Organizator.objects.all()
|
|
||||||
|
|
||||||
# „explicitní“ importy:
|
|
||||||
from personalni.models import Organizator
|
|
||||||
...
|
|
||||||
Organizator.objects.all()
|
|
||||||
|
|
||||||
Na webschůzce 2024-11-05 jsme na toto téma otevřeli diskusi, tady je její závěr.
|
|
||||||
|
|
||||||
.. admonition:: Historické okénko
|
|
||||||
:class: note
|
|
||||||
|
|
||||||
Kdysi jsme měli (prakticky) všechny modely v jedné aplikaci, ``seminar``. Na
|
|
||||||
různých místech se pak ``seminar.models`` importovalo typicky jako ``s``
|
|
||||||
nebo jako ``m``.
|
|
||||||
|
|
||||||
Přirozeně, toto už nejde tak snadno, protože už neexistuje jedno místo, ze
|
|
||||||
kterého chceme tahat modely v kódu.
|
|
||||||
|
|
||||||
Konvence
|
|
||||||
========
|
|
||||||
|
|
||||||
Shodli jsme se, že nám rozhodně nevadí explicitní importy a z pohledu
|
|
||||||
čitelnosti je preferujeme. Nicméně při psaní kódu to některým webařům přijde
|
|
||||||
nepohodlné, takže očekáváme, že bude existovat spousta kódu, která bude chtít
|
|
||||||
importovat hromadně. Usnesli jsme se proto na následujících kanonických
|
|
||||||
zkratkách, aby se aplikace alespoň zkracovaly konzistentně.
|
|
||||||
|
|
||||||
V závorkách je uvedené případné jméno, ale nepředpokládáme, že někdo bude danou
|
|
||||||
aplikaci chtít importovat hromadně. Některé aplikace zkratku nemají, ty se
|
|
||||||
importují vždy pod plným jménem nebo explicitně.
|
|
||||||
|
|
||||||
.. list-table::
|
|
||||||
:header-rows: 1
|
|
||||||
|
|
||||||
* - Model
|
|
||||||
- Zkratka
|
|
||||||
* - ``aesop``
|
|
||||||
- ---
|
|
||||||
* - ``api``
|
|
||||||
- --- (``api``)
|
|
||||||
* - ``galerie``
|
|
||||||
- ``g``
|
|
||||||
* - ``header_fotky``
|
|
||||||
- --- (``hdr``)
|
|
||||||
* - ``korektury``
|
|
||||||
- ``kor``
|
|
||||||
* - ``novinky``
|
|
||||||
- ``nov``
|
|
||||||
* - ``odevzdavatko``
|
|
||||||
- ``odev``
|
|
||||||
* - ``personální``
|
|
||||||
- ``pers``/``p``
|
|
||||||
* - ``sifrovacka``
|
|
||||||
- (``sifr``)
|
|
||||||
* - ``soustredeni``
|
|
||||||
- ``sou``
|
|
||||||
* - ``treenode``
|
|
||||||
- ``tn``
|
|
||||||
* - ``tvorba``
|
|
||||||
- ``tv``
|
|
||||||
* - ``various``
|
|
||||||
- ``v``/``var``
|
|
||||||
* - ``vyroci``
|
|
||||||
- ---
|
|
||||||
* - ``vysledkovky``
|
|
||||||
- ``vysl``
|
|
||||||
|
|
||||||
|
|
||||||
.. admonition:: O všech modelech pod jedním jménem
|
|
||||||
:class: warning
|
|
||||||
|
|
||||||
Historické okénko výš zatajuje jeden detail: Při práci v shellu se hodí mít
|
|
||||||
modely k dispozici a nemuset přemýšlet nad dělením do aplikací, takže ve
|
|
||||||
skutečnosti existuje ``mamweb.vsechno``, jenž všechny modely obsahuje.
|
|
||||||
Z čitelnostních důvodů je ale *zakázáno* tento modul používat v kódu.
|
|
||||||
25
galerie/TODO
Normal file
25
galerie/TODO
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
========
|
||||||
|
| 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,4 +1,6 @@
|
||||||
from galerie.models import Obrazek, Galerie, VZDY, ORG, NIKDY, UCASTNIK
|
#coding: utf-8
|
||||||
|
|
||||||
|
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
|
||||||
from django import forms
|
from django import forms
|
||||||
|
|
@ -8,9 +10,8 @@ from django.db import models
|
||||||
|
|
||||||
def zverejnit_fotogalerii(modeladmin, request, queryset):
|
def zverejnit_fotogalerii(modeladmin, request, queryset):
|
||||||
'''zverejni vybranou fotogalerii i jeji vsechny podgalerie'''
|
'''zverejni vybranou fotogalerii i jeji vsechny podgalerie'''
|
||||||
queryset = queryset.filter(zobrazit=ORG)
|
|
||||||
for galerie in queryset:
|
for galerie in queryset:
|
||||||
galerie.zobrazit = VZDY
|
galerie.zobrazit = 0
|
||||||
galerie.save()
|
galerie.save()
|
||||||
zverejnit_fotogalerii(modeladmin, request,
|
zverejnit_fotogalerii(modeladmin, request,
|
||||||
Galerie.objects.filter(galerie_up = galerie))
|
Galerie.objects.filter(galerie_up = galerie))
|
||||||
|
|
@ -19,9 +20,8 @@ def zverejnit_fotogalerii(modeladmin, request, queryset):
|
||||||
|
|
||||||
def prepnout_fotogalerii_do_org_rezimu(modeladmin, request, queryset):
|
def prepnout_fotogalerii_do_org_rezimu(modeladmin, request, queryset):
|
||||||
'''zneverjni vybranou fotogalerii i jeji vsechny podgalerie'''
|
'''zneverjni vybranou fotogalerii i jeji vsechny podgalerie'''
|
||||||
queryset = queryset.filter(zobrazit=VZDY)
|
|
||||||
for galerie in queryset:
|
for galerie in queryset:
|
||||||
galerie.zobrazit = ORG
|
galerie.zobrazit = 1
|
||||||
galerie.save()
|
galerie.save()
|
||||||
prepnout_fotogalerii_do_org_rezimu(modeladmin, request,
|
prepnout_fotogalerii_do_org_rezimu(modeladmin, request,
|
||||||
Galerie.objects.filter(galerie_up = galerie))
|
Galerie.objects.filter(galerie_up = galerie))
|
||||||
|
|
|
||||||
47
galerie/autocomplete_light_registry.py.old
Normal file
47
galerie/autocomplete_light_registry.py.old
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
# -*- 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,4 +1,7 @@
|
||||||
|
#coding: utf-8
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
|
from seminar.models import Soustredeni
|
||||||
|
|
||||||
class KomentarForm(forms.Form):
|
class KomentarForm(forms.Form):
|
||||||
komentar = forms.CharField(label = "Komentář:", max_length = 300, required=False)
|
komentar = forms.CharField(label = "Komentář:", max_length = 300, required=False)
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,13 +0,0 @@
|
||||||
# Generated by Django 4.2.11 on 2024-04-30 21:53
|
|
||||||
|
|
||||||
from django.db import migrations
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('galerie', '0010_auto_20200819_0947'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
]
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
# Generated by Django 4.2.11 on 2024-05-01 13:07
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('soustredeni', '0001_split_from_seminar'),
|
|
||||||
('galerie', '0011_pre_split_soustredeni'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='galerie',
|
|
||||||
name='soustredeni',
|
|
||||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='soustredeni.soustredeni'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
# Generated by Django 4.2.11 on 2024-05-01 13:35
|
|
||||||
|
|
||||||
from django.db import migrations
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('galerie', '0012_soustredeni_relink'),
|
|
||||||
('soustredeni', '0003_post_split_soustredeni'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
]
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
# Generated by Django 4.2.20 on 2025-04-23 18:37
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('galerie', '0013_post_split_soustredeni'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='galerie',
|
|
||||||
name='zobrazit',
|
|
||||||
field=models.IntegerField(choices=[(0, 'Vždy'), (1, 'Organizátorům'), (3, 'Účastníkům a orgům'), (2, 'Nikdy')], default=1, verbose_name='Zobrazit?'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
# Generated by Django 4.2.16 on 2025-04-30 18:53
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('galerie', '0014_alter_galerie_zobrazit'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='galerie',
|
|
||||||
name='galerie_up',
|
|
||||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, to='galerie.galerie'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
# Generated by Django 4.2.16 on 2025-04-30 19:02
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('galerie', '0015_alter_galerie_galerie_up'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='obrazek',
|
|
||||||
name='galerie',
|
|
||||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='galerie.galerie'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,20 +1,21 @@
|
||||||
|
# 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 django.utils.encoding import force_text
|
||||||
from imagekit.models import ImageSpecField
|
from imagekit.models import ImageSpecField
|
||||||
from imagekit.processors import ResizeToFit, Transpose
|
from imagekit.processors import ResizeToFit, Transpose
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from soustredeni.models import Soustredeni
|
from seminar.models import Soustredeni
|
||||||
|
|
||||||
VZDY=0
|
VZDY=0
|
||||||
ORG=1
|
ORG=1
|
||||||
NIKDY=2
|
NIKDY=2
|
||||||
UCASTNIK=3
|
|
||||||
VIDITELNOST = (
|
VIDITELNOST = (
|
||||||
(VZDY, 'Vždy'),
|
(VZDY, 'Vždy'),
|
||||||
(ORG, 'Organizátorům'),
|
(ORG, 'Organizátorům'),
|
||||||
(UCASTNIK, 'Účastníkům a orgům'),
|
|
||||||
(NIKDY, 'Nikdy'),
|
(NIKDY, 'Nikdy'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -56,7 +57,7 @@ class Obrazek(models.Model):
|
||||||
nazev = models.CharField('Název', max_length=50, blank=True, null=True)
|
nazev = models.CharField('Název', max_length=50, blank=True, null=True)
|
||||||
popis = models.TextField('Popis', blank=True, null=True)
|
popis = models.TextField('Popis', blank=True, null=True)
|
||||||
datum_vlozeni = models.DateTimeField('Datum vložení', auto_now_add=True)
|
datum_vlozeni = models.DateTimeField('Datum vložení', auto_now_add=True)
|
||||||
galerie = models.ForeignKey('Galerie', blank=True, null=True, on_delete=models.CASCADE)
|
galerie = models.ForeignKey('Galerie', blank=True, null=True, on_delete=models.SET_NULL)
|
||||||
poradi = models.IntegerField('Pořadí', blank=True, null=True)
|
poradi = models.IntegerField('Pořadí', blank=True, null=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|
@ -90,7 +91,7 @@ class Galerie(models.Model):
|
||||||
titulni_obrazek = models.ForeignKey(Obrazek, blank = True, null = True, related_name = "+", on_delete = models.SET_NULL)
|
titulni_obrazek = models.ForeignKey(Obrazek, blank = True, null = True, related_name = "+", on_delete = models.SET_NULL)
|
||||||
zobrazit = models.IntegerField('Zobrazit?', default = ORG, choices = VIDITELNOST)
|
zobrazit = models.IntegerField('Zobrazit?', default = ORG, choices = VIDITELNOST)
|
||||||
galerie_up = models.ForeignKey('Galerie', blank = True, null = True,
|
galerie_up = models.ForeignKey('Galerie', blank = True, null = True,
|
||||||
on_delete=models.PROTECT)
|
on_delete=models.SET_NULL)
|
||||||
soustredeni = models.ForeignKey(Soustredeni, blank = True, null = True,
|
soustredeni = models.ForeignKey(Soustredeni, blank = True, null = True,
|
||||||
on_delete=models.PROTECT)
|
on_delete=models.PROTECT)
|
||||||
poradi = models.IntegerField('Pořadí', blank = True, null = False, default = 0)
|
poradi = models.IntegerField('Pořadí', blank = True, null = False, default = 0)
|
||||||
|
|
@ -100,3 +101,25 @@ class Galerie(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = 'Galerie'
|
verbose_name = 'Galerie'
|
||||||
verbose_name_plural = 'Galerie'
|
verbose_name_plural = 'Galerie'
|
||||||
|
|
||||||
|
#def link_na_preview(self):
|
||||||
|
#"""Odkaz na galerii, používá se v admin rozhranní. """
|
||||||
|
#return '<a href="/fotogalerie/galerie/%s/">Preview</a>' % self.id
|
||||||
|
#link_na_preview.allow_tags = True
|
||||||
|
#link_na_preview.short_description = 'Zobrazit galerii'
|
||||||
|
#
|
||||||
|
#def je_publikovano(self):
|
||||||
|
#"""Vraci True, pokud je tato galerie publikovana. """
|
||||||
|
#if self.zobrazit == VZDY:
|
||||||
|
#return True
|
||||||
|
#if self.zobrazit == PODLE_CLANKU:
|
||||||
|
#for clanek in self.clanek_set.all():
|
||||||
|
#if clanek.je_publikovano():
|
||||||
|
#return True
|
||||||
|
#return False
|
||||||
|
#
|
||||||
|
#@staticmethod
|
||||||
|
#def publikovane_galerie():
|
||||||
|
#"""Vraci galerie, ktere uz maji byt publikovane."""
|
||||||
|
#clanky = Blog.models.Clanek.publikovane_clanky()
|
||||||
|
#return Galerie.objects.filter(Q(zobrazit=VZDY) | (Q(clanek__in=clanky) & Q(zobrazit=PODLE_CLANKU))).distinct()
|
||||||
|
|
|
||||||
|
|
@ -1,191 +0,0 @@
|
||||||
@charset "utf-8"; /* vynuť utf-8 */
|
|
||||||
|
|
||||||
/* Galerie */
|
|
||||||
|
|
||||||
|
|
||||||
/* velká fotka */
|
|
||||||
/* zmenšování spolu s oknem prohlížeče */
|
|
||||||
.galerie .obrazek, .titulni_obrazek {
|
|
||||||
max-width: 100%;
|
|
||||||
height: auto;
|
|
||||||
width: auto\9; /* ie8 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.predchozi_obrazek{
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1;
|
|
||||||
width: 33%;
|
|
||||||
height: 100%;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
.predchozi_obrazek:hover{
|
|
||||||
background-image: url("/static/galerie/prvky/predchozi.svg");
|
|
||||||
filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.4));
|
|
||||||
background-position: left center;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
}
|
|
||||||
.dalsi_obrazek{
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1;
|
|
||||||
width: 33%;
|
|
||||||
height: 100%;
|
|
||||||
left: 67%;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
.dalsi_obrazek:hover{
|
|
||||||
background-image: url("/static/galerie/prvky/dalsi.svg");
|
|
||||||
filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.4));
|
|
||||||
background-position: right center;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
.galerie {
|
|
||||||
position: relative;
|
|
||||||
text-align: center;
|
|
||||||
margin: 20px auto 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.galerie h1 {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.galerie_hlavicka {
|
|
||||||
margin: 30px auto 30px auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popis {
|
|
||||||
margin: 10px 10px 30px 0px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#nahoru {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* titulní obrázek hlavní galerie soustředění */
|
|
||||||
|
|
||||||
.galerie_nahledy{
|
|
||||||
/*margin: 1em 0;*/
|
|
||||||
margin: auto;
|
|
||||||
padding: 10px;
|
|
||||||
text-align: center;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.galerie_nahledy img {
|
|
||||||
margin: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.galerie_nahledy div.navigace {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.galerie_nahled, .podgalerie_nahled { /* frame */
|
|
||||||
display: block;
|
|
||||||
position: relative;
|
|
||||||
float: left;
|
|
||||||
width: 200px;
|
|
||||||
height: 200px;
|
|
||||||
text-align: center;
|
|
||||||
border: solid;
|
|
||||||
border-width: 1px;
|
|
||||||
border-radius: 4px;
|
|
||||||
border-color: var(--svetla-oranzova);
|
|
||||||
background-color: var(--barva-pozadi);
|
|
||||||
white-space: nowrap;
|
|
||||||
margin: 10px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.galerie_nahled:hover, .podgalerie_nahled:hover {
|
|
||||||
background-color: var(--svetla-oranzova);
|
|
||||||
filter: drop-shadow(0px 5px 5px rgba(0, 0, 0, 0.4));
|
|
||||||
color: var(--tmava-oranzova);
|
|
||||||
}
|
|
||||||
|
|
||||||
.vystredeno{ /* helper */
|
|
||||||
display: inline-block;
|
|
||||||
height: 100%;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.galerie_nahled img {
|
|
||||||
vertical-align: middle;
|
|
||||||
max-height: 180px;
|
|
||||||
max-width: 180px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.galerie_nahled div {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0px;
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.podgalerie_nahled img {
|
|
||||||
margin-top: 20px;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
max-height: 125px;
|
|
||||||
max-width: 167px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.podgalerie_nahled .nazev_galerie {
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
top: 160px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.podgalerie_nahled.mam-org-only, .podgalerie_nahled.mam-resitel-only {
|
|
||||||
margin: 10px;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Odkazy na předchozí a následující podgalerii */
|
|
||||||
.galerie_predchozi_nasledujici {
|
|
||||||
overflow: auto;
|
|
||||||
margin: 10px auto 10px auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.galerie_predchozi_nasledujici .predchozi {
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.galerie_predchozi_nasledujici .nasledujici {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* posune kotvu obrázku v galerii o oranžový pruh dolu, aby se pod ním obrázek neschovával */
|
|
||||||
/* https://stackoverflow.com/questions/10732690/offsetting-an-html-anchor-to-adjust-for-fixed-header */
|
|
||||||
.kotva_obrazku {
|
|
||||||
position: absolute;
|
|
||||||
width: 0;
|
|
||||||
height: 55px; /* viz #title */
|
|
||||||
margin-top: -55px; /* viz #title */
|
|
||||||
}
|
|
||||||
@media(max-width: 860px) {
|
|
||||||
.kotva_obrazku {
|
|
||||||
height: 3em; /* #FIXME nemám páru, jak zjistit výšku toho elementu */
|
|
||||||
margin-top: -3em; /* #FIXME */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* plus a minus tlacitka */
|
|
||||||
.mam-org-only-galerie {
|
|
||||||
background: var(--orgovska-svetla-fialova);
|
|
||||||
padding: 10px;
|
|
||||||
margin: 10px 10px 10px -20px;
|
|
||||||
border: #333 2px dashed;
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mam-org-only-galerie a{
|
|
||||||
padding: 3px 5px;
|
|
||||||
margin: 5px;
|
|
||||||
border-radius: 20px;
|
|
||||||
background-color: var(--tmava-oranzova);;
|
|
||||||
color: var(--barva-pozadi);
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{% extends "galerie/base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
|
||||||
{% block nadpis1a %}
|
{% block nadpis1a %}
|
||||||
|
|
@ -46,7 +46,6 @@
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<div class="{% if obrazek.galerie.zobrazit == 1 or obrazek.galerie.zobrazit == 2 %}mam-org-only{% endif %}{% if obrazek.galerie.zobrazit == 3 %}mam-resitel-only{% endif %}">
|
|
||||||
|
|
||||||
<h2>
|
<h2>
|
||||||
{% for g in cesta %}
|
{% for g in cesta %}
|
||||||
|
|
@ -84,7 +83,7 @@
|
||||||
|
|
||||||
{# Popisek fotky #}
|
{# Popisek fotky #}
|
||||||
<div class="popis">
|
<div class="popis">
|
||||||
{% if upravy_popisku %}
|
{% if preview %}
|
||||||
<form action=".#nahoru" method="post" id="komentarform">
|
<form action=".#nahoru" method="post" id="komentarform">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<table>
|
<table>
|
||||||
|
|
@ -134,6 +133,4 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{% extends "galerie/base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
{% block nadpis1a %}
|
{% block nadpis1a %}
|
||||||
Galerie {{galerie.nazev}}
|
Galerie {{galerie.nazev}}
|
||||||
|
|
@ -6,11 +6,8 @@ Galerie {{galerie.nazev}}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
{# FIXME: použít konstanty… #}
|
{% if galerie.zobrazit > 0 %}
|
||||||
{% if galerie.zobrazit == 1 or galerie.zobrazit == 2 %}
|
|
||||||
<div class="mam-org-only">
|
<div class="mam-org-only">
|
||||||
{% elif galerie.zobrazit == 3 %}
|
|
||||||
<div class="mam-resitel-only">
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<h2>
|
<h2>
|
||||||
|
|
@ -48,43 +45,37 @@ Galerie {{galerie.nazev}}
|
||||||
{% if podgalerie %}
|
{% if podgalerie %}
|
||||||
{% with 22 as max_delka_nazvu %}
|
{% with 22 as max_delka_nazvu %}
|
||||||
<div class="galerie_nahledy">
|
<div class="galerie_nahledy">
|
||||||
{% for pgalerie in podgalerie %}
|
{% for galerie in podgalerie %}
|
||||||
<a href="../{{pgalerie.pk}}"
|
<a href="../{{galerie.pk}}"
|
||||||
{% if pgalerie.nazev|length > max_delka_nazvu %}
|
{% if galerie.nazev|length > max_delka_nazvu %}
|
||||||
title="{{ pgalerie.nazev }}"
|
title="{{ galerie.nazev }}"
|
||||||
{% endif %}
|
{% endif %}
|
||||||
class="podgalerie_nahled {% if pgalerie.zobrazit == 1 or pgalerie.zobrazit == 2 %}mam-org-only{% endif %}{% if pgalerie.zobrazit == 3 %}mam-resitel-only{% endif %}">
|
class="podgalerie_nahled">
|
||||||
{% if pgalerie.titulni_obrazek %}
|
{% if galerie.titulni_obrazek %}
|
||||||
{% with pgalerie.titulni_obrazek.obrazek_maly as obrazek %}
|
{% with galerie.titulni_obrazek.obrazek_maly as obrazek %}
|
||||||
<img src="{{ obrazek.url }}"
|
<img src="{{ obrazek.url }}"
|
||||||
/>
|
/>
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="nazev_galerie">
|
<div class="nazev_galerie">
|
||||||
{{ pgalerie|truncatechars:max_delka_nazvu }}
|
{{ galerie|truncatechars:max_delka_nazvu }}
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
{% if galerie.zobrazit == 1 or galerie.zobrazit == 2 %}
|
{% if user.je_org and galerie.zobrazit > 0 %}
|
||||||
{% if user.je_org %}
|
|
||||||
<div class="mam-org-only-galerie">
|
<div class="mam-org-only-galerie">
|
||||||
({{pgalerie.poradi}})
|
({{galerie.poradi}})
|
||||||
<span class="plus"><a href="plus/{{pgalerie.pk}}/">+</a></span>
|
<span class="plus"><a href="plus/{{galerie.pk}}/">+</a></span>
|
||||||
<span class="minus"><a href="minus/{{pgalerie.pk}}/">-</a></span>
|
<span class="minus"><a href="minus/{{galerie.pk}}/">-</a></span>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if user.je_org %}
|
{% if user.je_org and galerie.zobrazit > 0 %}
|
||||||
<div class="mam-org-only">
|
<div class="mam-org-only">
|
||||||
{% if galerie.zobrazit == 1 or galerie.zobrazit == 2 %}
|
<a href="./new">Vytvořit novou podgalerii </a>
|
||||||
<a href="./new">Vytvořit novou podgalerii</a>, <a href="{% url 'admin:galerie_galerie_change' galerie.pk %}">upravit galerii v adminu</a>
|
|
||||||
{% else %}
|
|
||||||
Jestli chceš změnit pořadí podgalerií nebo přidat novou, nastav zobrazení jen pro orgy v <a href="{% url 'admin:galerie_galerie_change' galerie.pk %}">adminu</a>.
|
|
||||||
{% endif %}
|
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
|
@ -129,10 +120,8 @@ Galerie {{galerie.nazev}}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if galerie.zobrazit == 1 or galerie.zobrazit == 2 %}
|
{% if galerie.zobrazit > 0 %}
|
||||||
</div> {# mam-org-only #}
|
</div> {# mam-org-only #}
|
||||||
{% elif galerie.zobrazit == 2 %}
|
|
||||||
</div> {# mam-resitel-only #}
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{% extends "galerie/base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
{% extends "base.html" %}
|
|
||||||
{% load static %}
|
|
||||||
|
|
||||||
{% block custom_css %}
|
|
||||||
<link href="{% static 'css/galerie.css' %}?version=2" rel="stylesheet">
|
|
||||||
{% endblock %}
|
|
||||||
|
|
@ -1,5 +1,14 @@
|
||||||
|
"""
|
||||||
|
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 personalni.utils import org_required
|
from seminar.utils import org_required
|
||||||
from . import views
|
from . import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
from galerie.models import Galerie
|
|
||||||
|
|
||||||
def top_galerie(g: Galerie) -> Galerie:
|
|
||||||
while g.galerie_up is not None:
|
|
||||||
g = g.galerie_up
|
|
||||||
return g
|
|
||||||
141
galerie/views.py
141
galerie/views.py
|
|
@ -1,41 +1,24 @@
|
||||||
|
# coding: utf-8
|
||||||
|
|
||||||
import random
|
import random
|
||||||
|
|
||||||
from django.http import HttpResponse, Http404, HttpRequest
|
from django.http import HttpResponse, Http404
|
||||||
from django.shortcuts import render, HttpResponseRedirect, get_object_or_404
|
from django.shortcuts import render, HttpResponseRedirect, get_object_or_404
|
||||||
from django.template import RequestContext
|
from django.template import RequestContext
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
from galerie.utils import top_galerie
|
from galerie.models import Obrazek, Galerie
|
||||||
from personalni.utils import resitel_uzivatele
|
from seminar.models import Soustredeni
|
||||||
|
|
||||||
from galerie.models import Obrazek, Galerie, VZDY, ORG, UCASTNIK, NIKDY
|
|
||||||
from soustredeni.models import Soustredeni
|
|
||||||
from galerie.forms import KomentarForm, NewGalerieForm
|
from galerie.forms import KomentarForm, NewGalerieForm
|
||||||
|
|
||||||
import logging
|
def zobrazit(galerie, request):
|
||||||
logger = logging.getLogger(__name__)
|
preview = False
|
||||||
|
if galerie.zobrazit >= 1:
|
||||||
def galerie_ke_zobrazeni(soustredeni: Soustredeni | None, request: HttpRequest) -> tuple[int]:
|
if request.user.je_org:
|
||||||
if request.user.is_superuser: return (VZDY, ORG, UCASTNIK, NIKDY)
|
preview = True;
|
||||||
if request.user.je_org: return (VZDY, ORG, UCASTNIK)
|
|
||||||
if request.user.is_anonymous: return (VZDY,)
|
|
||||||
if soustredeni is None: return (VZDY,)
|
|
||||||
if (resitel := resitel_uzivatele(request.user)) is not None:
|
|
||||||
if resitel.soustredeni_set.contains(soustredeni):
|
|
||||||
return (VZDY, UCASTNIK)
|
|
||||||
else:
|
else:
|
||||||
return (VZDY,)
|
raise Http404
|
||||||
logger.warning("Nepodařilo se zjistit, jaké galerie se mají zobrazit!")
|
return preview
|
||||||
return (VZDY,)
|
|
||||||
|
|
||||||
|
|
||||||
def zobrazit(galerie: Galerie, request: HttpRequest) -> bool:
|
|
||||||
soustredeni = top_galerie(galerie).soustredeni
|
|
||||||
return galerie.zobrazit in galerie_ke_zobrazeni(soustredeni, request)
|
|
||||||
|
|
||||||
def dovolit_upravy_popisku(galerie: Galerie, request: HttpRequest) -> bool:
|
|
||||||
# FIXME: Dočasné: úpravy jen když je to v org-only stavu. (Odpovídá předchozímu chování)
|
|
||||||
return request.user.je_org and galerie.zobrazit in (ORG, NIKDY)
|
|
||||||
|
|
||||||
|
|
||||||
def cesta_od_korene(g):
|
def cesta_od_korene(g):
|
||||||
|
|
@ -50,19 +33,19 @@ def cesta_od_korene(g):
|
||||||
def nahled(request, pk, soustredeni):
|
def nahled(request, pk, soustredeni):
|
||||||
"""Zobrazeni nahledu vsech fotek ve skupine."""
|
"""Zobrazeni nahledu vsech fotek ve skupine."""
|
||||||
galerie = get_object_or_404(Galerie, pk=pk)
|
galerie = get_object_or_404(Galerie, pk=pk)
|
||||||
soustredeni = top_galerie(galerie).soustredeni
|
|
||||||
|
|
||||||
# FIXME: přepsat model a použít přímo dolů…
|
|
||||||
podgalerie = Galerie.objects.filter(galerie_up = galerie).order_by('poradi')
|
podgalerie = Galerie.objects.filter(galerie_up = galerie).order_by('poradi')
|
||||||
podgalerie = podgalerie.filter(zobrazit__in=galerie_ke_zobrazeni(soustredeni, request))
|
if not request.user.je_org:
|
||||||
|
podgalerie = podgalerie.filter(zobrazit__lt=1)
|
||||||
|
|
||||||
obrazky = galerie.obrazek_set.all().order_by('poradi', 'nazev')
|
obrazky = Obrazek.objects.filter(galerie = galerie).order_by('poradi', 'nazev')
|
||||||
ma_se_zobrazit = zobrazit(galerie, request)
|
preview = zobrazit(galerie, request)
|
||||||
if not ma_se_zobrazit: raise Http404("Galerie sice existuje, ale my se tváříme, že ne :-D")
|
|
||||||
|
|
||||||
sourozenci = []
|
sourozenci = []
|
||||||
if galerie.galerie_up:
|
if galerie.galerie_up:
|
||||||
sourozenci = galerie.galerie_up.galerie_set.filter(zobrazit__in=galerie_ke_zobrazeni(soustredeni, request)).order_by('poradi')
|
sourozenci = galerie.galerie_up.galerie_set.all().order_by('poradi')
|
||||||
|
if not request.user.je_org:
|
||||||
|
sourozenci = sourozenci.filter(zobrazit__lt=1)
|
||||||
|
|
||||||
predchozi = None
|
predchozi = None
|
||||||
nasledujici = None
|
nasledujici = None
|
||||||
|
|
@ -81,6 +64,7 @@ def nahled(request, pk, soustredeni):
|
||||||
{'galerie' : galerie,
|
{'galerie' : galerie,
|
||||||
'podgalerie' : podgalerie,
|
'podgalerie' : podgalerie,
|
||||||
'obrazky' : obrazky,
|
'obrazky' : obrazky,
|
||||||
|
'preview' : preview,
|
||||||
'cesta': cesta,
|
'cesta': cesta,
|
||||||
'sourozenci': sourozenci,
|
'sourozenci': sourozenci,
|
||||||
'predchozi': predchozi,
|
'predchozi': predchozi,
|
||||||
|
|
@ -96,41 +80,9 @@ def detail(request, pk, fotka, soustredeni):
|
||||||
NAHLEDU = 1
|
NAHLEDU = 1
|
||||||
|
|
||||||
galerie = get_object_or_404(Galerie, pk=pk)
|
galerie = get_object_or_404(Galerie, pk=pk)
|
||||||
soustredeni = top_galerie(galerie).soustredeni
|
preview = zobrazit(galerie, request)
|
||||||
ma_se_zobrazit = zobrazit(galerie, request)
|
|
||||||
if not ma_se_zobrazit: raise Http404("Obrázek neukážu!")
|
|
||||||
obrazek = get_object_or_404(Obrazek, pk=fotka)
|
obrazek = get_object_or_404(Obrazek, pk=fotka)
|
||||||
|
|
||||||
# Pořadí není povinné. FIXME: `nazev` je zavádějící… Ale tohle je kanonické pořadí obrázků v galerii…
|
|
||||||
obrazky = galerie.obrazek_set.all().order_by('poradi', 'nazev')
|
obrazky = galerie.obrazek_set.all().order_by('poradi', 'nazev')
|
||||||
obrazky = list(obrazky)
|
|
||||||
index_obrazku = obrazky.index(obrazek)
|
|
||||||
# Podle mě se nemůže stát, že by volání výš selhalo, kdyžtak shodí web. (původně to byl explicitně ošetřený stav dávající 404)
|
|
||||||
predchozi_obrazky = list(reversed(obrazky[:index_obrazku]))
|
|
||||||
nasledujici_obrazky = obrazky[index_obrazku+1:]
|
|
||||||
# Může jich být hodně…
|
|
||||||
predchozi_obrazky = predchozi_obrazky[:NAHLEDU]
|
|
||||||
nasledujici_obrazky = nasledujici_obrazky[:NAHLEDU]
|
|
||||||
# Předchozí obrázky chceme v normálním pořadí
|
|
||||||
predchozi_obrazky = list(reversed(predchozi_obrazky))
|
|
||||||
|
|
||||||
if galerie.galerie_up is not None:
|
|
||||||
sousedni_galerie = Galerie.objects.filter(galerie_up=galerie.galerie_up, zobrazit__in=galerie_ke_zobrazeni(soustredeni, request)).order_by('poradi')
|
|
||||||
sousedni_galerie = list(sousedni_galerie)
|
|
||||||
# Teoreticky se můžeme dívat na galerie.poradi, ale jednak už tenhle pattern stejně je výš a druhak je galerií málo, takže pomalost nevadí.
|
|
||||||
index_galerie = sousedni_galerie.index(galerie)
|
|
||||||
predchozi_galerie = sousedni_galerie[index_galerie-1] if index_galerie > 0 else None
|
|
||||||
nasledujici_galerie = sousedni_galerie[index_galerie+1] if index_galerie < len(sousedni_galerie) - 1 else None
|
|
||||||
else:
|
|
||||||
predchozi_galerie = None
|
|
||||||
nasledujici_galerie = None
|
|
||||||
|
|
||||||
# Pokud je obrázků dost, tak další galerii nepotřebujeme
|
|
||||||
# (jo, mohli jsme si ušetřit práci, ale takhle je kód imho přehlednější a za pár ušetřených dotazů do DB to nestojí)
|
|
||||||
if len(predchozi_obrazky) >= NAHLEDU:
|
|
||||||
predchozi_galerie = None
|
|
||||||
if len(nasledujici_obrazky) >= NAHLEDU:
|
|
||||||
nasledujici_galerie = None
|
|
||||||
|
|
||||||
# vytvoreni a obslouzeni formulare
|
# vytvoreni a obslouzeni formulare
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
|
|
@ -141,6 +93,49 @@ def detail(request, pk, fotka, soustredeni):
|
||||||
else:
|
else:
|
||||||
form = KomentarForm({'komentar': obrazek.popis})
|
form = KomentarForm({'komentar': obrazek.popis})
|
||||||
|
|
||||||
|
# Poradi aktualniho obrazku v galerii/stitku.
|
||||||
|
for i in range(len(obrazky)):
|
||||||
|
if obrazky[i] == obrazek:
|
||||||
|
poradi = i
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# Obrazek neni v galerii/stitku.
|
||||||
|
raise Http404
|
||||||
|
|
||||||
|
|
||||||
|
# Nacteni okolnich obrazku a galerii
|
||||||
|
# TODO vyjmout zjisteni predchozich a nasledujicich galerii
|
||||||
|
# a udelat z toho funkci, ktera se pouzije u nahledu
|
||||||
|
predchozi_galerie = None
|
||||||
|
nasledujici_galerie = None
|
||||||
|
obrazky_dalsi = obrazky[poradi+1:poradi+NAHLEDU+1]
|
||||||
|
if (poradi+1) > NAHLEDU:
|
||||||
|
obrazky_predchozi = obrazky[poradi-NAHLEDU:poradi]
|
||||||
|
else:
|
||||||
|
obrazky_predchozi = obrazky[0:poradi]
|
||||||
|
if galerie.poradi > 1:
|
||||||
|
predchozi_galerie = Galerie.objects.\
|
||||||
|
filter(galerie_up=galerie.galerie_up).\
|
||||||
|
filter(poradi=(galerie.poradi-1))
|
||||||
|
if predchozi_galerie:
|
||||||
|
predchozi_galerie = predchozi_galerie[0]
|
||||||
|
else:
|
||||||
|
predchozi_galerie = None
|
||||||
|
if (poradi+1) == len(obrazky): # Tohle je poslední obrázek
|
||||||
|
if (galerie.poradi is not None
|
||||||
|
and galerie.galerie_up is not None):
|
||||||
|
nasledujici_galerie = Galerie.objects.\
|
||||||
|
filter(galerie_up=galerie.galerie_up).\
|
||||||
|
filter(poradi=(galerie.poradi+1))
|
||||||
|
else:
|
||||||
|
nasledujici_galerie = None
|
||||||
|
if nasledujici_galerie:
|
||||||
|
nasledujici_galerie = nasledujici_galerie[0]
|
||||||
|
else:
|
||||||
|
nasledujici_galerie = None
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Preskalovani obrazku do vybraneho prostoru.
|
# Preskalovani obrazku do vybraneho prostoru.
|
||||||
vyska = obrazek.obrazek_stredni.height
|
vyska = obrazek.obrazek_stredni.height
|
||||||
sirka = obrazek.obrazek_stredni.width
|
sirka = obrazek.obrazek_stredni.width
|
||||||
|
|
@ -158,9 +153,9 @@ def detail(request, pk, fotka, soustredeni):
|
||||||
'obrazek' : obrazek,
|
'obrazek' : obrazek,
|
||||||
'vyska' : vyska,
|
'vyska' : vyska,
|
||||||
'sirka' : sirka,
|
'sirka' : sirka,
|
||||||
'obrazky_predchozi' : predchozi_obrazky,
|
'obrazky_predchozi' : obrazky_predchozi,
|
||||||
'obrazky_dalsi' : nasledujici_obrazky,
|
'obrazky_dalsi' : obrazky_dalsi,
|
||||||
'upravy_popisku' : dovolit_upravy_popisku(galerie, request),
|
'preview' : preview,
|
||||||
'form' : form,
|
'form' : form,
|
||||||
'cesta': cesta_od_korene(galerie),
|
'cesta': cesta_od_korene(galerie),
|
||||||
})
|
})
|
||||||
|
|
@ -186,7 +181,7 @@ def new_galerie(request, galerie, soustredeni):
|
||||||
gal = Galerie()
|
gal = Galerie()
|
||||||
gal.nazev = form.cleaned_data['nazev']
|
gal.nazev = form.cleaned_data['nazev']
|
||||||
#gal.popis = form.cleaned_data['popis'] # popis nepouzivame
|
#gal.popis = form.cleaned_data['popis'] # popis nepouzivame
|
||||||
gal.zobrazit = ORG # galerie je v procesu vytvareni
|
gal.zobrazit = 1 # galerie je v procesu vytvareni
|
||||||
''' pokud je to podgalerie pridej nadrazenou galerii
|
''' pokud je to podgalerie pridej nadrazenou galerii
|
||||||
a nadrazene soustredeni nechej volne,
|
a nadrazene soustredeni nechej volne,
|
||||||
pokud je to hlavni galerie, tak nadrazena galerie neexistuje,
|
pokud je to hlavni galerie, tak nadrazena galerie neexistuje,
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,14 @@
|
||||||
|
"""
|
||||||
|
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,6 +1,8 @@
|
||||||
|
"""
|
||||||
|
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,3 +1,17 @@
|
||||||
|
"""
|
||||||
|
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,4 +1,3 @@
|
||||||
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
|
||||||
11
korektury/TODO
Normal file
11
korektury/TODO
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
- 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,10 +1,21 @@
|
||||||
|
"""
|
||||||
|
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, Oprava, KorekturaTag
|
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
|
||||||
|
|
@ -25,13 +36,12 @@ class KorekturovanePDFAdmin(VersionAdmin):
|
||||||
fieldsets = [
|
fieldsets = [
|
||||||
(None,
|
(None,
|
||||||
{'fields':
|
{'fields':
|
||||||
['pdf', 'cas', 'stran', 'nazev', 'orgove', 'komentar', 'poslat_mail']}),
|
['pdf', 'cas', 'org', 'stran', 'nazev', 'komentar', 'poslat_mail']}),
|
||||||
# (u'PDF', {'fields': ['pdf']}),
|
# (u'PDF', {'fields': ['pdf']}),
|
||||||
]
|
]
|
||||||
list_display = ['nazev', 'cas', 'stran']
|
list_display = ['nazev', 'cas', 'stran', 'org']
|
||||||
list_filter = []
|
list_filter = []
|
||||||
search_fields = []
|
search_fields = []
|
||||||
autocomplete_fields = ['orgove']
|
|
||||||
|
|
||||||
def save_model(self, request, obj, form, change):
|
def save_model(self, request, obj, form, change):
|
||||||
"""
|
"""
|
||||||
|
|
@ -62,11 +72,3 @@ Korekturovátko
|
||||||
).send()
|
).send()
|
||||||
|
|
||||||
admin.site.register(KorekturovanePDF, KorekturovanePDFAdmin)
|
admin.site.register(KorekturovanePDF, KorekturovanePDFAdmin)
|
||||||
|
|
||||||
|
|
||||||
class OpravaAdmin(admin.ModelAdmin):
|
|
||||||
model = Oprava
|
|
||||||
filter_horizontal = ("informovani_orgove", "tagy",)
|
|
||||||
|
|
||||||
admin.site.register(Oprava, OpravaAdmin)
|
|
||||||
admin.site.register(KorekturaTag)
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
from django.apps import AppConfig
|
|
||||||
|
|
||||||
|
|
||||||
class ApiConfig(AppConfig):
|
|
||||||
default_auto_field = 'django.db.models.BigAutoField'
|
|
||||||
name = 'korektury.api'
|
|
||||||
label = 'korektury_api' # Protože jedno api už máme.
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
from django.urls import path
|
|
||||||
from personalni.utils import org_required
|
|
||||||
from . import views
|
|
||||||
|
|
||||||
urlpatterns = [
|
|
||||||
path('<int:pdf_id>/stav', org_required(views.korektury_stav_view), name='korektury_api_pdf_stav'),
|
|
||||||
path('oprava/stav', org_required(views.oprava_stav_view), name='korektury_api_oprava_stav'),
|
|
||||||
path('<int:pdf_id>/opravy_a_komentare', org_required(views.opravy_a_komentare_view), name='korektury_api_opravy_a_komentare'),
|
|
||||||
path('oprava/smaz', org_required(views.oprava_smaz_view), name='korektury_api_oprava_smaz'),
|
|
||||||
path('komentar/smaz', org_required(views.komentar_smaz_view), name='korektury_api_komentar_smaz'),
|
|
||||||
]
|
|
||||||
|
|
@ -1,134 +0,0 @@
|
||||||
from http import HTTPStatus
|
|
||||||
|
|
||||||
from django.http import JsonResponse, HttpResponse
|
|
||||||
from django.shortcuts import get_object_or_404
|
|
||||||
from django.utils.html import linebreaks
|
|
||||||
|
|
||||||
from rest_framework import serializers
|
|
||||||
|
|
||||||
from korektury.utils import send_email_notification_komentar
|
|
||||||
from korektury.models import Oprava, KorekturovanePDF, Komentar, KorekturaTag
|
|
||||||
from personalni.models import Organizator
|
|
||||||
|
|
||||||
|
|
||||||
def korektury_stav_view(request, pdf_id: int, **kwargs):
|
|
||||||
q = request.POST
|
|
||||||
pdf = get_object_or_404(KorekturovanePDF, id=pdf_id)
|
|
||||||
status = q.get('state')
|
|
||||||
if status is not None:
|
|
||||||
assert status in KorekturovanePDF.STATUS.values
|
|
||||||
pdf.status = status
|
|
||||||
pdf.save()
|
|
||||||
return JsonResponse({'status': pdf.status})
|
|
||||||
|
|
||||||
|
|
||||||
def oprava_stav_view(request, **kwargs):
|
|
||||||
q = request.POST
|
|
||||||
op_id_str = q.get('id')
|
|
||||||
assert op_id_str is not None
|
|
||||||
op_id = int(op_id_str)
|
|
||||||
op = get_object_or_404(Oprava, id=op_id)
|
|
||||||
status = q.get('action')
|
|
||||||
if status is not None:
|
|
||||||
assert status in Oprava.STATUS.values
|
|
||||||
op.status = status
|
|
||||||
op.save()
|
|
||||||
return JsonResponse({'status': op.status})
|
|
||||||
|
|
||||||
def oprava_smaz_view(request, **kwargs):
|
|
||||||
q = request.POST
|
|
||||||
op_id_str = q.get('oprava_id')
|
|
||||||
assert op_id_str is not None
|
|
||||||
op_id = int(op_id_str)
|
|
||||||
oprava = get_object_or_404(Oprava, id=op_id)
|
|
||||||
oprava.delete()
|
|
||||||
return HttpResponse(status=HTTPStatus.NO_CONTENT)
|
|
||||||
|
|
||||||
def komentar_smaz_view(request, **kwargs):
|
|
||||||
q = request.POST
|
|
||||||
kom_id_str = q.get('komentar_id')
|
|
||||||
assert kom_id_str is not None
|
|
||||||
kom_id = int(kom_id_str)
|
|
||||||
komentar = get_object_or_404(Komentar, id=kom_id)
|
|
||||||
komentar.delete()
|
|
||||||
return HttpResponse(status=HTTPStatus.NO_CONTENT)
|
|
||||||
|
|
||||||
class KomentarSerializer(serializers.ModelSerializer):
|
|
||||||
class Meta:
|
|
||||||
model = Komentar
|
|
||||||
fields = '__all__'
|
|
||||||
|
|
||||||
def to_representation(self, instance):
|
|
||||||
ret = super().to_representation(instance)
|
|
||||||
ret["autor"] = str(instance.autor)
|
|
||||||
ret["text"] = linebreaks(ret["text"], autoescape=True) # Autora není třeba escapovat, ten se vkládá jako text.
|
|
||||||
return ret
|
|
||||||
|
|
||||||
class KorekturaTagSerializer(serializers.ModelSerializer):
|
|
||||||
class Meta:
|
|
||||||
model = KorekturaTag
|
|
||||||
fields = '__all__'
|
|
||||||
|
|
||||||
|
|
||||||
class OpravaSerializer(serializers.ModelSerializer):
|
|
||||||
class Meta:
|
|
||||||
model = Oprava
|
|
||||||
fields = '__all__'
|
|
||||||
|
|
||||||
def to_representation(self, instance):
|
|
||||||
ret = super().to_representation(instance)
|
|
||||||
ret["komentare"] = [KomentarSerializer(komentar).data for komentar in instance.komentar_set.all()]
|
|
||||||
ret["tagy"] = [KorekturaTagSerializer(tag).data for tag in instance.tagy.all()]
|
|
||||||
return ret
|
|
||||||
|
|
||||||
# komentar_set = serializers.ListField(child=KomentarSerializer())
|
|
||||||
|
|
||||||
def opravy_a_komentare_view(request, pdf_id: int, **kwargs):
|
|
||||||
if request.method == 'POST':
|
|
||||||
q = request.POST
|
|
||||||
|
|
||||||
x = int(q.get('x'))
|
|
||||||
y = int(q.get('y'))
|
|
||||||
img_id = int(q.get('img_id'))
|
|
||||||
oprava_id = int(q.get('oprava_id'))
|
|
||||||
komentar_id = int(q.get('komentar_id'))
|
|
||||||
text = q.get('text')
|
|
||||||
|
|
||||||
# prirazeni autora podle prihlaseni
|
|
||||||
autor_user = request.user
|
|
||||||
# pokud existuje ucet (user), ale neni to organizator = 403
|
|
||||||
autor = Organizator.objects.filter(osoba__user=autor_user).first()
|
|
||||||
|
|
||||||
if komentar_id != -1:
|
|
||||||
komentar = get_object_or_404(Komentar, id=komentar_id)
|
|
||||||
if komentar.text != text:
|
|
||||||
komentar.text = text
|
|
||||||
komentar.autor = autor
|
|
||||||
komentar.save()
|
|
||||||
oprava = komentar.oprava
|
|
||||||
else:
|
|
||||||
if oprava_id != -1:
|
|
||||||
oprava = get_object_or_404(Oprava, id=oprava_id)
|
|
||||||
else:
|
|
||||||
pdf = get_object_or_404(KorekturovanePDF, id=pdf_id)
|
|
||||||
oprava = Oprava.objects.create(
|
|
||||||
pdf=pdf,
|
|
||||||
strana=img_id,
|
|
||||||
x=x,
|
|
||||||
y=y,
|
|
||||||
)
|
|
||||||
|
|
||||||
Komentar.objects.create(oprava=oprava, autor=autor, text=text)
|
|
||||||
send_email_notification_komentar(oprava, autor, request)
|
|
||||||
|
|
||||||
tagy_raw = q.get('tagy')
|
|
||||||
if tagy_raw is not None:
|
|
||||||
oprava.tagy.clear()
|
|
||||||
if tagy_raw != "":
|
|
||||||
tagy = list(map(int, tagy_raw.split(",")))
|
|
||||||
oprava.tagy.add(*KorekturaTag.objects.filter(id__in=tagy))
|
|
||||||
|
|
||||||
|
|
||||||
opravy = Oprava.objects.filter(pdf=pdf_id).all()
|
|
||||||
# Serializovat list je prý security vulnerability, tedy je přidán slovník pro bezpečnost
|
|
||||||
return JsonResponse({"context": [OpravaSerializer(oprava).data for oprava in opravy]})
|
|
||||||
24
korektury/forms.py
Normal file
24
korektury/forms.py
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
"""
|
||||||
|
Formuláře (:class:`django.forms.Form`) umožňují jednoduchou tvorbu formulářů,
|
||||||
|
které lze pak jednoduše dát do frontendu i zpracovat na backendu.
|
||||||
|
|
||||||
|
Pro přidání políčka do formuláře je potřeba
|
||||||
|
- mít v modelu tu položku, kterou chci upravovat
|
||||||
|
- přidat do views (prihlaskaView, resitelEditView)
|
||||||
|
- přidat do forms
|
||||||
|
- includovat do html
|
||||||
|
"""
|
||||||
|
from django import forms
|
||||||
|
|
||||||
|
class OpravaForm(forms.Form):
|
||||||
|
""" formulář k přidání opravy (:class:`korektury.models.Oprava`) """
|
||||||
|
text = forms.CharField(max_length=256)
|
||||||
|
autor = forms.CharField(max_length=20)
|
||||||
|
x = forms.IntegerField()
|
||||||
|
y = forms.IntegerField()
|
||||||
|
scroll = forms.CharField(max_length=256)
|
||||||
|
pdf = forms.CharField(max_length=256)
|
||||||
|
img_id = forms.CharField(max_length=256)
|
||||||
|
id = forms.CharField(max_length=256)
|
||||||
|
action = forms.CharField(max_length=256)
|
||||||
|
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,3 +1,4 @@
|
||||||
|
# -*- 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,13 +0,0 @@
|
||||||
# Generated by Django 4.2.8 on 2024-03-12 20:24
|
|
||||||
|
|
||||||
from django.db import migrations
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('korektury', '0020_lepsi_popis_nazvu_PDF_v_adminu'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
]
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
# Generated by Django 4.2.11 on 2024-03-19 21:35
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
import django.db.models.deletion
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('personalni', '0003_initial'),
|
|
||||||
('korektury', '0021_auto_20240312_2124'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='komentar',
|
|
||||||
name='autor',
|
|
||||||
field=models.ForeignKey(blank=True, help_text='Autor komentáře', null=True, on_delete=django.db.models.deletion.SET_NULL, to='personalni.organizator'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='korekturovanepdf',
|
|
||||||
name='org',
|
|
||||||
field=models.ForeignKey(blank=True, default=None, help_text='Zodpovědný organizátor za obsah', null=True, on_delete=django.db.models.deletion.SET_NULL, to='personalni.organizator'),
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='oprava',
|
|
||||||
name='autor',
|
|
||||||
field=models.ForeignKey(blank=True, help_text='Autor opravy', null=True, on_delete=django.db.models.deletion.SET_NULL, to='personalni.organizator'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
# Generated by Django 4.2.11 on 2024-03-26 21:25
|
|
||||||
|
|
||||||
from django.db import migrations
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('korektury', '0022_alter_komentar_autor_alter_korekturovanepdf_org_and_more'),
|
|
||||||
('personalni', '0005_personalni_post_migrate'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
]
|
|
||||||
|
|
@ -1,41 +0,0 @@
|
||||||
# Generated by Django 4.2.13 on 2024-06-11 23:53
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
def pridej_orgy(apps, schema_editor):
|
|
||||||
PDF = apps.get_model('korektury', 'KorekturovanePDF')
|
|
||||||
for pdf in PDF.objects.all(): # Tohle by asi mělo jít udělat pomocí update, ale moc práce a rychlé hledání taky nepomohlo.
|
|
||||||
if pdf.org is not None: pdf.orgove.add(pdf.org)
|
|
||||||
pdf.save() # ig?
|
|
||||||
|
|
||||||
def vyber_orga(apps, schema_editor):
|
|
||||||
PDF = apps.get_model('korektury', 'KorekturovanePDF')
|
|
||||||
for pdf in PDF.objects.all():
|
|
||||||
orgove = pdf.orgove.all()
|
|
||||||
if len(orgove) > 1:
|
|
||||||
raise migrations.exceptions.IrreversibleError(f'PDF {pdf.id} má víc než jednoho zodpovědného orga, nejde odmigrovat na verzi, která umí jen jednoho.')
|
|
||||||
if len(orgove) == 0:
|
|
||||||
pdf.org = None
|
|
||||||
else:
|
|
||||||
pdf.org = orgove[0]
|
|
||||||
pdf.save()
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('personalni', '0011_osloveni_vsechny_choices'),
|
|
||||||
('korektury', '0023_personalni_post_migrate'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='korekturovanepdf',
|
|
||||||
name='orgove',
|
|
||||||
field=models.ManyToManyField(blank=True, default=None, help_text='Zodpovědní organizátoři za obsah (chodí jim maily o nových korekturách)', to='personalni.organizator'),
|
|
||||||
),
|
|
||||||
migrations.RunPython(pridej_orgy, vyber_orga),
|
|
||||||
migrations.RemoveField(
|
|
||||||
model_name='korekturovanepdf',
|
|
||||||
name='org',
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,45 +0,0 @@
|
||||||
# Generated by Django 4.2.16 on 2024-12-12 10:25
|
|
||||||
|
|
||||||
from django.db import migrations
|
|
||||||
|
|
||||||
import datetime
|
|
||||||
from django.utils import timezone
|
|
||||||
|
|
||||||
|
|
||||||
def oprava2komentar(apps, schema_editor):
|
|
||||||
Oprava = apps.get_model('korektury', 'Oprava')
|
|
||||||
Komentar = apps.get_model('korektury', 'Komentar')
|
|
||||||
|
|
||||||
for o in Oprava.objects.all():
|
|
||||||
Komentar.objects.create(oprava=o, text=o.text, autor=o.autor, cas=timezone.make_aware(datetime.datetime.fromtimestamp(0)))
|
|
||||||
|
|
||||||
def komentar2oprava(apps, schema_editor):
|
|
||||||
Oprava = apps.get_model('korektury', 'Oprava')
|
|
||||||
Komentar = apps.get_model('korektury', 'Komentar')
|
|
||||||
|
|
||||||
for o in Oprava.objects.all():
|
|
||||||
k = Komentar.objects.filter(oprava=o).first()
|
|
||||||
o.text = k.text
|
|
||||||
o.autor = k.autor
|
|
||||||
o.save()
|
|
||||||
k.delete()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('korektury', '0024_vic_orgu_k_pdf'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.RunPython(oprava2komentar, komentar2oprava),
|
|
||||||
migrations.RemoveField(
|
|
||||||
model_name='oprava',
|
|
||||||
name='autor',
|
|
||||||
),
|
|
||||||
migrations.RemoveField(
|
|
||||||
model_name='oprava',
|
|
||||||
name='text',
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
# Generated by Django 4.2.16 on 2025-02-11 14:28
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
def pridani_orgu(apps, _schema_editor):
|
|
||||||
Komentar = apps.get_model('korektury','Komentar')
|
|
||||||
for komentar in Komentar.objects.all():
|
|
||||||
org = komentar.autor
|
|
||||||
if org is not None:
|
|
||||||
# Tohle jde asi udělat lépe než .all(…). Ale nejhorší na tom je, že .add(…) funguje jinak tady v migracích.
|
|
||||||
if org not in komentar.oprava.informovani_orgove.all():
|
|
||||||
komentar.oprava.informovani_orgove.add(org)
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('personalni', '0019_rename_upozorneni_resitel_upozornovat_na_opravy_reseni'),
|
|
||||||
('korektury', '0025_remove_oprava_autor_remove_oprava_text'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='oprava',
|
|
||||||
name='informovani_orgove',
|
|
||||||
field=models.ManyToManyField(blank=True, default=None, help_text='Orgové informovaní při přidání komentáře ke korektuře', related_name='informovan_o_opravach', to='personalni.organizator', verbose_name='Informovaní organizátoři'),
|
|
||||||
),
|
|
||||||
migrations.RunPython(pridani_orgu, migrations.RunPython.noop),
|
|
||||||
]
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
# Generated by Django 4.2.16 on 2025-02-11 16:07
|
|
||||||
|
|
||||||
import colorfield.fields
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('korektury', '0026_oprava_informovani_orgove'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name='KorekturaTag',
|
|
||||||
fields=[
|
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
|
||||||
('nazev', models.CharField(help_text='Název daného tagu, <20 znaků', max_length=20, verbose_name='název tagu')),
|
|
||||||
('barva', colorfield.fields.ColorField(default='#FFFFFF', image_field=None, max_length=25, samples=None, verbose_name='barva daného tagu')),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
migrations.AddField(
|
|
||||||
model_name='oprava',
|
|
||||||
name='tagy',
|
|
||||||
field=models.ManyToManyField(blank=True, default=None, to='korektury.korekturatag'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
# Generated by Django 4.2.16 on 2025-03-19 18:27
|
|
||||||
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
('korektury', '0027_korekturatag_oprava_tagy'),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.AlterModelOptions(
|
|
||||||
name='korekturovanepdf',
|
|
||||||
options={'ordering': ['-cas'], 'verbose_name': 'PDF ke korekturování', 'verbose_name_plural': 'PDFka ke korekturování'},
|
|
||||||
),
|
|
||||||
migrations.AlterField(
|
|
||||||
model_name='korekturovanepdf',
|
|
||||||
name='nazev',
|
|
||||||
field=models.CharField(help_text='Název (např. „42.6 | analýza v4“ nebo „propagace | letáček v0“) korekturovaného PDF, v seznamu se seskupují podle textu do první mezery, tedy zde „42.6“ respektive „propagace“.', max_length=50, verbose_name='název PDF'),
|
|
||||||
),
|
|
||||||
]
|
|
||||||
|
|
@ -1,16 +1,27 @@
|
||||||
|
"""
|
||||||
|
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 colorfield.fields import ColorField
|
|
||||||
|
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.urls import reverse
|
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
from django.utils.encoding import force_text
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.text import get_valid_filename
|
from django.utils.text import get_valid_filename
|
||||||
|
|
||||||
from personalni.models import Organizator
|
from seminar.models import Organizator
|
||||||
|
|
||||||
import subprocess
|
import subprocess
|
||||||
from reversion import revisions as reversion
|
from reversion import revisions as reversion
|
||||||
|
|
@ -30,38 +41,42 @@ def generate_filename(self, filename):
|
||||||
clean)
|
clean)
|
||||||
return os.path.join(settings.KOREKTURY_PDF_DIR, fname)
|
return os.path.join(settings.KOREKTURY_PDF_DIR, fname)
|
||||||
|
|
||||||
|
|
||||||
#@reversion.register(ignore_duplicates=True)
|
#@reversion.register(ignore_duplicates=True)
|
||||||
class KorekturovanePDF(models.Model):
|
class KorekturovanePDF(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ['-cas']
|
ordering = ['-cas']
|
||||||
db_table = 'korekturovane_cislo'
|
db_table = 'korekturovane_cislo'
|
||||||
verbose_name = 'PDF ke korekturování'
|
verbose_name = u'PDF k opravám'
|
||||||
verbose_name_plural = 'PDFka ke korekturování'
|
verbose_name_plural = u'PDF k opravám'
|
||||||
|
|
||||||
#Interní ID
|
#Interní ID
|
||||||
id = models.AutoField(primary_key = True)
|
id = models.AutoField(primary_key = True)
|
||||||
|
|
||||||
cas = models.DateTimeField(u'čas vložení PDF',default=timezone.now,help_text = 'Čas vložení PDF')
|
cas = models.DateTimeField(u'čas vložení PDF',default=timezone.now,help_text = 'Čas vložení PDF')
|
||||||
|
|
||||||
nazev = models.CharField(u'název PDF',blank = False,max_length=50, help_text='Název (např. „42.6 | analýza v4“ nebo „propagace | letáček v0“) korekturovaného PDF, v seznamu se seskupují podle textu do první mezery, tedy zde „42.6“ respektive „propagace“.')
|
nazev = models.CharField(u'název PDF',blank = False,max_length=50, help_text='Název (např. `22.1 | analyza v4` nebo `propagace | letacek v0`) korekturovaného PDF')
|
||||||
|
|
||||||
komentar = models.TextField(u'komentář k PDF',blank = True, help_text='Komentář ke korekturovanému PDF (např. na co se zaměřit)')
|
komentar = models.TextField(u'komentář k PDF',blank = True, help_text='Komentář ke korekturovanému PDF (např. na co se zaměřit)')
|
||||||
|
|
||||||
pdf = models.FileField(u'PDF', upload_to = generate_filename)
|
pdf = models.FileField(u'PDF', upload_to = generate_filename)
|
||||||
|
|
||||||
orgove = models.ManyToManyField(Organizator, blank=True,
|
org = models.ForeignKey(Organizator, blank=True,
|
||||||
help_text='Zodpovědní organizátoři za obsah (chodí jim maily o nových korekturách)',
|
help_text='Zodpovědný organizátor za obsah',
|
||||||
default=None)
|
null=True, default=None, on_delete=models.SET_NULL)
|
||||||
|
|
||||||
stran = models.IntegerField(u'počet stran', help_text='Počet stran PDF',
|
stran = models.IntegerField(u'počet stran', help_text='Počet stran PDF',
|
||||||
default=0)
|
default=0)
|
||||||
|
STATUS_PRIDAVANI = 'pridavani'
|
||||||
class STATUS(models.TextChoices):
|
STATUS_ZANASENI = 'zanaseni'
|
||||||
PRIDAVANI = 'pridavani', 'Přidávání korektur'
|
STATUS_ZASTARALE = 'zastarale'
|
||||||
ZANASENI = 'zanaseni', 'Korektury jsou zanášeny'
|
STATUS_CHOICES = (
|
||||||
ZASTARALE = 'zastarale', 'Stará verze, nekorigovat'
|
(STATUS_PRIDAVANI, u'Přidávání korektur'),
|
||||||
|
(STATUS_ZANASENI, u'Korektury jsou zanášeny'),
|
||||||
status = models.CharField(u'stav PDF',max_length=16, choices=STATUS.choices, blank=False, default = STATUS.PRIDAVANI)
|
(STATUS_ZASTARALE, u'Stará verze, nekorigovat'),
|
||||||
|
)
|
||||||
|
status = models.CharField(u'stav PDF',max_length=16, choices=STATUS_CHOICES, blank=False,
|
||||||
|
default = STATUS_PRIDAVANI)
|
||||||
|
|
||||||
poslat_mail = models.BooleanField('Poslat mail o novém PDF', default=True,
|
poslat_mail = models.BooleanField('Poslat mail o novém PDF', default=True,
|
||||||
help_text='Určuje, zda se má o nově nahraném PDF poslat e-mail do mam-org. Při upravování existujícího souboru už nemá žádný vliv.',
|
help_text='Určuje, zda se má o nově nahraném PDF poslat e-mail do mam-org. Při upravování existujícího souboru už nemá žádný vliv.',
|
||||||
|
|
@ -130,17 +145,6 @@ class KorekturovanePDF(models.Model):
|
||||||
except IndexError:
|
except IndexError:
|
||||||
return self.nazev
|
return self.nazev
|
||||||
|
|
||||||
def get_absolute_url(self):
|
|
||||||
return reverse('korektury', kwargs={'pdf': self.id})
|
|
||||||
|
|
||||||
|
|
||||||
class KorekturaTag(models.Model):
|
|
||||||
nazev = models.CharField("název tagu", blank = False, max_length=20, help_text="Název daného tagu, <20 znaků")
|
|
||||||
barva = ColorField("barva daného tagu", default="#FFFFFF")
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.nazev
|
|
||||||
|
|
||||||
|
|
||||||
@reversion.register(ignore_duplicates=True)
|
@reversion.register(ignore_duplicates=True)
|
||||||
class Oprava(models.Model):
|
class Oprava(models.Model):
|
||||||
|
|
@ -160,22 +164,32 @@ class Oprava(models.Model):
|
||||||
x = models.IntegerField(u'x-ová souřadnice bugu')
|
x = models.IntegerField(u'x-ová souřadnice bugu')
|
||||||
y = models.IntegerField(u'y-ová souřadnice bugu')
|
y = models.IntegerField(u'y-ová souřadnice bugu')
|
||||||
|
|
||||||
class STATUS(models.TextChoices):
|
STATUS_K_OPRAVE = 'k_oprave'
|
||||||
K_OPRAVE = 'k_oprave', 'K opravě'
|
STATUS_OPRAVENO = 'opraveno'
|
||||||
OPRAVENO = 'opraveno', 'Opraveno'
|
STATUS_NENI_CHYBA = 'neni_chyba'
|
||||||
NENI_CHYBA = 'neni_chyba', 'Není chyba'
|
STATUS_K_ZANESENI = 'k_zaneseni'
|
||||||
K_ZANESENI = 'k_zaneseni', 'K zanesení do TeXu'
|
STATUS_CHOICES = (
|
||||||
|
(STATUS_K_OPRAVE, u'K opravě'),
|
||||||
status = models.CharField(u'stav opravy',max_length=16, choices=STATUS.choices, blank=False, default = STATUS.K_OPRAVE)
|
(STATUS_OPRAVENO, u'Opraveno'),
|
||||||
|
(STATUS_NENI_CHYBA, u'Není chyba'),
|
||||||
informovani_orgove = models.ManyToManyField(
|
(STATUS_K_ZANESENI, u'K zanesení do TeXu'),
|
||||||
Organizator, blank=True, default=None,
|
|
||||||
verbose_name='Informovaní organizátoři',
|
|
||||||
help_text="Orgové informovaní při přidání komentáře ke korektuře",
|
|
||||||
related_name='informovan_o_opravach',
|
|
||||||
)
|
)
|
||||||
|
status = models.CharField(u'stav opravy',max_length=16, choices=STATUS_CHOICES, blank=False,
|
||||||
|
default = STATUS_K_OPRAVE)
|
||||||
|
|
||||||
|
autor = models.ForeignKey(Organizator, blank = True,
|
||||||
|
help_text='Autor opravy',
|
||||||
|
null = True, on_delete=models.SET_NULL)
|
||||||
|
|
||||||
|
text = models.TextField(u'text opravy',blank = True, help_text='Text opravy')
|
||||||
|
|
||||||
|
# def __init__(self,dictionary):
|
||||||
|
# for k,v in dictionary.items():
|
||||||
|
# setattr(self,k,v)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return '{} od {}: {}'.format(self.status,self.autor,self.text)
|
||||||
|
|
||||||
tagy = models.ManyToManyField(KorekturaTag, blank=True, default=None,)
|
|
||||||
|
|
||||||
|
|
||||||
@reversion.register(ignore_duplicates=True)
|
@reversion.register(ignore_duplicates=True)
|
||||||
|
|
@ -201,7 +215,5 @@ class Komentar(models.Model):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '{} od {}: {}'.format(self.cas,self.autor,self.text)
|
return '{} od {}: {}'.format(self.cas,self.autor,self.text)
|
||||||
|
|
||||||
def save(self, *args, **kwargs):
|
|
||||||
super().save(*args, **kwargs)
|
|
||||||
if self.autor is not None:
|
|
||||||
self.oprava.informovani_orgove.add(self.autor)
|
|
||||||
|
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 697 B |
Binary file not shown.
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 717 B |
Binary file not shown.
|
Before Width: | Height: | Size: 307 B After Width: | Height: | Size: 270 B |
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue