Ejemplo n.º 1
0
def age_group_details(request, country_id=None, gender_code=None, age=None, distance_code=None, is_indoor=None):
	if request.method == 'POST':
		return redirect('results:age_group_record_details',
			country_id=request.POST.get('country_id', 'RU'),
			gender_code=results_util.GENDER_CODES[results_util.int_safe(request.POST.get('gender', models.GENDER_MALE))],
			age=request.POST.get('age', 0),
			distance_code=results_util.DISTANCE_CODES[results_util.int_safe(request.POST.get('distance_id', results_util.DIST_MARATHON_ID))],
			is_indoor=request.POST.get('is_indoor', 0),
		)

	country = get_object_or_404(models.Country, pk=country_id, pk__in=results_util.THREE_COUNTRY_IDS)
	gender = results_util.GENDER_CODES_INV.get(gender_code)
	if not gender:
		raise Http404()
	age_min = None if (age == '0') else age
	age_group = get_object_or_404(models.Record_age_group, age_min=age_min)

	distance_id = results_util.DISTANCE_CODES_INV.get(distance_code)
	distance = get_object_or_404(models.Distance, pk=distance_id, pk__in=results_util.DISTANCES_FOR_COUNTRY_RECORDS)
	is_indoor = (is_indoor == '1')

	context = user_edit_vars(request.user)
	context['country'] = country
	context['form'] = forms.AgeGroupRecordForm(initial={
			'country_id': country.id,
			'distance_id': distance.id,
			'gender': gender,
			'age': age_group.age_min if age_group.age_min else 0,
		})

	records = age_group.record_result_set.filter(country=country, gender=gender, distance=distance, is_indoor=is_indoor).select_related(
		'result__race__event__series__city__region__country', 'result__race__event__city__region__country',
		'result__runner__user__user_profile', 'result__runner__city__region__country', 'result__result_on_strava')
	context['results_best_overall'] = records.exclude(cur_place=None).order_by('cur_place')
	context['old_records'] = records.filter(was_record_ever=True).exclude(cur_place=1).order_by('-date')

	context['has_shatilo_results'] = context['results_best_overall'].filter(is_from_shatilo=True).exists() \
		or context['old_records'].filter(is_from_shatilo=True).exists()

	if context['is_admin']:
		context['other_results'] = records.filter(was_record_ever=False, cur_place=None).order_by('-result__race__event__start_date')
		context['has_shatilo_results'] = context['has_shatilo_results'] or context['other_results'].filter(is_from_shatilo=True).exists()
		context['update_records_link'] = reverse('editor:update_age_group_records', kwargs={'country_id': country_id, 'gender_code': gender_code,
			'age': age, 'distance_code': distance_code, 'is_indoor': 1 if is_indoor else 0})
		context['generate_records_link'] = reverse('editor:generate_better_age_group_results_for_tuple',
			kwargs={'country_id': country_id, 'gender_code': gender_code,
				'age': age, 'distance_code': distance_code, 'is_indoor': 1 if is_indoor else 0})

	context['page_title_first'] = u'Рекорды {}'.format(country.prep_case)
	context['page_title_second'] = u'{} на дистанции {}{}'.format(
			age_group.get_full_name_in_prep_case(gender),
			distance.name,
			u' в закрытых помещениях' if is_indoor else '',
		)
	context['page_title'] = context['page_title_first'] + context['page_title_second']
	return render(request, 'age_group_records/age_group_details.html', context)
