Source code for oioioi.timeline.views

import datetime
from collections import defaultdict
from operator import itemgetter  # pylint: disable=E0611

from django.conf import settings
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
from django.template.response import TemplateResponse
from django.urls import reverse
from django.utils import timezone
from django.utils.translation import gettext_lazy as _

from oioioi.base.permissions import enforce_condition
from oioioi.contests.date_registration import date_registry
from oioioi.contests.menu import contest_admin_menu_registry
from oioioi.contests.models import Round
from oioioi.contests.utils import contest_exists, is_contest_admin


[docs]def _get_date_id(registry_item): date_id = ( str(registry_item['model']._meta.verbose_name) + ":" + str(registry_item['id']) + ":" + str(registry_item['date_field']) ) return date_id.replace(' ', '_')
[docs]def _make_group_registry(registry): group_registry = defaultdict(list) for item in registry: item['type'] = None if item['model'] == Round: if item['date_field'] == 'start_date': item['type'] = 'start' elif item['date_field'] == 'end_date': item['type'] = 'end' round_id = getattr(item['round'], 'id', 0) round_name = getattr(item['round'], 'name', '') group_registry[round_id, round_name].append(item) return sorted(group_registry.items(), key=itemgetter(0))
[docs]def _translate_field(field, obj): if field == NON_FIELD_ERRORS: return None return obj._meta.get_field(field).verbose_name
@contest_admin_menu_registry.register_decorator( _("Timeline"), lambda request: reverse('timeline_view', kwargs={'contest_id': request.contest.id}), ) @enforce_condition(contest_exists & is_contest_admin)
[docs]def timeline_view(request): registry = date_registry.tolist(request.contest.id) group_registry = _make_group_registry(registry) for item in registry: item['date_id'] = _get_date_id(item) if request.POST: tosave = {} error_list = [] for item in registry: date = request.POST.get(item['date_id'], None) obj = item['model'].objects.get(pk=item['id']) if date: try: current_tz = timezone.get_current_timezone() dt = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M") parsed_date = dt.replace(tzinfo=current_tz) # parsed_date = current_tz.localize(dt) except ValueError: error_list.append( ( str(item['text']), {None: [_("Date format is invalid")]}, ) ) continue else: if not getattr(obj, item['date_field']): continue parsed_date = None item['date'] = parsed_date obj_str = str(item['model']) + str(item['id']) if obj_str in tosave: setattr(tosave[obj_str], item['date_field'], parsed_date) else: setattr(obj, item['date_field'], parsed_date) tosave[obj_str] = obj for obj in tosave.values(): try: obj.full_clean() except ValidationError as e: object_name = getattr(obj, 'name', None) if not object_name: object_name = '%s (%s)' % (obj._meta.verbose_name.title(), obj.id) message_dict = dict( (_translate_field(field, obj), value) for (field, value) in e.message_dict.items() ) error_list.append((object_name, message_dict)) if error_list: return TemplateResponse( request, 'timeline/timeline_view.html', { 'registry': group_registry, 'error_list': sorted(error_list), 'server_timezone': settings.TIME_ZONE, }, ) for obj in tosave.values(): obj.save() return TemplateResponse( request, 'timeline/timeline_view.html', {'registry': group_registry, 'server_timezone': settings.TIME_ZONE}, )