diff --git a/header_fotky/context_processors.py b/header_fotky/context_processors.py index 0040cb5f..7f73faa7 100644 --- a/header_fotky/context_processors.py +++ b/header_fotky/context_processors.py @@ -12,46 +12,46 @@ from header_fotky.models import FotkaUrlVazba def vzhled(request): - """ - Podle času přidá do contextu, zdali je nebo není noc. Dále podle dení - doby a url přidá do contextu správnou fotku. - - url adresu nejprve vyzkouší celou, pak postupně odřezává věci za - lomítkem, dokud nenajde url, pro kterou existuje alespoň jedna fotka. - Z fotek pro toto url zkusí vybrat tu ve správné denní době a až poté - libovolnou. (Z více možných fotek pro 1 url a 1 dobu vybírá náhodně.) - """ - hodin = datetime.now().hour - if (hodin <= 6) or (hodin >= 20): - noc = True - nedoba = 'den' - doba = 'noc' - else: - noc = False - nedoba = 'noc' - doba = 'den' - url = request.path - - fotky = FotkaUrlVazba.objects.exclude(denni_doba=nedoba) - fotka = None - - # TODO rychlejší patternmatch? - while (fotka is None) and (url != ''): - presne = fotky.filter(url__exact=url) - if presne.count() > 0: - presne_doba = presne.filter(denni_doba=doba) - if presne_doba.count() > 0: - fotka = random.choice(presne_doba).url_fotky() - else: - fotka = random.choice(presne).url_fotky() - - url = url[:-1] - index = url.rfind('/') - if index != -1: - url = url[:index+1] - - if fotka is None: - fotka = settings.STATIC_URL + "images/header/vikendovka.jpg" - - return {'noc': noc, 'fotka': fotka} + """ + Podle času přidá do contextu, zdali je nebo není noc. Dále podle dení + doby a url přidá do contextu správnou fotku. + + url adresu nejprve vyzkouší celou, pak postupně odřezává věci za + lomítkem, dokud nenajde url, pro kterou existuje alespoň jedna fotka. + Z fotek pro toto url zkusí vybrat tu ve správné denní době a až poté + libovolnou. (Z více možných fotek pro 1 url a 1 dobu vybírá náhodně.) + """ + hodin = datetime.now().hour + if (hodin <= 6) or (hodin >= 20): + noc = True + nedoba = 'den' + doba = 'noc' + else: + noc = False + nedoba = 'noc' + doba = 'den' + url = request.path + + fotky = FotkaUrlVazba.objects.exclude(denni_doba=nedoba) + fotka = None + + # TODO rychlejší patternmatch? + while (fotka is None) and (url != ''): + presne = fotky.filter(url__exact=url) + if presne.count() > 0: + presne_doba = presne.filter(denni_doba=doba) + if presne_doba.count() > 0: + fotka = random.choice(presne_doba).url_fotky() + else: + fotka = random.choice(presne).url_fotky() + + url = url[:-1] + index = url.rfind('/') + if index != -1: + url = url[:index+1] + + if fotka is None: + fotka = settings.STATIC_URL + "images/header/vikendovka.jpg" + + return {'noc': noc, 'fotka': fotka} diff --git a/korektury/views.py b/korektury/views.py index d8d78c24..efeab19d 100644 --- a/korektury/views.py +++ b/korektury/views.py @@ -30,28 +30,28 @@ class KorekturyListView(generic.ListView): template_name = 'korektury/seznam.html' class KorekturyAktualniListView(KorekturyListView): - def get_queryset(self, *args, **kwargs): - queryset=super().get_queryset() - queryset=queryset.exclude(status="zastarale") - return queryset + def get_queryset(self, *args, **kwargs): + queryset=super().get_queryset() + queryset=queryset.exclude(status="zastarale") + return queryset - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - context['selected'] = 'aktualni' - return context + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['selected'] = 'aktualni' + return context class KorekturyZastaraleListView(KorekturyListView): - def get_queryset(self, *args, **kwargs): - queryset=super().get_queryset() - queryset=queryset.filter(status="zastarale").order_by("-cas") - return queryset - - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - context['selected'] = 'zastarale' - return context + def get_queryset(self, *args, **kwargs): + queryset=super().get_queryset() + queryset=queryset.filter(status="zastarale").order_by("-cas") + return queryset + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context['selected'] = 'zastarale' + return context class KorekturySeskupeneListView(KorekturyAktualniListView): template_name = 'korektury/seskupeny_seznam.html' diff --git a/mamweb/admin.py b/mamweb/admin.py index 2ad1aaaa..b6924468 100644 --- a/mamweb/admin.py +++ b/mamweb/admin.py @@ -17,14 +17,14 @@ from ckeditor_uploader.widgets import CKEditorUploadingWidget class FlatpageForm(FlatpageFormOld): - content = forms.CharField(widget=CKEditorUploadingWidget()) - class Meta: - model = FlatPage # this is not automatically inherited from FlatpageFormOld - exclude = [] + content = forms.CharField(widget=CKEditorUploadingWidget()) + class Meta: + model = FlatPage # this is not automatically inherited from FlatpageFormOld + exclude = [] class FlatPageAdmin(FlatPageAdminOld): - form = FlatpageForm + form = FlatpageForm # We have to unregister the normal admin, and then reregister ours @@ -36,19 +36,19 @@ locale.setlocale(locale.LC_COLLATE, 'cs_CZ.UTF-8') # https://books.agiliq.com/projects/django-admin-cookbook/en/latest/set_ordering.html # FIXME zpraseno pomocí toho, že Python umí bez problému přepisovat funkce def get_app_list(self, request): - """ - Return a sorted list of all the installed apps that have been - registered in this site. - """ + """ + Return a sorted list of all the installed apps that have been + registered in this site. + """ - app_dict = self._build_app_dict(request) - # Sort the apps alphabetically. - app_list = sorted(app_dict.values(), key=lambda x: locale.strxfrm('!') if (x['name'] == "Seminar") else locale.strxfrm(x['name'].lower())) + app_dict = self._build_app_dict(request) + # Sort the apps alphabetically. + app_list = sorted(app_dict.values(), key=lambda x: locale.strxfrm('!') if (x['name'] == "Seminar") else locale.strxfrm(x['name'].lower())) - # Sort the models alphabetically within each app. - for app in app_list: - app['models'].sort(key=lambda x: locale.strxfrm('žž' + x['name'].lower()) if (x['name'].endswith("(Node)")) else locale.strxfrm(x['name'].lower())) + # Sort the models alphabetically within each app. + for app in app_list: + app['models'].sort(key=lambda x: locale.strxfrm('žž' + x['name'].lower()) if (x['name'].endswith("(Node)")) else locale.strxfrm(x['name'].lower())) - return app_list + return app_list AdminSite.get_app_list = get_app_list diff --git a/mamweb/middleware.py b/mamweb/middleware.py index c1014257..7109423e 100644 --- a/mamweb/middleware.py +++ b/mamweb/middleware.py @@ -6,83 +6,83 @@ from django.http import HttpResponse, HttpResponseRedirect class LoggedInHintCookieMiddleware(object): - """Middleware to securely help with 'logged-in' detection for dual HTTP/HTTPS sites. - - On insecure requests: Checks for a (non-secure) cookie settings.LOGGED_IN_HINT_COOKIE_NAME - and if present, redirects to HTTPS (same adress). - Note this usually breaks non-GET (POST) requests. - - On secure requests: Updates cookie settings.LOGGED_IN_HINT_COOKIE_NAME to reflect - whether an user is logged in in the current session (cookie set to 'True' or cleared). - The cookie is set to expire at the same time as the sessionid cookie. - - By default, LOGGED_IN_HINT_COOKIE_NAME = 'logged_in_hint'. - """ - - def __init__(self): - if hasattr(settings, 'LOGGED_IN_HINT_COOKIE_NAME'): - self.cookie_name = settings.LOGGED_IN_HINT_COOKIE_NAME - else: self.cookie_name = 'logged_in_hint' - self.cookie_value = 'True' - - def cookie_correct(self, request): - return self.cookie_name in request.COOKIES and request.COOKIES[self.cookie_name] == self.cookie_value - - def process_request(self, request): - if not request.is_secure(): - if self.cookie_correct(request): - # redirect insecure (assuming http) requests with hint cookie to https - url = request.build_absolute_uri() - assert url[:5] == 'http:' - return HttpResponseRedirect('https:' + url[5:]) - return None - - def process_response(self, request, response): - if request.is_secure(): - # assuming full session info (as the conn. is secure) - try: - user = request.user - except AttributeError: # no user - ajax or other special request - return response - if user.is_authenticated(): - if not self.cookie_correct(request): - expiry = None if request.session.get_expire_at_browser_close() else request.session.get_expiry_date() - response.set_cookie(self.cookie_name, value=self.cookie_value, expires=expiry, secure=False) - else: - if self.cookie_name in request.COOKIES: - response.delete_cookie(self.cookie_name) - return response + """Middleware to securely help with 'logged-in' detection for dual HTTP/HTTPS sites. + + On insecure requests: Checks for a (non-secure) cookie settings.LOGGED_IN_HINT_COOKIE_NAME + and if present, redirects to HTTPS (same adress). + Note this usually breaks non-GET (POST) requests. + + On secure requests: Updates cookie settings.LOGGED_IN_HINT_COOKIE_NAME to reflect + whether an user is logged in in the current session (cookie set to 'True' or cleared). + The cookie is set to expire at the same time as the sessionid cookie. + + By default, LOGGED_IN_HINT_COOKIE_NAME = 'logged_in_hint'. + """ + + def __init__(self): + if hasattr(settings, 'LOGGED_IN_HINT_COOKIE_NAME'): + self.cookie_name = settings.LOGGED_IN_HINT_COOKIE_NAME + else: self.cookie_name = 'logged_in_hint' + self.cookie_value = 'True' + + def cookie_correct(self, request): + return self.cookie_name in request.COOKIES and request.COOKIES[self.cookie_name] == self.cookie_value + + def process_request(self, request): + if not request.is_secure(): + if self.cookie_correct(request): + # redirect insecure (assuming http) requests with hint cookie to https + url = request.build_absolute_uri() + assert url[:5] == 'http:' + return HttpResponseRedirect('https:' + url[5:]) + return None + + def process_response(self, request, response): + if request.is_secure(): + # assuming full session info (as the conn. is secure) + try: + user = request.user + except AttributeError: # no user - ajax or other special request + return response + if user.is_authenticated(): + if not self.cookie_correct(request): + expiry = None if request.session.get_expire_at_browser_close() else request.session.get_expiry_date() + response.set_cookie(self.cookie_name, value=self.cookie_value, expires=expiry, secure=False) + else: + if self.cookie_name in request.COOKIES: + response.delete_cookie(self.cookie_name) + return response class vzhled: - def process_request(self, request): - return None - - def process_view(self, request, view_func, view_args, view_kwargs): - #print "====== process_request ======" - #print view_func - #print view_args - #print view_kwargs - #print "=============================" - return None - - def process_template_response(self, request, response): - hodin = datetime.now().hour - if (hodin <= 6) or (hodin >= 14): # TODO 20 - response.context_data['noc'] = True - else: - response.context_data['noc'] = False - return response - - def process_response(self, request, response): - #hodin = datetime.now().hour - #if (hodin <= 6) or (hodin >= 14): # TODO 20 - #response.context_data['noc'] = True - #else: - #response.context_data['noc'] = False - return response - - - ##def process_exception(request, exception): - #pass + def process_request(self, request): + return None + + def process_view(self, request, view_func, view_args, view_kwargs): + #print "====== process_request ======" + #print view_func + #print view_args + #print view_kwargs + #print "=============================" + return None + + def process_template_response(self, request, response): + hodin = datetime.now().hour + if (hodin <= 6) or (hodin >= 14): # TODO 20 + response.context_data['noc'] = True + else: + response.context_data['noc'] = False + return response + + def process_response(self, request, response): + #hodin = datetime.now().hour + #if (hodin <= 6) or (hodin >= 14): # TODO 20 + #response.context_data['noc'] = True + #else: + #response.context_data['noc'] = False + return response + + + ##def process_exception(request, exception): + #pass diff --git a/mamweb/settings_common.py b/mamweb/settings_common.py index 5a610795..139190fa 100644 --- a/mamweb/settings_common.py +++ b/mamweb/settings_common.py @@ -40,8 +40,8 @@ MEDIA_ROOT = os.path.join(BASE_DIR, 'media') STATIC_ROOT = os.path.join(BASE_DIR, 'static') STATICFILES_FINDERS = ( - 'django.contrib.staticfiles.finders.AppDirectoriesFinder', - 'django.contrib.staticfiles.finders.FileSystemFinder', + 'django.contrib.staticfiles.finders.AppDirectoriesFinder', + 'django.contrib.staticfiles.finders.FileSystemFinder', ) # Where redirect for login required services @@ -57,41 +57,41 @@ DOBA_ODHLASENI_PRI_ZASKRTNUTI_NEODHLASOVAT = 365 * 24 * 3600 # rok # Modules configuration AUTHENTICATION_BACKENDS = ( - 'django.contrib.auth.backends.ModelBackend', + 'django.contrib.auth.backends.ModelBackend', ) MIDDLEWARE = ( # 'reversion.middleware.RevisionMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', + 'django.contrib.sessions.middleware.SessionMiddleware', + 'django.middleware.common.CommonMiddleware', + 'django.middleware.csrf.CsrfViewMiddleware', # FIXME: rozbilo se při přechodu na Django 2.0, nevím, jestli # se to dá zahodit bez náhrady # 'mamweb.middleware.LoggedInHintCookieMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', - 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware', + 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.messages.middleware.MessageMiddleware', + 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware', ) TEMPLATES = [ - { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': ( - 'django.contrib.auth.context_processors.auth', + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'DIRS': [], + 'APP_DIRS': True, + 'OPTIONS': { + 'context_processors': ( + 'django.contrib.auth.context_processors.auth', 'django.template.context_processors.request', - 'django.contrib.messages.context_processors.messages', - 'sekizai.context_processors.sekizai', - 'header_fotky.context_processors.vzhled', - 'various.context_processors.rozliseni', - 'various.context_processors.april', - ) - }, - }, + 'django.contrib.messages.context_processors.messages', + 'sekizai.context_processors.sekizai', + 'header_fotky.context_processors.vzhled', + 'various.context_processors.rozliseni', + 'various.context_processors.april', + ) + }, + }, ] @@ -99,59 +99,59 @@ TEMPLATES = [ INSTALLED_APPS = ( - # Basic - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.sites', - 'django.contrib.staticfiles', - 'django.contrib.auth', - - # Utilities - 'sekizai', - 'reversion', - 'django_countries', - 'solo', - 'ckeditor', - 'ckeditor_uploader', - 'taggit', - 'dal', - 'dal_select2', - - 'crispy_forms', - 'django_comments', - - 'django.contrib.flatpages', - 'django.contrib.humanize', - - 'sitetree', - - 'imagekit', - - 'polymorphic', - - 'webpack_loader', - 'rest_framework', - 'rest_framework.authtoken', - - # MaMweb - 'mamweb', - 'seminar', - 'galerie', - 'korektury', - 'prednasky', - 'header_fotky', - 'various', - 'various.autentizace', - 'api', - 'aesop', - 'odevzdavatko', - 'vysledkovky', - 'personalni', - 'soustredeni', - 'treenode', - - # Admin upravy: + # Basic + 'django.contrib.contenttypes', + 'django.contrib.sessions', + 'django.contrib.messages', + 'django.contrib.sites', + 'django.contrib.staticfiles', + 'django.contrib.auth', + + # Utilities + 'sekizai', + 'reversion', + 'django_countries', + 'solo', + 'ckeditor', + 'ckeditor_uploader', + 'taggit', + 'dal', + 'dal_select2', + + 'crispy_forms', + 'django_comments', + + 'django.contrib.flatpages', + 'django.contrib.humanize', + + 'sitetree', + + 'imagekit', + + 'polymorphic', + + 'webpack_loader', + 'rest_framework', + 'rest_framework.authtoken', + + # MaMweb + 'mamweb', + 'seminar', + 'galerie', + 'korektury', + 'prednasky', + 'header_fotky', + 'various', + 'various.autentizace', + 'api', + 'aesop', + 'odevzdavatko', + 'vysledkovky', + 'personalni', + 'soustredeni', + 'treenode', + + # Admin upravy: # 'material', # 'material.admin', @@ -159,76 +159,76 @@ INSTALLED_APPS = ( # 'admin_tools.theming', # 'admin_tools.menu', # 'admin_tools.dashboard', - 'django.contrib.admin', + 'django.contrib.admin', - # Nechat na konci (INSTALLED_APPS je uspořádané): - 'django_cleanup.apps.CleanupConfig', # Uklízí media/ + # Nechat na konci (INSTALLED_APPS je uspořádané): + 'django_cleanup.apps.CleanupConfig', # Uklízí media/ ) DEBUG_TOOLBAR_CONFIG = { - 'SHOW_COLLAPSED': True, + 'SHOW_COLLAPSED': True, } SUMMERNOTE_CONFIG = { - 'iframe': False, - 'airMode': False, - 'attachment_require_authentication': True, - 'width': '80%', + 'iframe': False, + 'airMode': False, + 'attachment_require_authentication': True, + 'width': '80%', # 'height': '30em', - 'toolbar': [ - ['style', ['style']], - ['font', ['bold', 'italic', 'superscript', 'subscript', 'clear']], - ['color', ['color']], - ['para', ['ul', 'ol', 'paragraph']], - ['table', ['table']], - ['insert', ['link', 'picture', 'hr']], - ['view', ['fullscreen', 'codeview']], - ['help', ['help']], - ] + 'toolbar': [ + ['style', ['style']], + ['font', ['bold', 'italic', 'superscript', 'subscript', 'clear']], + ['color', ['color']], + ['para', ['ul', 'ol', 'paragraph']], + ['table', ['table']], + ['insert', ['link', 'picture', 'hr']], + ['view', ['fullscreen', 'codeview']], + ['help', ['help']], + ] } CKEDITOR_UPLOAD_PATH = "uploads/" CKEDITOR_IMAGE_BACKEND = 'pillow' #CKEDITOR_JQUERY_URL = '//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js' CKEDITOR_CONFIGS = { - 'default': { - 'entities': False, - 'toolbar': [ - ['Source', 'ShowBlocks', '-', 'Maximize'], - ['Bold', 'Italic', 'Subscript', 'Superscript', '-', 'RemoveFormat'], - ['NumberedList','BulletedList','-','Blockquote','-','JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], - ['Link', 'Unlink', 'Anchor', '-', 'Image', 'Table', 'HorizontalRule'], - ['Format'], - - ], + 'default': { + 'entities': False, + 'toolbar': [ + ['Source', 'ShowBlocks', '-', 'Maximize'], + ['Bold', 'Italic', 'Subscript', 'Superscript', '-', 'RemoveFormat'], + ['NumberedList','BulletedList','-','Blockquote','-','JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'], + ['Link', 'Unlink', 'Anchor', '-', 'Image', 'Table', 'HorizontalRule'], + ['Format'], + + ], # 'toolbar': 'full', - 'height': '40em', - 'width': '100%', - 'toolbarStartupExpanded': False, - 'allowedContent' : True, - }, + 'height': '40em', + 'width': '100%', + 'toolbarStartupExpanded': False, + 'allowedContent' : True, + }, } # Webpack loader VUE_FRONTEND_DIR = os.path.join(BASE_DIR, 'vue_frontend') WEBPACK_LOADER = { - 'DEFAULT': { - 'CACHE': False, - 'BUNDLE_DIR_NAME': 'vue/', # must end with slash - 'STATS_FILE': os.path.join(VUE_FRONTEND_DIR, 'webpack-stats.json'), - 'POLL_INTERVAL': 0.1, - 'TIMEOUT': None, - 'IGNORE': [r'.+\.hot-update.js', r'.+\.map'] - } + 'DEFAULT': { + 'CACHE': False, + 'BUNDLE_DIR_NAME': 'vue/', # must end with slash + 'STATS_FILE': os.path.join(VUE_FRONTEND_DIR, 'webpack-stats.json'), + 'POLL_INTERVAL': 0.1, + 'TIMEOUT': None, + 'IGNORE': [r'.+\.hot-update.js', r'.+\.map'] + } } # Dajngo REST Framework REST_FRAMEWORK = { - 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', - 'PAGE_SIZE': 100 + 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', + 'PAGE_SIZE': 100 } @@ -236,22 +236,22 @@ REST_FRAMEWORK = { # Create file 'django.secret' in every install (it is not kept in git) try: - with open(os.path.join(os.path.dirname(__file__), '..', 'django.secret')) as f: - SECRET_KEY = f.readline().strip() + with open(os.path.join(os.path.dirname(__file__), '..', 'django.secret')) as f: + SECRET_KEY = f.readline().strip() except: - SECRET_KEY = '12345zmr_k53a*@f4q_+ji^o@!pgpef*5&8c7zzdqwkdlkj' + SECRET_KEY = '12345zmr_k53a*@f4q_+ji^o@!pgpef*5&8c7zzdqwkdlkj' # Logging LOGGING = { - 'version': 1, - 'disable_existing_loggers': False, + 'version': 1, + 'disable_existing_loggers': False, - 'formatters': { - 'verbose': { - 'format': '%(levelname)s %(asctime)s %(module)s (logger %(name)s): %(message)s' - }, - }, + 'formatters': { + 'verbose': { + 'format': '%(levelname)s %(asctime)s %(module)s (logger %(name)s): %(message)s' + }, + }, 'filters': { 'Http404AsInfo': { @@ -262,76 +262,76 @@ LOGGING = { }, }, - 'loggers': { - - 'django': { - 'handlers': ['console'], - 'level': 'DEBUG', - 'filters': ['StripSensitiveFormData'], - }, - 'django.security.csrf': { - 'handlers': ['console'], - 'level': 'DEBUG', - 'filters': ['StripSensitiveFormData'], - }, - 'django.request': { - 'handlers': ['console'], - 'level': 'DEBUG', + 'loggers': { + + 'django': { + 'handlers': ['console'], + 'level': 'DEBUG', + 'filters': ['StripSensitiveFormData'], + }, + 'django.security.csrf': { + 'handlers': ['console'], + 'level': 'DEBUG', + 'filters': ['StripSensitiveFormData'], + }, + 'django.request': { + 'handlers': ['console'], + 'level': 'DEBUG', 'filters': ['Http404AsInfo'], - }, + }, - 'seminar.prihlaska.form':{ + 'seminar.prihlaska.form':{ 'handlers': ['console','registration_logfile'], 'level': 'INFO' }, - 'seminar.prihlaska.problem':{ + 'seminar.prihlaska.problem':{ 'handlers': ['console','mail_registration','registration_error_log'], 'level': 'INFO' }, - # Catch-all logger - '': { - 'handlers': ['console'], # Add 'mail_admins' in prod and test - 'level': 'DEBUG', - 'filters': ['StripSensitiveFormData'], - }, - - }, - - 'handlers': { - - 'console': { - 'level': 'WARNING', ## Set to 'DEBUG' in local - 'class': 'logging.StreamHandler', - 'formatter': 'verbose', - }, - - 'mail_admins': { - 'level': 'WARNING', - 'class': 'django.utils.log.AdminEmailHandler', - 'formatter': 'verbose', - 'filters': ['StripSensitiveFormData'], - }, - 'mail_registration': { - 'level': 'WARNING', - 'class': 'django.utils.log.AdminEmailHandler', - 'formatter': 'verbose', - }, - 'registration_logfile':{ - 'level': 'INFO', + # Catch-all logger + '': { + 'handlers': ['console'], # Add 'mail_admins' in prod and test + 'level': 'DEBUG', + 'filters': ['StripSensitiveFormData'], + }, + + }, + + 'handlers': { + + 'console': { + 'level': 'WARNING', ## Set to 'DEBUG' in local + 'class': 'logging.StreamHandler', + 'formatter': 'verbose', + }, + + 'mail_admins': { + 'level': 'WARNING', + 'class': 'django.utils.log.AdminEmailHandler', + 'formatter': 'verbose', + 'filters': ['StripSensitiveFormData'], + }, + 'mail_registration': { + 'level': 'WARNING', + 'class': 'django.utils.log.AdminEmailHandler', + 'formatter': 'verbose', + }, + 'registration_logfile':{ + 'level': 'INFO', 'class': 'logging.FileHandler', # filename declared in specific configuration files - 'formatter': 'verbose', + 'formatter': 'verbose', }, - 'registration_error_log':{ - 'level': 'INFO', + 'registration_error_log':{ + 'level': 'INFO', 'class': 'logging.FileHandler', # filename declared in specific configuration files - 'formatter': 'verbose', + 'formatter': 'verbose', }, - }, - } + }, + } # Permissions for uploads FILE_UPLOAD_PERMISSIONS = 0o0644 @@ -352,14 +352,14 @@ POSLI_MAILOVOU_NOTIFIKACI = False # Logování chyb class InvalidTemplateVariable(str): - def __mod__(self, variable): - import logging - logger = logging.getLogger(__name__) - for line in traceback.walk_stack(None): - if 'context' in line[0].f_locals and 'request' in line[0].f_locals['context']: - logger.warning("Proměnná '%s' neexistuje: %s" % (variable, line[0].f_locals['context']['request'])) - break - return '' + def __mod__(self, variable): + import logging + logger = logging.getLogger(__name__) + for line in traceback.walk_stack(None): + if 'context' in line[0].f_locals and 'request' in line[0].f_locals['context']: + logger.warning("Proměnná '%s' neexistuje: %s" % (variable, line[0].f_locals['context']['request'])) + break + return '' TEMPLATES[0]['OPTIONS']['string_if_invalid'] = InvalidTemplateVariable('%s') # Django 3.2 vyžaduje explicitní nastavení autoklíče, zatím nechápu proč diff --git a/mamweb/settings_local.py b/mamweb/settings_local.py index 4cf76dc2..540c0453 100644 --- a/mamweb/settings_local.py +++ b/mamweb/settings_local.py @@ -11,16 +11,16 @@ import os.path from .settings_common import * MIDDLEWARE += ( - 'debug_toolbar.middleware.DebugToolbarMiddleware', - ) + 'debug_toolbar.middleware.DebugToolbarMiddleware', + ) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/ INSTALLED_APPS += ( - 'debug_toolbar', - 'django_extensions', - ) + 'debug_toolbar', + 'django_extensions', + ) # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True @@ -37,10 +37,10 @@ ALLOWED_HOSTS.append('localhost') # https://docs.djangoproject.com/en/1.7/ref/settings/#databases DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME': os.path.join(BASE_DIR, 'db-local.sqlite3'), - } + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': os.path.join(BASE_DIR, 'db-local.sqlite3'), + } } #DATABASES = { # 'default': { @@ -52,46 +52,46 @@ DATABASES = { # LOGGING LOGGING = { - 'version': 1, - 'disable_existing_loggers': True, - 'filters': { - 'require_debug_false': { - '()': 'django.utils.log.RequireDebugFalse' - } - }, - 'formatters': { - 'simple': { - 'format': '%(asctime)s - %(name)s - %(levelname)-8s - %(message)s', - }, - }, - 'handlers': { - 'dummy': { - 'class': 'logging.NullHandler', - }, - 'console': { - 'level': 'DEBUG', - 'class': 'logging.StreamHandler', - 'formatter': 'simple', - }, - }, - 'loggers': { + 'version': 1, + 'disable_existing_loggers': True, + 'filters': { + 'require_debug_false': { + '()': 'django.utils.log.RequireDebugFalse' + } + }, + 'formatters': { + 'simple': { + 'format': '%(asctime)s - %(name)s - %(levelname)-8s - %(message)s', + }, + }, + 'handlers': { + 'dummy': { + 'class': 'logging.NullHandler', + }, + 'console': { + 'level': 'DEBUG', + 'class': 'logging.StreamHandler', + 'formatter': 'simple', + }, + }, + 'loggers': { # Vypisovani databazovych dotazu do konzole - #'django.db.backends': { - # 'level': 'DEBUG', - # 'handlers': ['console'], - # 'propagate': False, - #}, - 'werkzeug': { - 'handlers': ['console'], - 'level': 'DEBUG', - 'propagate': True, - }, - '': { - 'handlers': ['console'], - 'level': 'DEBUG', - 'propagate': False, - }, - }, + #'django.db.backends': { + # 'level': 'DEBUG', + # 'handlers': ['console'], + # 'propagate': False, + #}, + 'werkzeug': { + 'handlers': ['console'], + 'level': 'DEBUG', + 'propagate': True, + }, + '': { + 'handlers': ['console'], + 'level': 'DEBUG', + 'propagate': False, + }, + }, } # set to 'DEBUG' for EXTRA verbose output diff --git a/mamweb/settings_prod.py b/mamweb/settings_prod.py index 6a20ff8c..3a81c8c4 100644 --- a/mamweb/settings_prod.py +++ b/mamweb/settings_prod.py @@ -16,8 +16,8 @@ from .settings_common import * # See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/ INSTALLED_APPS += ( - 'django_extensions', - ) + 'django_extensions', + ) # SECURITY WARNING: keep the secret key used in production secret! assert not SECRET_KEY.startswith('12345') @@ -34,14 +34,14 @@ ALLOWED_HOSTS = ['mam.mff.cuni.cz', 'www.mam.mff.cuni.cz', 'atrey.karlin.mff.cun # https://docs.djangoproject.com/en/1.7/ref/settings/#databases DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': 'mam_prod', - 'USER': 'mam-web', - 'TEST': { - 'NAME': 'mam-prod-testdb', - }, - }, + 'default': { + 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'NAME': 'mam_prod', + 'USER': 'mam-web', + 'TEST': { + 'NAME': 'mam-prod-testdb', + }, + }, } import os diff --git a/mamweb/settings_test.py b/mamweb/settings_test.py index 365664d2..eac5a7b4 100644 --- a/mamweb/settings_test.py +++ b/mamweb/settings_test.py @@ -13,16 +13,16 @@ import os.path from .settings_common import * # zatim nutne, casem snad vyresime # noqa MIDDLEWARE += ( - 'debug_toolbar.middleware.DebugToolbarMiddleware', - ) + 'debug_toolbar.middleware.DebugToolbarMiddleware', + ) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.7/howto/deployment/checklist/ INSTALLED_APPS += ( - 'debug_toolbar', - 'django_extensions', - ) + 'debug_toolbar', + 'django_extensions', + ) # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = ')^u=i65*zmr_k53a*@f4q_+ji^o@!pgpef*5&8c7zzv9l+zo)n' @@ -38,21 +38,21 @@ ALLOWED_HOSTS = ['*.mam.mff.cuni.cz', 'atrey.karlin.mff.cuni.cz', 'mam.mff.cuni. # https://docs.djangoproject.com/en/1.7/ref/settings/#databases DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.postgresql_psycopg2', - 'NAME': 'mam_test', - 'USER': 'mam-web', - 'TEST': { - 'NAME': 'mam-test-testdb', - }, - }, + 'default': { + 'ENGINE': 'django.db.backends.postgresql_psycopg2', + 'NAME': 'mam_test', + 'USER': 'mam-web', + 'TEST': { + 'NAME': 'mam-test-testdb', + }, + }, } import os SERVER_EMAIL = 'mamweb-test-errors@mam.mff.cuni.cz' ADMINS = [ - ('M&M ERRORs', 'mam-errors@mam.mff.cuni.cz'), + ('M&M ERRORs', 'mam-errors@mam.mff.cuni.cz'), ] diff --git a/seminar/models/base.py b/seminar/models/base.py index 77c857a3..1069f165 100644 --- a/seminar/models/base.py +++ b/seminar/models/base.py @@ -4,18 +4,18 @@ from django.db import models class SeminarModelBase(models.Model): - class Meta: - abstract = True + class Meta: + abstract = True - def verejne(self): - return False + def verejne(self): + return False - # def get_absolute_url(self): - # return "https://" + str(get_current_site(None)) + self.verejne_url() + # def get_absolute_url(self): + # return "https://" + str(get_current_site(None)) + self.verejne_url() - def admin_url(self): - model_name = self.__class__.__name__.lower() - return reverse('admin:seminar_{}_change'.format(model_name), args=(self.id, )) + def admin_url(self): + model_name = self.__class__.__name__.lower() + return reverse('admin:seminar_{}_change'.format(model_name), args=(self.id, )) # def verejne_url(self): # return None diff --git a/seminar/models/novinky.py b/seminar/models/novinky.py index f6ce4161..cee674a8 100644 --- a/seminar/models/novinky.py +++ b/seminar/models/novinky.py @@ -9,30 +9,30 @@ from . import personalni as pm @reversion.register(ignore_duplicates=True) class Novinky(models.Model): - class Meta: - verbose_name = 'Novinka' - verbose_name_plural = 'Novinky' - ordering = ['-datum'] + class Meta: + verbose_name = 'Novinka' + verbose_name_plural = 'Novinky' + ordering = ['-datum'] - datum = models.DateField(auto_now_add=True) + datum = models.DateField(auto_now_add=True) - text = models.TextField('Text novinky', blank=True, null=True) - obrazek = models.ImageField('Obrázek', upload_to='image_novinky/%Y/%m/%d/', - null=True, blank=True) + text = models.TextField('Text novinky', blank=True, null=True) + obrazek = models.ImageField('Obrázek', upload_to='image_novinky/%Y/%m/%d/', + null=True, blank=True) - obrazek_maly = ImageSpecField(source='obrazek', - processors=[ - ResizeToFit(350, 200, upscale=False) - ], - options={'quality': 95}) + obrazek_maly = ImageSpecField(source='obrazek', + processors=[ + ResizeToFit(350, 200, upscale=False) + ], + options={'quality': 95}) - autor = models.ForeignKey(pm.Organizator, verbose_name='Autor novinky', null=True, - on_delete=models.SET_NULL) + autor = models.ForeignKey(pm.Organizator, verbose_name='Autor novinky', null=True, + on_delete=models.SET_NULL) - zverejneno = models.BooleanField('Zveřejněno', default=False) + zverejneno = models.BooleanField('Zveřejněno', default=False) - def __str__(self): - if self.text: - return '[' + str(self.datum) + '] ' + self.text[0:50] - else: - return '[' + str(self.datum) + '] ' + def __str__(self): + if self.text: + return '[' + str(self.datum) + '] ' + self.text[0:50] + else: + return '[' + str(self.datum) + '] ' diff --git a/seminar/models/odevzdavatko.py b/seminar/models/odevzdavatko.py index 9ae161c5..c286558c 100644 --- a/seminar/models/odevzdavatko.py +++ b/seminar/models/odevzdavatko.py @@ -18,68 +18,68 @@ from seminar.models import base as bm @reversion.register(ignore_duplicates=True) class Reseni(bm.SeminarModelBase): - class Meta: - db_table = 'seminar_reseni' - verbose_name = 'Řešení' - verbose_name_plural = 'Řešení' - #ordering = ['-problem', 'resitele'] # FIXME: Takhle to chceme, ale nefunguje to. - ordering = ['-cas_doruceni'] + class Meta: + db_table = 'seminar_reseni' + verbose_name = 'Řešení' + verbose_name_plural = 'Řešení' + #ordering = ['-problem', 'resitele'] # FIXME: Takhle to chceme, ale nefunguje to. + ordering = ['-cas_doruceni'] - # Interní ID - id = models.AutoField(primary_key = True) + # Interní ID + id = models.AutoField(primary_key = True) - # Ke každé dvojici řešní a problém existuje nanejvýš jedno hodnocení, doplnění vazby. - problem = models.ManyToManyField(am.Problem, verbose_name='problém', help_text='Problém', - through='Hodnoceni') + # Ke každé dvojici řešní a problém existuje nanejvýš jedno hodnocení, doplnění vazby. + problem = models.ManyToManyField(am.Problem, verbose_name='problém', help_text='Problém', + through='Hodnoceni') - resitele = models.ManyToManyField(pm.Resitel, verbose_name='autoři řešení', - help_text='Seznam autorů řešení', through='Reseni_Resitele') + resitele = models.ManyToManyField(pm.Resitel, verbose_name='autoři řešení', + help_text='Seznam autorů řešení', through='Reseni_Resitele') - cas_doruceni = models.DateTimeField('čas_doručení', default=timezone.now, blank=True) + cas_doruceni = models.DateTimeField('čas_doručení', default=timezone.now, blank=True) - FORMA_PAPIR = 'papir' - FORMA_EMAIL = 'email' - FORMA_UPLOAD = 'upload' - FORMA_CHOICES = [ - (FORMA_PAPIR, 'Papírové řešení'), - (FORMA_EMAIL, 'Emailem'), - (FORMA_UPLOAD, 'Upload přes web'), - ] - forma = models.CharField('forma řešení', max_length=16, choices=FORMA_CHOICES, blank=False, - default=FORMA_EMAIL) + FORMA_PAPIR = 'papir' + FORMA_EMAIL = 'email' + FORMA_UPLOAD = 'upload' + FORMA_CHOICES = [ + (FORMA_PAPIR, 'Papírové řešení'), + (FORMA_EMAIL, 'Emailem'), + (FORMA_UPLOAD, 'Upload přes web'), + ] + forma = models.CharField('forma řešení', max_length=16, choices=FORMA_CHOICES, blank=False, + default=FORMA_EMAIL) - text_cely = models.OneToOneField('ReseniNode', verbose_name='Plná verze textu řešení', - blank=True, null=True, related_name="reseni_cely_set", - on_delete=models.PROTECT) + text_cely = models.OneToOneField('ReseniNode', verbose_name='Plná verze textu řešení', + blank=True, null=True, related_name="reseni_cely_set", + on_delete=models.PROTECT) - poznamka = models.TextField('neveřejná poznámka', blank=True, - help_text='Neveřejná poznámka k řešení (plain text)') + poznamka = models.TextField('neveřejná poznámka', blank=True, + help_text='Neveřejná poznámka k řešení (plain text)') - zverejneno = models.BooleanField('řešení zveřejněno', default=False, - help_text='Udává, zda je řešení zveřejněno') + zverejneno = models.BooleanField('řešení zveřejněno', default=False, + help_text='Udává, zda je řešení zveřejněno') - def verejne_url(self): - return str(reverse_lazy('odevzdavatko_detail_reseni', args=[self.id])) + def verejne_url(self): + return str(reverse_lazy('odevzdavatko_detail_reseni', args=[self.id])) - def absolute_url(self): - return "https://" + str(get_current_site(None)) + self.verejne_url() + def absolute_url(self): + return "https://" + str(get_current_site(None)) + self.verejne_url() - # má OneToOneField s: - # Konfera + # má OneToOneField s: + # Konfera - # má ForeignKey s: - # Hodnoceni + # má ForeignKey s: + # Hodnoceni - def sum_body(self): - return self.hodnoceni_set.all().aggregate(Sum('body'))["body__sum"] + def sum_body(self): + return self.hodnoceni_set.all().aggregate(Sum('body'))["body__sum"] - def __str__(self): - return "{}({}): {}({})".format(self.resitele.first(),len(self.resitele.all()), self.problem.first() ,len(self.problem.all())) - # NOTE: Potenciální DB HOG (bez select_related) + def __str__(self): + return "{}({}): {}({})".format(self.resitele.first(),len(self.resitele.all()), self.problem.first() ,len(self.problem.all())) + # NOTE: Potenciální DB HOG (bez select_related) - def deadline_reseni(self): - return am.Deadline.objects.filter(deadline__gte=self.cas_doruceni).order_by("deadline").first() + def deadline_reseni(self): + return am.Deadline.objects.filter(deadline__gte=self.cas_doruceni).order_by("deadline").first() ## Pravdepodobne uz nebude potreba: # def save(self, *args, **kwargs): @@ -89,112 +89,112 @@ class Reseni(bm.SeminarModelBase): # super(Reseni, self).save(*args, **kwargs) class Hodnoceni(bm.SeminarModelBase): - class Meta: - db_table = 'seminar_hodnoceni' - verbose_name = 'Hodnocení' - verbose_name_plural = 'Hodnocení' + class Meta: + db_table = 'seminar_hodnoceni' + verbose_name = 'Hodnocení' + verbose_name_plural = 'Hodnocení' - # Interní ID - id = models.AutoField(primary_key = True) + # Interní ID + id = models.AutoField(primary_key = True) - body = models.DecimalField(max_digits=8, decimal_places=1, verbose_name='body', - blank=True, null=True) + body = models.DecimalField(max_digits=8, decimal_places=1, verbose_name='body', + blank=True, null=True) - cislo_body = models.ForeignKey(am.Cislo, verbose_name='číslo pro body', - related_name='hodnoceni', blank=True, null=True, on_delete=models.PROTECT) + cislo_body = models.ForeignKey(am.Cislo, verbose_name='číslo pro body', + related_name='hodnoceni', blank=True, null=True, on_delete=models.PROTECT) - # V ročníku < 26 nastaveno na deadline vygenerovaný pro původní cislo_body - deadline_body = models.ForeignKey(am.Deadline, verbose_name='deadline pro body', - related_name='hodnoceni', blank=True, null=True, on_delete=models.PROTECT) + # V ročníku < 26 nastaveno na deadline vygenerovaný pro původní cislo_body + deadline_body = models.ForeignKey(am.Deadline, verbose_name='deadline pro body', + related_name='hodnoceni', blank=True, null=True, on_delete=models.PROTECT) - reseni = models.ForeignKey(Reseni, verbose_name='řešení', on_delete=models.CASCADE) + reseni = models.ForeignKey(Reseni, verbose_name='řešení', on_delete=models.CASCADE) - problem = models.ForeignKey(am.Problem, verbose_name='problém', - related_name='hodnoceni', on_delete=models.PROTECT) + problem = models.ForeignKey(am.Problem, verbose_name='problém', + related_name='hodnoceni', on_delete=models.PROTECT) - feedback = models.TextField('zpětná vazba', blank=True, default='', help_text='Zpětná vazba řešiteli (plain text)') + feedback = models.TextField('zpětná vazba', blank=True, default='', help_text='Zpětná vazba řešiteli (plain text)') - def __str__(self): - return "{}, {}, {}".format(self.problem, self.reseni, self.body) + def __str__(self): + return "{}, {}, {}".format(self.problem, self.reseni, self.body) def generate_filename(self, filename): - return os.path.join( - settings.SEMINAR_RESENI_DIR, - am.aux_generate_filename(self, filename) - ) + return os.path.join( + settings.SEMINAR_RESENI_DIR, + am.aux_generate_filename(self, filename) + ) @reversion.register(ignore_duplicates=True) class PrilohaReseni(bm.SeminarModelBase): - class Meta: - db_table = 'seminar_priloha_reseni' - verbose_name = 'Příloha řešení' - verbose_name_plural = 'Přílohy řešení' - ordering = ['reseni', 'vytvoreno'] + class Meta: + db_table = 'seminar_priloha_reseni' + verbose_name = 'Příloha řešení' + verbose_name_plural = 'Přílohy řešení' + ordering = ['reseni', 'vytvoreno'] - # Interní ID - id = models.AutoField(primary_key = True) + # Interní ID + id = models.AutoField(primary_key = True) - reseni = models.ForeignKey(Reseni, verbose_name='řešení', related_name='prilohy', - on_delete=models.CASCADE) + reseni = models.ForeignKey(Reseni, verbose_name='řešení', related_name='prilohy', + on_delete=models.CASCADE) - vytvoreno = models.DateTimeField('vytvořeno', default=timezone.now, blank=True, editable=False) + vytvoreno = models.DateTimeField('vytvořeno', default=timezone.now, blank=True, editable=False) - soubor = models.FileField('soubor', upload_to = generate_filename) + soubor = models.FileField('soubor', upload_to = generate_filename) - poznamka = models.TextField('neveřejná poznámka', blank=True, - help_text='Neveřejná poznámka k příloze řešení (plain text), např. o původu') + poznamka = models.TextField('neveřejná poznámka', blank=True, + help_text='Neveřejná poznámka k příloze řešení (plain text), např. o původu') - res_poznamka = models.TextField('poznámka řešitele', blank=True, - help_text='Poznámka k příloze řešení, např. co daný soubor obsahuje') + res_poznamka = models.TextField('poznámka řešitele', blank=True, + help_text='Poznámka k příloze řešení, např. co daný soubor obsahuje') - def __str__(self): - return str(self.soubor) + def __str__(self): + return str(self.soubor) - def split(self): - "Vrátí cestu rozsekanou po složkách. To se hodí v templatech" - # Věřím, že tohle funguje, případně použít os.path nebo pathlib. - return self.soubor.url.split('/') + def split(self): + "Vrátí cestu rozsekanou po složkách. To se hodí v templatech" + # Věřím, že tohle funguje, případně použít os.path nebo pathlib. + return self.soubor.url.split('/') # Vazebna tabulka. Mozna se generuje automaticky. @reversion.register(ignore_duplicates=True) class Reseni_Resitele(models.Model): - class Meta: - db_table = 'seminar_reseni_resitele' - verbose_name = 'Řešení řešitelů' - verbose_name_plural = 'Řešení řešitelů' - ordering = ['reseni', 'resitele'] + class Meta: + db_table = 'seminar_reseni_resitele' + verbose_name = 'Řešení řešitelů' + verbose_name_plural = 'Řešení řešitelů' + ordering = ['reseni', 'resitele'] - # Interní ID - id = models.AutoField(primary_key = True) + # Interní ID + id = models.AutoField(primary_key = True) - resitele = models.ForeignKey(pm.Resitel, verbose_name='řešitel', on_delete=models.PROTECT) + resitele = models.ForeignKey(pm.Resitel, verbose_name='řešitel', on_delete=models.PROTECT) - reseni = models.ForeignKey(Reseni, verbose_name='řešení', on_delete=models.CASCADE) + reseni = models.ForeignKey(Reseni, verbose_name='řešení', on_delete=models.CASCADE) - # podil - jakou merou se ktery resitel podilel na danem reseni - # - pouziti v budoucnu, pokud by resitele nemeli dostat vsichni stejne bodu za spolecne reseni + # podil - jakou merou se ktery resitel podilel na danem reseni + # - pouziti v budoucnu, pokud by resitele nemeli dostat vsichni stejne bodu za spolecne reseni - def __str__(self): - return '{} od {}'.format(self.reseni, self.resitel) - # NOTE: Poteciální DB HOG bez select_related + def __str__(self): + return '{} od {}'.format(self.reseni, self.resitel) + # NOTE: Poteciální DB HOG bez select_related class ReseniNode(tm.TreeNode): - class Meta: - db_table = 'seminar_nodes_otistene_reseni' - verbose_name = 'Otištěné řešení (Node)' - verbose_name_plural = 'Otištěná řešení (Node)' - reseni = models.ForeignKey(Reseni, - on_delete=models.PROTECT, - verbose_name = 'reseni') - - def aktualizuj_nazev(self): - self.nazev = "ReseniNode: "+str(self.reseni) - - def getOdkazStr(self): - return str(self.reseni) + class Meta: + db_table = 'seminar_nodes_otistene_reseni' + verbose_name = 'Otištěné řešení (Node)' + verbose_name_plural = 'Otištěná řešení (Node)' + reseni = models.ForeignKey(Reseni, + on_delete=models.PROTECT, + verbose_name = 'reseni') + + def aktualizuj_nazev(self): + self.nazev = "ReseniNode: "+str(self.reseni) + + def getOdkazStr(self): + return str(self.reseni) diff --git a/soustredeni/admin.py b/soustredeni/admin.py index 11cb8d1d..091f9c59 100644 --- a/soustredeni/admin.py +++ b/soustredeni/admin.py @@ -6,38 +6,38 @@ from seminar.models import soustredeni as m class SoustredeniUcastniciInline(admin.TabularInline): - model = m.Soustredeni_Ucastnici - extra = 1 - fields = ['resitel','poznamka'] - autocomplete_fields = ['resitel'] - ordering = ['resitel__osoba__jmeno', 'resitel__osoba__prijmeni'] - formfield_overrides = { - models.TextField: {'widget': widgets.TextInput} - } + model = m.Soustredeni_Ucastnici + extra = 1 + fields = ['resitel','poznamka'] + autocomplete_fields = ['resitel'] + ordering = ['resitel__osoba__jmeno', 'resitel__osoba__prijmeni'] + formfield_overrides = { + models.TextField: {'widget': widgets.TextInput} + } - def get_queryset(self,request): - qs = super().get_queryset(request) - return qs.select_related('resitel','soustredeni') + def get_queryset(self,request): + qs = super().get_queryset(request) + return qs.select_related('resitel','soustredeni') class SoustredeniOrganizatoriInline(admin.TabularInline): - model = m.Soustredeni.organizatori.through - extra = 1 - fields = ['organizator','poznamka'] - autocomplete_fields = ['organizator'] - ordering = ['organizator__osoba__jmeno','organizator__prijmeni'] - formfield_overrides = { - models.TextField: {'widget': widgets.TextInput} - } + model = m.Soustredeni.organizatori.through + extra = 1 + fields = ['organizator','poznamka'] + autocomplete_fields = ['organizator'] + ordering = ['organizator__osoba__jmeno','organizator__prijmeni'] + formfield_overrides = { + models.TextField: {'widget': widgets.TextInput} + } - def get_queryset(self,request): - qs = super().get_queryset(request) - return qs.select_related('organizator', 'soustredeni') + def get_queryset(self,request): + qs = super().get_queryset(request) + return qs.select_related('organizator', 'soustredeni') @admin.register(m.Soustredeni) class SoustredeniAdmin(admin.ModelAdmin): - model = m.Soustredeni - inline_type = 'tabular' - inlines = [SoustredeniUcastniciInline, SoustredeniOrganizatoriInline] + model = m.Soustredeni + inline_type = 'tabular' + inlines = [SoustredeniUcastniciInline, SoustredeniOrganizatoriInline] diff --git a/treenode/admin.py b/treenode/admin.py index d2ff4409..92c85cd5 100644 --- a/treenode/admin.py +++ b/treenode/admin.py @@ -9,80 +9,80 @@ import seminar.models as m @admin.register(m.TreeNode) class TreeNodeAdmin(PolymorphicParentModelAdmin): - base_model = m.TreeNode - child_models = [ - m.RocnikNode, - m.CisloNode, - m.MezicisloNode, - m.TemaVCisleNode, - m.UlohaZadaniNode, - m.PohadkaNode, - m.UlohaVzorakNode, - m.TextNode, - m.CastNode, - m.OrgTextNode, - ] - - actions = ['aktualizuj_nazvy'] - - # XXX: nejspíš je to totální DB HOG, nechcete to použít moc často. - def aktualizuj_nazvy(self, request, queryset): - newqs = queryset.get_real_instances() - for tn in newqs: - tn.aktualizuj_nazev() - tn.save() - self.message_user(request, "Názvy aktualizovány.") - aktualizuj_nazvy.short_description = "Aktualizuj vybraným TreeNodům názvy" + base_model = m.TreeNode + child_models = [ + m.RocnikNode, + m.CisloNode, + m.MezicisloNode, + m.TemaVCisleNode, + m.UlohaZadaniNode, + m.PohadkaNode, + m.UlohaVzorakNode, + m.TextNode, + m.CastNode, + m.OrgTextNode, + ] + + actions = ['aktualizuj_nazvy'] + + # XXX: nejspíš je to totální DB HOG, nechcete to použít moc často. + def aktualizuj_nazvy(self, request, queryset): + newqs = queryset.get_real_instances() + for tn in newqs: + tn.aktualizuj_nazev() + tn.save() + self.message_user(request, "Názvy aktualizovány.") + aktualizuj_nazvy.short_description = "Aktualizuj vybraným TreeNodům názvy" @admin.register(m.RocnikNode) class RocnikNodeAdmin(PolymorphicChildModelAdmin): - base_model = m.RocnikNode - show_in_index = True + base_model = m.RocnikNode + show_in_index = True @admin.register(m.CisloNode) class CisloNodeAdmin(PolymorphicChildModelAdmin): - base_model = m.CisloNode - show_in_index = True + base_model = m.CisloNode + show_in_index = True @admin.register(m.MezicisloNode) class MezicisloNodeAdmin(PolymorphicChildModelAdmin): - base_model = m.MezicisloNode - show_in_index = True + base_model = m.MezicisloNode + show_in_index = True @admin.register(m.TemaVCisleNode) class TemaVCisleNodeAdmin(PolymorphicChildModelAdmin): - base_model = m.TemaVCisleNode - show_in_index = True + base_model = m.TemaVCisleNode + show_in_index = True @admin.register(m.UlohaZadaniNode) class UlohaZadaniNodeAdmin(PolymorphicChildModelAdmin): - base_model = m.UlohaZadaniNode - show_in_index = True + base_model = m.UlohaZadaniNode + show_in_index = True @admin.register(m.PohadkaNode) class PohadkaNodeAdmin(PolymorphicChildModelAdmin): - base_model = m.PohadkaNode - show_in_index = True + base_model = m.PohadkaNode + show_in_index = True @admin.register(m.UlohaVzorakNode) class UlohaVzorakNodeAdmin(PolymorphicChildModelAdmin): - base_model = m.UlohaVzorakNode - show_in_index = True + base_model = m.UlohaVzorakNode + show_in_index = True @admin.register(m.TextNode) class TextNodeAdmin(PolymorphicChildModelAdmin): - base_model = m.TextNode - show_in_index = True + base_model = m.TextNode + show_in_index = True @admin.register(m.CastNode) class TextNodeAdmin(PolymorphicChildModelAdmin): - base_model = m.CastNode - show_in_index = True - fields = ('nadpis',) + base_model = m.CastNode + show_in_index = True + fields = ('nadpis',) @admin.register(m.OrgTextNode) class TextNodeAdmin(PolymorphicChildModelAdmin): - base_model = m.OrgTextNode - show_in_index = True + base_model = m.OrgTextNode + show_in_index = True diff --git a/treenode/permissions.py b/treenode/permissions.py index 5503832f..bc5c68a8 100644 --- a/treenode/permissions.py +++ b/treenode/permissions.py @@ -2,6 +2,6 @@ from rest_framework.permissions import BasePermission class AllowWrite(BasePermission): - def has_permission(self, request, view): - return request.user.has_perm('auth.org') + def has_permission(self, request, view): + return request.user.has_perm('auth.org') diff --git a/various/autentizace/utils.py b/various/autentizace/utils.py index 2341fbdd..d8bea060 100644 --- a/various/autentizace/utils.py +++ b/various/autentizace/utils.py @@ -6,16 +6,16 @@ from django.utils.http import urlsafe_base64_encode def posli_reset_hesla(u, request=None): - uid = urlsafe_base64_encode(force_bytes(u.pk)) - token = PasswordResetTokenGenerator().make_token(u) - url = "https://%s%s" % ( - str(get_current_site(request)), - str(reverse_lazy("reset_password_confirm", args=[uid, token])) - ) + uid = urlsafe_base64_encode(force_bytes(u.pk)) + token = PasswordResetTokenGenerator().make_token(u) + url = "https://%s%s" % ( + str(get_current_site(request)), + str(reverse_lazy("reset_password_confirm", args=[uid, token])) + ) - u.email_user( - subject="Vítej mezi řešiteli M&M!", - message="""Milý řešiteli, milá řešitelko, + u.email_user( + subject="Vítej mezi řešiteli M&M!", + message="""Milý řešiteli, milá řešitelko, tvůj e-mail byl právě zaregistrován na mam.matfyz.cz. Heslo si prosím nastav na: %s @@ -26,6 +26,6 @@ Organizátoři M&M Tento e-mail byl vygenerován automaticky, chceš-li nás kontaktovat, napiš nám na adresu mam@matfyz.cz. """ % url, - # TODO: templates/autentizace a django/contrib/auth/forms.py říkají, jak na to lépe - from_email="registrace@mam.mff.cuni.cz", # FIXME: Chceme to mít radši tady, nebo v nastavení? - ) \ No newline at end of file + # TODO: templates/autentizace a django/contrib/auth/forms.py říkají, jak na to lépe + from_email="registrace@mam.mff.cuni.cz", # FIXME: Chceme to mít radši tady, nebo v nastavení? + ) \ No newline at end of file diff --git a/various/log_filters.py b/various/log_filters.py index f20e032c..f037dcde 100644 --- a/various/log_filters.py +++ b/various/log_filters.py @@ -2,10 +2,10 @@ from logging import Filter, INFO from django.urls import reverse class Http404AsInfoFilter(Filter): - def filter(self, record): - if record.name == 'django.request' and record.status_code == 404: - record.levelno = INFO - return 1 # Keep the log record + def filter(self, record): + if record.name == 'django.request' and record.status_code == 404: + record.levelno = INFO + return 1 # Keep the log record class StripSensitiveFormDataFilter(Filter): def filter(self, record):