Ejemplo n.º 2
0
def runners_list(request, runner_id=None, race_id=None):
	results = []
	user = request.user
	query = request.GET.get('query', '').strip()
	runners = models.Runner.objects.select_related('city__region__country')
	if len(query) >= MIN_QUERY_LENGTH:
		if models.is_admin(user):
			query_as_number = results_util.int_safe(query)
			if query_as_number:
				runners = runners.filter(pk=query_as_number)
			else:
				runners = filter_by_name(runners, query)

			if runner_id: # When merging runner with id=runner_id with other runner
				runners = runners.exclude(pk=runner_id)
			elif race_id: # When choosing only runners without results on current race
				race = models.Race.objects.filter(pk=race_id).first()
				if race:
					runners_in_race = set(race.result_set.values_list('runner_id', flat=True))
					runners = runners.exclude(pk__in=runners_in_race)
		elif user.club_editor_set.exists(): # When club manager wants to enter club members' unofficial results
			runners = filter_by_name(runners.filter(pk__in=models.get_runner_ids_for_user(user)), query)
		for runner in runners.order_by('lname', 'fname', 'birthday')[:(2 * MAX_ENTRIES)]:
			results.append({
				'id': runner.id,
				'text': runner.get_name_for_ajax_select(),
			})
	res = json.dumps(results)
	return HttpResponse(res, content_type='application/json')
Ejemplo n.º 3
0
def update_series_results(series, user, reverse_races=False):
    new_races = []
    # print "Trying to read url {}".format(series.url_site + '/results/eventhistory/')
    url_history = series.url_site + '/results/eventhistory/'
    result, response, _ = results_util.read_url(url_history)
    if not result:
        models.send_panic_email(
            'views_parkrun: update_series_results: problem with event history',
            u"Couldn't load event history for {}, id={}, from url {}".format(
                series.name, series.id, url_history))
        return []
    html = response.read().decode('utf-8')
    new_races_created = False
    parts = parkrun_result_history_re.findall(html)
    if reverse_races:
        parts.reverse()

    runners_touched = set()
    for item in parts:
        url_event, event_num, ev_day, ev_month, ev_year, n_runners = item
        event_date = datetime.date(results_util.int_safe(ev_year),
                                   results_util.int_safe(ev_month),
                                   results_util.int_safe(ev_day))
        url_results = series.url_site + '/results' + url_event[2:]
        existed, race = get_or_create_parkrun_event_and_race(
            series, url_results, event_date, results_util.int_safe(event_num),
            user)
        if race.loaded != models.RESULTS_LOADED:
            models.write_log(u"New event found: {}".format(item))
            n_results, new_runners_touched = load_race_results(
                race, url_results, user)
            runners_touched |= new_runners_touched
            new_races.append((race, n_results, existed))
            if not existed:
                new_races_created = True
        elif not reverse_races:
            if new_races_created:  # Maybe there were some extra parkruns, e.g. for New Year/Christmas
                fix_parkrun_numbers(race.event_id)
            break
    for runner in runners_touched:
        update_runner_stat(runner=runner)
        if runner.user:
            update_runner_stat(user=runner.user, update_club_members=False)
    return new_races, runners_touched
Ejemplo n.º 4
0
def records_for_distance(request, country_id, distance_code, is_indoor=False):
	if request.method == 'POST':
		kwargs = {}
		if is_indoor:
			kwargs['is_indoor'] = 1
		return redirect('results:age_group_records_for_distance',
			country_id=request.POST.get('country_id', 'RU'),
			distance_code=results_util.DISTANCE_CODES[results_util.int_safe(request.POST.get('distance_id', results_util.DIST_MARATHON_ID))],
			**kwargs
		)

	country = get_object_or_404(models.Country, pk=country_id, pk__in=results_util.THREE_COUNTRY_IDS)
	distance_id = results_util.DISTANCE_CODES_INV.get(distance_code)
	distance = get_object_or_404(models.Distance, pk=distance_id, pk__in=results_util.DISTANCES_FOR_COUNTRY_RECORDS)
	is_indoor = (is_indoor == '1')

	context = user_edit_vars(request.user)
	distance_name = u'марафоне'
	context['page_title_first'] = u'Рекорды в возрастных группах в {}'.format(country.prep_case)
	context['page_title_second'] = u': {}{}'.format(distance.name, u' в закрытых помещениях' if is_indoor else '')
	context['page_title'] = context['page_title_first'] + context['page_title_second']
	context['country'] = country

	context['form'] = forms.AgeGroupRecordsForDistanceForm(initial={
			'country_id': country.id,
			'distance_id': distance.id,
		})

	data = OrderedDict()
	for age_group in models.Record_age_group.objects.exclude(age_group_type=models.RECORD_AGE_GROUP_TYPE_YOUNG).order_by('age_min'):
		data[age_group] = {}

	records = country.record_result_set.filter(distance=distance, is_indoor=is_indoor, cur_place=1).exclude(
		age_group__age_group_type=models.RECORD_AGE_GROUP_TYPE_YOUNG).select_related(
		'result__race__event__series__city__region__country', 'result__race__event__city__region__country',
		'result__runner__user__user_profile', 'result__runner__city__region__country').order_by('age_group__age_min')
	for record in records:
		data[record.age_group][record.gender] = record
	context['records_by_age_group'] = data
	return render(request, 'age_group_records/records_for_distance.html', context)
Ejemplo n.º 5
0
def add_review(request):
    context = {}
    message_text = ''
    res = {}
    res['success'] = 0
    if request.method == 'POST':
        user = request.user
        form = forms.AddReviewForm(request.POST, request.FILES)
        if form.is_valid():
            event = get_object_or_404(models.Event,
                                      pk=form.cleaned_data['event_id'])
            attachment = request.FILES.get('attachment', None)
            doc_type = results_util.int_safe(form.cleaned_data['doc_type'])
            doc_type_name = u'отчёт' if doc_type == models.DOC_TYPE_IMPRESSIONS else u'фотоальбом'
            doc = models.Document.objects.create(
                event=event,
                document_type=doc_type,
                loaded_type=models.LOAD_TYPE_LOADED
                if attachment else models.LOAD_TYPE_NOT_LOADED,
                upload=attachment,
                url_original=form.cleaned_data['url'],
                author=form.cleaned_data['author'],
                created_by=user)
            models.log_obj_create(user,
                                  event,
                                  models.ACTION_DOCUMENT_CREATE,
                                  child_object=doc)
            doc.process_review_or_photo()
            generate_last_added_reviews()
            res['success'] = 1
            res['link'] = models.SITE_URL + event.get_absolute_url()

            if not models.is_admin(user):
                message_from_site = models.Message_from_site.objects.create(
                    sender_name=user.first_name + ' ' + user.last_name,
                    sender_email=models.ROBOT_MAIL_HEADER,
                    target_email=models.INFO_MAIL,
                    # target_email='*****@*****.**',
                    title=u'Добавлен новый {} к забегу {} ({})'.format(
                        doc_type_name, event.name,
                        event.date(with_nobr=False)),
                    attachment=attachment,
                )
                if attachment:
                    body = u'Только что пользователь {} ({}{}) добавил на сайт отчёт к забегу «{}»:\n\n {}/{}\n\n'.format(
                        user.get_full_name(), models.SITE_URL,
                        user.user_profile.get_absolute_url(), unicode(event),
                        models.SITE_URL_OLD, message_from_site.attachment.name)
                else:
                    body = u'Только что пользователь {} ({}{}) добавил на сайт ссылку на {} к забегу «{}»:\n{}\n\n'.format(
                        user.get_full_name(), models.SITE_URL,
                        user.user_profile.get_absolute_url(), doc_type_name,
                        unicode(event), form.cleaned_data['url'])
                body += u'Все документы забега: {}{}\n\n'.format(
                    models.SITE_URL, event.get_absolute_url())
                body += u'Успешных стартов!\nВаш робот'
                message_from_site.body = body
                message_from_site.save()
                message_from_site.try_send(attach_file=False)
        else:
            res['error'] = get_first_form_error(form)
    else:
        res['error'] = u'Запрос не получен.'
    return HttpResponse(json.dumps(res), content_type='application/json')
Ejemplo n.º 6
0
def load_race_results(race, url_results, user, load_only_russians=False):
    result, response, _ = results_util.read_url(url_results)
    if not result:
        models.write_log(
            u"Couldn't load results for parkrun {}, id={}, from url {}".format(
                race.event, race.event.id, url_results))
        return 0, set()
    html = response.read().decode('utf-8')
    race.result_set.filter(source=models.RESULT_SOURCE_DEFAULT).delete()
    results_added = 0
    runners_touched = set()

    category_sizes = {
        category_size.name: category_size
        for category_size in race.category_size_set.all()
    }
    category_lower_to_orig = {name.lower(): name for name in category_sizes}

    new_results = []

    for group in parkrun_result_re.finditer(html):
        groupdict = group.groupdict('')
        parkrun_id = results_util.int_safe(groupdict['parkrun_id'])
        lname, fname, midname = split_name(groupdict['name'].strip().title(),
                                           first_name_position=0)
        gender = models.string2gender(groupdict['gender'].strip())
        if gender == models.GENDER_UNKNOWN:
            models.send_panic_email(
                'views_parkrun: load_race_results: problem with gender',
                u"Problem with race id {}, url {} : gender '{}' cannot be parsed"
                .format(race.id, url_results, groupdict['gender']),
            )
        runner, created = models.Runner.objects.get_or_create(
            parkrun_id=parkrun_id,
            defaults={
                'lname': lname,
                'fname': fname,
                'gender': gender
            })

        centiseconds = models.string2centiseconds(groupdict['result'])
        if centiseconds == 0:
            models.send_panic_email(
                'views_parkrun: load_race_results: problem with time',
                u"Problem with race id {}, url {} : time '{}' cannot be parsed"
                .format(race.id, url_results, groupdict['result']),
            )

        category = groupdict['category']
        if category:
            category_lower = category.lower()
            if category_lower not in category_lower_to_orig:
                category_sizes[category] = models.Category_size.objects.create(
                    race=race, name=category)
                category_lower_to_orig[category_lower] = category

        new_results.append(
            models.Result(
                race=race,
                runner=runner,
                user=runner.user,
                parkrun_id=parkrun_id,
                name_raw=groupdict['name'],
                time_raw=groupdict['result'],
                club_raw=groupdict['club'],
                club_name=groupdict['club'],
                place_raw=results_util.int_safe(groupdict['place']),
                result=centiseconds,
                status=models.STATUS_FINISHED,
                status_raw=models.STATUS_FINISHED,
                category_size=category_sizes[
                    category_lower_to_orig[category_lower]]
                if category else None,
                category_raw=category,
                comment=groupdict['comment1'] + groupdict['comment2'],
                lname=lname,
                fname=fname,
                midname=midname,
                gender=gender,
                gender_raw=gender,
                loaded_by=user,
                loaded_from=url_results,
            ))
        runners_touched.add(runner)

    models.Result.objects.bulk_create(new_results)
    fill_places(race)
    fill_race_headers(race)
    if len(new_results) > 0:
        race.loaded = models.RESULTS_LOADED
        race.save()
    models.write_log(u"Race {}: {} results are loaded".format(
        race, len(new_results)))
    return len(new_results), runners_touched
Ejemplo n.º 7
0
def age_group_records_edit(request,
                           country_id=None,
                           gender_code=None,
                           distance_code=None,
                           is_indoor=None,
                           age=None):
    context = {}
    user = request.user

    country = get_object_or_404(models.Country,
                                pk=(country_id if country_id else 'RU'))
    is_indoor = (results_util.int_safe(is_indoor) > 0)
    gender = results_util.GENDER_CODES_INV.get(
        gender_code) if gender_code else models.GENDER_MALE
    if not gender:
        raise Http404()

    formset_params = {}
    formset_params['country'] = country
    formset_params['is_indoor'] = is_indoor
    formset_params['gender'] = gender

    distance = None
    if distance_code:
        distance_id = results_util.DISTANCE_CODES_INV.get(distance_code)
        distance = get_object_or_404(
            models.Distance,
            pk=distance_id,
            pk__in=results_util.DISTANCES_FOR_COUNTRY_RECORDS)
        formset_params['distance'] = distance
    if age is not None:
        age = results_util.int_safe(age)
        age_group = get_object_or_404(models.Record_age_group,
                                      age_min=age if age else None)
        formset_params['age_group'] = age_group
    formset_params['add_remaining_cur_leaders'] = (distance is not None) or (
        age is not None)

    if 'btnSubmitRecords' in request.POST:
        formset = getRecordResultFormSet(request,
                                         user,
                                         data=request.POST,
                                         **formset_params)
        if formset.is_valid():
            formset.save()
            for record in formset.new_objects:
                record.fill_and_save_if_needed()
            for record, changed_data in formset.changed_objects:
                record.fill_and_save_if_needed()

            messages.success(
                request,
                (u'{} рекордов добавлено, {} обновлено, {} удалено').format(
                    len(formset.new_objects), len(formset.changed_objects),
                    len(formset.deleted_objects)))
            return redirect('results:age_group_records')
        else:
            messages.warning(
                request,
                u'Рекорды не сохранены. Пожалуйста, исправьте ошибки в форме')
            context['errors'] = unicode(formset.errors)  # TODO: REMOVE
    else:
        formset = getRecordResultFormSet(request, user, **formset_params)

    if age == 0:
        context[
            'page_title'] = u'Редактирование абсолютных рекордов {}{} у {}'.format(
                formset_params['country'].prep_case,
                u' в закрытых помещениях' if is_indoor else u'', u'мужчин' if
                (gender == models.GENDER_MALE) else u'женщин')
    else:
        context['page_title'] = u'Редактирование рекордов в возрастных группах'
    context['formset'] = formset
    return render(request, 'editor/age_groups/age_group_records_edit.html',
                  context)
Ejemplo n.º 8
0
def add_possible_age_group_records(request):
    if request.method == 'POST':
        n_records_added = 0
        tuples_with_changed_records = set()
        for key, val in request.POST.items():
            if key.startswith("possible_result_"):
                possible_record_result_id = results_util.int_safe(
                    key[len("possible_result_"):])
                possible_record_result = models.Possible_record_result.objects.filter(
                    pk=possible_record_result_id).first()
                if possible_record_result is None:
                    messages.warning(
                        request, u'Возможный рекорд с id {} не найден'.format(
                            possible_record_result_id))
                elif models.Result_not_for_age_group_record.objects.filter(
                        country_id=possible_record_result.country_id,
                        age_group_id=possible_record_result.age_group_id,
                        result_id=possible_record_result.result_id).exists():
                    messages.warning(
                        request,
                        u'Возможный рекорд с id {} помечен как плохой. Не добавляем в рекорды'
                        .format(possible_record_result.id))
                elif models.Record_result.objects.filter(
                        country_id=possible_record_result.country_id,
                        age_group_id=possible_record_result.age_group_id,
                        result_id=possible_record_result.result_id).exists():
                    messages.warning(
                        request,
                        u'Возможный рекорд с id {} уже и так числится в рекордах. Удаляем с этой страницы'
                        .format(possible_record_result.id))
                    possible_record_result.delete()
                else:
                    record_result = models.Record_result.objects.create(
                        country_id=possible_record_result.country_id,
                        gender=possible_record_result.gender,
                        age_group_id=possible_record_result.age_group_id,
                        age_on_event_date=possible_record_result.
                        age_on_event_date,
                        distance_id=possible_record_result.distance_id,
                        is_indoor=possible_record_result.is_indoor,
                        value=possible_record_result.result.result,
                        runner=possible_record_result.result.runner,
                        result=possible_record_result.result,
                        race=possible_record_result.result.race,
                        created_by=request.user,
                    )
                    record_result.fill_and_save_if_needed()
                    n_records_added += 1
                    tuples_with_changed_records.add(
                        (record_result.country, record_result.gender,
                         record_result.age_group, record_result.distance,
                         record_result.is_indoor))
                    possible_record_result.delete()
        for tup in tuples_with_changed_records:
            update_records_for_given_tuple(*tup)
        if n_records_added > 0:
            messages.success(
                request,
                u'Добавлено результатов в рекорды в возрастных группах: {}'.
                format(n_records_added))
    return redirect('editor:better_age_group_results')