Enforce trailing commas

This commit is contained in:
Quantum 2019-09-28 17:17:05 -04:00 committed by Guanzhong Chen
parent 45c7d52101
commit cf9cf32236
44 changed files with 108 additions and 125 deletions

View File

@ -6,6 +6,7 @@ ignore =
W504, # line break occurred after a binary operator
# allow only generator_stop and annotations future imports
FI10,FI11,FI12,FI13,FI14,FI15,FI16,FI17,FI18,FI55,FI58,
C814, # missing trailing comma in Python 2 only
per-file-ignores =
# F401: unused imports, ignore in all __init__.py
# F403: import *

View File

@ -1,6 +1,6 @@
language: python
python: 3.7
install: pip install flake8 flake8-import-order flake8-future-import
install: pip install flake8 flake8-import-order flake8-future-import flake8-commas
script:
- flake8 --version
- flake8

View File

@ -28,5 +28,5 @@ logger = logging.getLogger('judge.celery')
@task_failure.connect()
def celery_failure_log(sender, task_id, exception, traceback, *args, **kwargs):
logger.exception('Celery Task {task_name}: {task_id} on {hostname}'.format(
task_name=sender.name, task_id=task_id, hostname=socket.gethostname()
task_name=sender.name, task_id=task_id, hostname=socket.gethostname(),
), exc_info=(type(exception), exception, traceback))

View File

@ -112,7 +112,7 @@ else:
'dashboard': {
'breadcrumbs': True,
},
}
},
}
INSTALLED_APPS += (
@ -239,7 +239,7 @@ TEMPLATES = [
'django.contrib.messages.context_processors.messages',
],
},
}
},
]
LOCALE_PATHS = [
@ -305,7 +305,7 @@ DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
},
}
ENABLE_FTS = False
@ -375,7 +375,7 @@ SOCIAL_AUTH_PIPELINE = (
'judge.social_auth.make_profile',
'social_core.pipeline.social_auth.associate_user',
'social_core.pipeline.social_auth.load_extra_data',
'social_core.pipeline.user.user_details'
'social_core.pipeline.user.user_details',
)
SOCIAL_AUTH_GITHUB_SECURE_SCOPE = ['user:email']

View File

@ -57,7 +57,7 @@ register_patterns = [
), name='auth_login'),
url(r'^logout/$', user.UserLogoutView.as_view(), name='auth_logout'),
url(r'^password/change/$', auth_views.PasswordChangeView.as_view(
template_name='registration/password_change_form.html'
template_name='registration/password_change_form.html',
), name='password_change'),
url(r'^password/change/done/$', auth_views.PasswordChangeDoneView.as_view(
template_name='registration/password_change_done.html',
@ -367,7 +367,7 @@ favicon_paths = ['apple-touch-icon-180x180.png', 'apple-touch-icon-114x114.png',
for favicon in favicon_paths:
urlpatterns.append(url(r'^%s$' % favicon, RedirectView.as_view(
url=lazystr(lambda: static('icons/' + favicon))
url=lazystr(lambda: static('icons/' + favicon)),
)))
handler404 = 'judge.views.error.error404'

View File

@ -18,7 +18,7 @@ else:
hub.wait(hub.loop.io(fd, 1))
MySQLdb.connect = MySQLdb.Connection = MySQLdb.Connect = wraps(MySQLdb.connect)(
partial(MySQLdb.connect, waiter=gevent_waiter)
partial(MySQLdb.connect, waiter=gevent_waiter),
)
from django.core.wsgi import get_wsgi_application # noqa: E402, I202, django must be imported here

View File

@ -171,7 +171,7 @@ class ContestAdmin(VersionAdmin):
return [
url(r'^rate/all/$', self.rate_all_view, name='judge_contest_rate_all'),
url(r'^(\d+)/rate/$', self.rate_view, name='judge_contest_rate'),
url(r'^(\d+)/judge/(\d+)/$', self.rejudge_view, name='judge_contest_rejudge')
url(r'^(\d+)/judge/(\d+)/$', self.rejudge_view, name='judge_contest_rejudge'),
] + super(ContestAdmin, self).get_urls()
def rejudge_view(self, request, contest_id, problem_id):
@ -228,7 +228,7 @@ class ContestAdmin(VersionAdmin):
form.base_fields['organizers'].queryset = Profile.objects.filter(
Q(user__is_superuser=True) |
Q(user__groups__permissions__codename__in=perms) |
Q(user__user_permissions__codename__in=perms)
Q(user__user_permissions__codename__in=perms),
).distinct()
return form
@ -253,7 +253,7 @@ class ContestParticipationAdmin(admin.ModelAdmin):
def get_queryset(self, request):
return super(ContestParticipationAdmin, self).get_queryset(request).only(
'contest__name', 'contest__format_name', 'contest__format_config',
'user__user__username', 'real_start', 'score', 'cumtime', 'virtual'
'user__user__username', 'real_start', 'score', 'cumtime', 'virtual',
)
def recalculate_results(self, request, queryset):

View File

@ -59,7 +59,7 @@ class BlogPostForm(ModelForm):
class BlogPostAdmin(VersionAdmin):
fieldsets = (
(None, {'fields': ('title', 'slug', 'authors', 'visible', 'sticky', 'publish_on')}),
(_('Content'), {'fields': ('content', 'og_image',)}),
(_('Content'), {'fields': ('content', 'og_image')}),
(_('Summary'), {'classes': ('collapse',), 'fields': ('summary',)}),
)
prepopulated_fields = {'slug': ('title',)}

View File

@ -25,7 +25,7 @@ class ProblemForm(ModelForm):
self.fields['testers'].widget.can_add_related = False
self.fields['banned_users'].widget.can_add_related = False
self.fields['change_message'].widget.attrs.update({
'placeholder': gettext('Describe the changes you made (optional)')
'placeholder': gettext('Describe the changes you made (optional)'),
})
class Meta:
@ -119,9 +119,8 @@ class ProblemAdmin(VersionAdmin):
(None, {
'fields': (
'code', 'name', 'is_public', 'is_manually_managed', 'date', 'authors', 'curators', 'testers',
'is_organization_private', 'organizations',
'description',
'license')
'is_organization_private', 'organizations', 'description', 'license',
),
}),
(_('Social Media'), {'classes': ('collapse',), 'fields': ('og_image', 'summary')}),
(_('Taxonomy'), {'fields': ('types', 'group')}),
@ -129,7 +128,7 @@ class ProblemAdmin(VersionAdmin):
(_('Limits'), {'fields': ('time_limit', 'memory_limit')}),
(_('Language'), {'fields': ('allowed_languages',)}),
(_('Justice'), {'fields': ('banned_users',)}),
(_('History'), {'fields': ('change_message',)})
(_('History'), {'fields': ('change_message',)}),
)
list_display = ['code', 'name', 'show_authors', 'points', 'is_public', 'show_public']
ordering = ['code']

View File

@ -87,7 +87,7 @@ class ContestSubmissionInline(admin.StackedInline):
def label(obj):
return pgettext('contest problem', '%(problem)s in %(contest)s') % {
'problem': obj.problem.name, 'contest': obj.contest.name
'problem': obj.problem.name, 'contest': obj.contest.name,
}
field = super(ContestSubmissionInline, self).formfield_for_dbfield(db_field, **kwargs)
if label is not None:
@ -123,7 +123,7 @@ class SubmissionAdmin(admin.ModelAdmin):
def get_queryset(self, request):
queryset = Submission.objects.select_related('problem', 'user__user', 'language').only(
'problem__code', 'problem__name', 'user__user__username', 'language__name',
'time', 'memory', 'points', 'status', 'result'
'time', 'memory', 'points', 'status', 'result',
)
use_straight_join(queryset)
if not request.user.has_perm('judge.edit_all_problem'):
@ -237,7 +237,7 @@ class SubmissionAdmin(admin.ModelAdmin):
def get_urls(self):
return [
url(r'^(\d+)/judge/$', self.judge_view, name='judge_submission_rejudge')
url(r'^(\d+)/judge/$', self.judge_view, name='judge_submission_rejudge'),
] + super(SubmissionAdmin, self).get_urls()
def judge_view(self, request, id):

View File

@ -67,7 +67,7 @@ class DjangoJudgeHandler(JudgeHandler):
logger.error('Submission vanished: %d', submission)
json_log.error(self._make_json_log(
sub=self._working, action='request',
info='submission vanished when fetching info'
info='submission vanished when fetching info',
))
return
@ -136,7 +136,7 @@ class DjangoJudgeHandler(JudgeHandler):
else:
self._submission_cache = data = Submission.objects.filter(id=id).values(
'problem__is_public', 'contest__participation__contest__key',
'user_id', 'problem_id', 'status', 'language__key'
'user_id', 'problem_id', 'status', 'language__key',
).get()
self._submission_cache_id = id
@ -238,7 +238,7 @@ class DjangoJudgeHandler(JudgeHandler):
packet, action='grading-end', time=time, memory=memory,
points=sub_points, total=problem.points, result=submission.result,
case_points=points, case_total=total, user=submission.user_id,
problem=problem.code, finish=True
problem=problem.code, finish=True,
))
submission.user._updating_stats_only = True
@ -255,7 +255,7 @@ class DjangoJudgeHandler(JudgeHandler):
'memory': memory,
'points': float(points),
'total': float(problem.points),
'result': submission.result
'result': submission.result,
})
if hasattr(submission, 'contest'):
participation = submission.contest.participation
@ -268,7 +268,7 @@ class DjangoJudgeHandler(JudgeHandler):
if Submission.objects.filter(id=packet['submission-id']).update(status='CE', result='CE', error=packet['log']):
event.post('sub_%s' % Submission.get_id_secret(packet['submission-id']), {
'type': 'compile-error',
'log': packet['log']
'log': packet['log'],
})
self._post_update_submission(packet['submission-id'], 'compile-error', done=True)
json_log.info(self._make_json_log(packet, action='compile-error', log=packet['log'],
@ -364,7 +364,7 @@ class DjangoJudgeHandler(JudgeHandler):
packet, action='test-case', case=test_case.case, batch=test_case.batch,
time=test_case.time, memory=test_case.memory, feedback=test_case.feedback,
extended_feedback=test_case.extended_feedback, output=test_case.output,
points=test_case.points, total=test_case.total, status=test_case.status
points=test_case.points, total=test_case.total, status=test_case.status,
))
do_post = True
@ -390,7 +390,7 @@ class DjangoJudgeHandler(JudgeHandler):
'memory': packet['memory'],
'points': float(test_case.points),
'total': float(test_case.total),
'output': packet['output']
'output': packet['output'],
})
self._post_update_submission(id, state='test-case')

View File

@ -7,11 +7,7 @@ from event_socket_server import ProxyProtocolMixin, ZlibPacketHandler
logger = logging.getLogger('judge.bridge')
SubmissionData = namedtuple(
'SubmissionData',
'time memory short_circuit pretests_only contest_no attempt_no user_id'
)
SubmissionData = namedtuple('SubmissionData', 'time memory short_circuit pretests_only contest_no attempt_no user_id')
class JudgeHandler(ProxyProtocolMixin, ZlibPacketHandler):

View File

@ -100,7 +100,7 @@ class CommentedDetailView(TemplateResponseMixin, SingleObjectMixin, View):
self.object = self.get_object()
return self.render_to_response(self.get_context_data(
object=self.object,
comment_form=CommentForm(request, initial={'page': self.get_comment_page(), 'parent': None})
comment_form=CommentForm(request, initial={'page': self.get_comment_page(), 'parent': None}),
))
def get_context_data(self, **kwargs):

View File

@ -31,7 +31,7 @@ class DefaultContestFormat(BaseContestFormat):
format_data = {}
for result in participation.submissions.values('problem_id').annotate(
time=Max('submission__date'), points=Max('points')
time=Max('submission__date'), points=Max('points'),
):
dt = (result['time'] - participation.start).total_seconds()
if result['points']:

View File

@ -7,7 +7,7 @@ class LockModel(object):
def __init__(self, write, read=()):
self.tables = ', '.join(chain(
('`%s` WRITE' % model._meta.db_table for model in write),
('`%s` READ' % model._meta.db_table for model in read)
('`%s` READ' % model._meta.db_table for model in read),
))
self.cursor = connection.cursor()

View File

@ -45,7 +45,7 @@ class ProfileForm(ModelForm):
if HeavyPreviewPageDownWidget is not None:
widgets['about'] = HeavyPreviewPageDownWidget(
preview=reverse_lazy('profile_preview'),
attrs={'style': 'max-width:700px;min-width:700px;width:700px'}
attrs={'style': 'max-width:700px;min-width:700px;width:700px'},
)
def clean(self):
@ -63,7 +63,7 @@ class ProfileForm(ModelForm):
super(ProfileForm, self).__init__(*args, **kwargs)
if not user.has_perm('judge.edit_all_organization'):
self.fields['organizations'].queryset = Organization.objects.filter(
Q(is_open=True) | Q(id__in=user.profile.organizations.all())
Q(is_open=True) | Q(id__in=user.profile.organizations.all()),
)
@ -128,7 +128,7 @@ class TOTPForm(Form):
TOLERANCE = getattr(settings, 'DMOJ_TOTP_TOLERANCE_HALF_MINUTES', 1)
totp_token = NoAutoCompleteCharField(validators=[
RegexValidator('^[0-9]{6}$', _('Two Factor Authentication tokens must be 6 decimal digits.'))
RegexValidator('^[0-9]{6}$', _('Two Factor Authentication tokens must be 6 decimal digits.')),
])
def __init__(self, *args, **kwargs):

View File

@ -22,12 +22,8 @@ NOFOLLOW_WHITELIST = getattr(settings, 'NOFOLLOW_EXCLUDED', set())
class CodeSafeInlineGrammar(mistune.InlineGrammar):
double_emphasis = re.compile(
r'^\*{2}([\s\S]+?)()\*{2}(?!\*)' # **word**
)
emphasis = re.compile(
r'^\*((?:\*\*|[^\*])+?)()\*(?!\*)' # *word*
)
double_emphasis = re.compile(r'^\*{2}([\s\S]+?)()\*{2}(?!\*)') # **word**
emphasis = re.compile(r'^\*((?:\*\*|[^\*])+?)()\*(?!\*)') # *word*
class AwesomeInlineGrammar(MathInlineGrammar, CodeSafeInlineGrammar):
@ -87,7 +83,7 @@ class AwesomeRenderer(MathRenderer, mistune.Renderer):
'width="%(width)s" height="%(height)s"%(tail)s>') % {
'svg': result['svg'], 'png': result['png'],
'width': result['meta']['width'], 'height': result['meta']['height'],
'tail': ' /' if self.options.get('use_xhtml') else ''
'tail': ' /' if self.options.get('use_xhtml') else '',
}
style = ['max-width: 100%',
'height: %s' % result['meta']['height'],

View File

@ -33,7 +33,7 @@ class Command(BaseCommand):
contest__participation__virtual__in=(ContestParticipation.LIVE, ContestParticipation.SPECTATE),
contest__participation__contest__key=contest,
result='AC', problem__id=problem.id,
language__common_name=dmoj_lang
language__common_name=dmoj_lang,
).values_list('user__user__username', 'source__source')
if not subs:
print('<no submissions>')

View File

@ -25,7 +25,7 @@ class Migration(migrations.Migration):
['''UPDATE judge_submission sub
INNER JOIN judge_submissionsource src ON sub.id = src.submission_id
SET sub.source = src.source;'''],
elidable=True
elidable=True,
),
migrations.RemoveField(
model_name='submission',
@ -34,6 +34,6 @@ class Migration(migrations.Migration):
migrations.AlterField(
model_name='submissionsource',
name='submission',
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='source', to='judge.Submission', verbose_name='associated submission')
field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='source', to='judge.Submission', verbose_name='associated submission'),
),
]

View File

@ -176,7 +176,7 @@ class Profile(models.Model):
class Meta:
permissions = (
('test_site', 'Shows in-progress development stuff'),
('totp', 'Edit TOTP settings')
('totp', 'Edit TOTP settings'),
)
verbose_name = _('user profile')
verbose_name_plural = _('user profiles')

View File

@ -74,7 +74,7 @@ def choose_username(backend, user, username=None, *args, **kwargs):
else:
form = UsernameForm(initial={'username': username})
return render(request, 'registration/username_select.html', {
'title': 'Choose a username', 'form': form
'title': 'Choose a username', 'form': form,
})
@ -98,7 +98,7 @@ def make_profile(backend, user, response, is_new=False, *args, **kwargs):
revisions.set_comment('Updated on registration')
return
return render(backend.strategy.request, 'registration/profile_creation.html', {
'title': 'Create your profile', 'form': form
'title': 'Create your profile', 'form': form,
})

View File

@ -17,7 +17,7 @@ class Progress:
'done': self._done,
'total': self._total,
'stage': self._stage,
}
},
)
@property

View File

@ -63,7 +63,7 @@ class MathoidMathParser(object):
try:
response = requests.post(self.mathoid_url, data={
'q': reescape.sub(lambda m: '\\' + m.group(0), formula).encode('utf-8'),
'type': 'tex' if formula.startswith(r'\displaystyle') else 'inline-tex'
'type': 'tex' if formula.startswith(r'\displaystyle') else 'inline-tex',
})
response.raise_for_status()
data = response.json()

View File

@ -138,7 +138,7 @@ def hot_problems(duration, limit):
qs = qs.annotate(ordering=ExpressionWrapper(
0.5 * F('points') * (0.4 * F('ac_volume') / F('submission_volume') + 0.6 * F('ac_rate')) +
100 * e ** (F('unique_user_count') / mx), output_field=FloatField()
100 * e ** (F('unique_user_count') / mx), output_field=FloatField(),
)).order_by('-ordering').defer('description')[:limit]
cache.set(cache_key, qs, 900)

View File

@ -68,9 +68,7 @@ def _get_pwned(prefix):
response.raise_for_status()
except requests.RequestException as e:
# Gracefully handle timeouts and HTTP error response codes.
log.warning(
'Skipped Pwned Passwords check due to error: %r', e
)
log.warning('Skipped Pwned Passwords check due to error: %r', e)
return None
results = {}
@ -100,12 +98,8 @@ class PwnedPasswordsValidator(object):
"""
Password validator which checks the Pwned Passwords database.
"""
DEFAULT_HELP_MESSAGE = _(
"Your password can't be a commonly used password."
)
DEFAULT_PWNED_MESSAGE = _(
"This password is too common."
)
DEFAULT_HELP_MESSAGE = _("Your password can't be a commonly used password.")
DEFAULT_PWNED_MESSAGE = _('This password is too common.')
def __init__(self, error_message=None, help_message=None):
self.help_message = help_message or self.DEFAULT_HELP_MESSAGE
@ -118,7 +112,7 @@ class PwnedPasswordsValidator(object):
singular, plural = error_message
self.error_message = {
'singular': singular,
'plural': plural
'plural': plural,
}
def validate(self, password, user=None):

View File

@ -28,7 +28,7 @@ class TexoidRenderer(object):
try:
response = requests.post(settings.TEXOID_URL, data=utf8bytes(document), headers={
'Content-Type': 'application/x-tex'
'Content-Type': 'application/x-tex',
})
response.raise_for_status()
except requests.HTTPError as e:

View File

@ -24,7 +24,7 @@ def class_view_decorator(function_decorator):
def generic_message(request, title, message, status=None):
return render(request, 'generic-message.html', {
'message': message,
'title': title
'title': title,
}, status=status)

View File

@ -74,8 +74,8 @@ def api_v1_contest_detail(request, contest):
'user': participation.username,
'points': participation.score,
'cumtime': participation.cumtime,
'solutions': contest.format.get_problem_breakdown(participation, problems)
} for participation in participations]
'solutions': contest.format.get_problem_breakdown(participation, problems),
} for participation in participations],
})
@ -91,7 +91,7 @@ def api_v1_problem_list(request):
'points': points,
'partial': partial,
'name': name,
'group': group
'group': group,
} for code, points, partial, name, group in queryset})
@ -119,7 +119,7 @@ def api_v1_user_list(request):
return JsonResponse({username: {
'points': points,
'performance_points': performance_points,
'rank': rank
'rank': rank,
} for username, points, performance_points, rank in queryset})

View File

@ -9,9 +9,7 @@ from judge.views.contests import contest_ranking_list
def error(message):
return JsonResponse({
"error": message
}, status=422)
return JsonResponse({'error': message}, status=422)
def api_v2_user_info(request):
@ -62,7 +60,7 @@ def api_v2_user_info(request):
resp = {
"rank": profile.display_rank,
"organizations": list(profile.organizations.values_list('key', flat=True))
"organizations": list(profile.organizations.values_list('key', flat=True)),
}
contest_history = []
@ -110,7 +108,7 @@ def api_v2_user_info(request):
attempted_problems.append({
'awarded': awarded_pts,
'max': max_pts,
'problem': problem
'problem': problem,
})
resp['problems'] = {
@ -118,7 +116,7 @@ def api_v2_user_info(request):
'solved': solved_problems,
'attempted': attempted_problems,
'authored': list(Problem.objects.filter(is_public=True, is_organization_private=False, authors=profile)
.values_list('code', flat=True))
.values_list('code', flat=True)),
}
return JsonResponse(resp)

View File

@ -204,7 +204,7 @@ class ContestMixin(object):
_('Could not find such contest.'))
except PrivateContestError as e:
return render(request, 'contest/private.html', {
'orgs': e.orgs, 'title': _('Access to contest "%s" denied') % escape(e.name)
'orgs': e.orgs, 'title': _('Access to contest "%s" denied') % escape(e.name),
}, status=403)
@ -283,7 +283,7 @@ class ContestJoin(LoginRequiredMixin, ContestMixin, BaseDetailView):
try:
participation = ContestParticipation.objects.create(
contest=contest, user=profile, virtual=virtual_id,
real_start=timezone.now()
real_start=timezone.now(),
)
# There is obviously a race condition here, so we keep trying until we win the race.
except IntegrityError:
@ -293,7 +293,7 @@ class ContestJoin(LoginRequiredMixin, ContestMixin, BaseDetailView):
else:
try:
participation = ContestParticipation.objects.get(
contest=contest, user=profile, virtual=(-1 if self.is_organizer else 0)
contest=contest, user=profile, virtual=(-1 if self.is_organizer else 0),
)
except ContestParticipation.DoesNotExist:
if requires_access_code:
@ -307,9 +307,7 @@ class ContestJoin(LoginRequiredMixin, ContestMixin, BaseDetailView):
if participation.ended:
participation = ContestParticipation.objects.get_or_create(
contest=contest, user=profile, virtual=-1,
defaults={
'real_start': timezone.now()
}
defaults={'real_start': timezone.now()},
)[0]
profile.current_contest = participation
@ -446,7 +444,7 @@ class CachedContestCalendar(ContestCalendar):
ContestRankingProfile = namedtuple(
'ContestRankingProfile',
'id user css_class username points cumtime organization participation '
'participation_rating problem_cells result_cell'
'participation_rating problem_cells result_cell',
)
BestSolutionData = namedtuple('BestSolutionData', 'code points time state is_pretested')

View File

@ -12,18 +12,22 @@ def error404(request, exception=None):
# TODO: "panic: go back"
return render(request, 'generic-message.html', {
'title': _('404 error'),
'message': _('Could not find page "%s"') % request.path
'message': _('Could not find page "%s"') % request.path,
}, status=404)
def error403(request, exception=None):
return error(request, {'id': 'unauthorized_access',
'description': _('no permission for %s') % request.path,
'code': 403}, 403)
return error(request, {
'id': 'unauthorized_access',
'description': _('no permission for %s') % request.path,
'code': 403,
}, 403)
def error500(request):
return error(request, {'id': 'invalid_state',
'description': _('corrupt page %s') % request.path,
'traceback': traceback.format_exc(),
'code': 500}, 500)
return error(request, {
'id': 'invalid_state',
'description': _('corrupt page %s') % request.path,
'traceback': traceback.format_exc(),
'code': 500,
}, 500)

View File

@ -86,10 +86,9 @@ class OrganizationUsers(OrganizationDetailView):
def get_context_data(self, **kwargs):
context = super(OrganizationUsers, self).get_context_data(**kwargs)
context['title'] = _('%s Members') % self.object.name
context['users'] = ranker(
self.object.members.filter(is_unlisted=False).order_by('-performance_points', '-problem_count')
.select_related('user').defer('about', 'user_script', 'notes')
)
context['users'] = \
ranker(self.object.members.filter(is_unlisted=False).order_by('-performance_points', '-problem_count')
.select_related('user').defer('about', 'user_script', 'notes'))
context['partial'] = True
context['is_admin'] = self.can_edit_organization()
context['kick_url'] = reverse('organization_user_kick', args=[self.object.id, self.object.slug])
@ -120,7 +119,7 @@ class JoinOrganization(OrganizationMembershipChange):
if profile.organizations.filter(is_open=True).count() >= max_orgs:
return generic_message(
request, _('Joining organization'),
_('You may not be part of more than {count} public organizations.').format(count=max_orgs)
_('You may not be part of more than {count} public organizations.').format(count=max_orgs),
)
profile.organizations.add(org)
@ -166,7 +165,7 @@ class RequestJoinOrganization(LoginRequiredMixin, SingleObjectMixin, FormView):
request.state = 'P'
request.save()
return HttpResponseRedirect(reverse('request_organization_detail', args=(
request.organization.id, request.organization.slug, request.id
request.organization.id, request.organization.slug, request.id,
)))
@ -184,9 +183,7 @@ class OrganizationRequestDetail(LoginRequiredMixin, TitleMixin, DetailView):
return object
OrganizationRequestFormSet = modelformset_factory(
OrganizationRequest, extra=0, fields=('state',), can_delete=True
)
OrganizationRequestFormSet = modelformset_factory(OrganizationRequest, extra=0, fields=('state',), can_delete=True)
class OrganizationRequestBaseView(LoginRequiredMixin, SingleObjectTemplateResponseMixin, SingleObjectMixin, View):
@ -220,7 +217,7 @@ class OrganizationRequestView(OrganizationRequestBaseView):
def get(self, request, *args, **kwargs):
self.object = self.get_object()
self.formset = OrganizationRequestFormSet(
queryset=OrganizationRequest.objects.filter(state='P', organization=self.object)
queryset=OrganizationRequest.objects.filter(state='P', organization=self.object),
)
context = self.get_context_data(object=self.object)
return self.render_to_response(context)

View File

@ -636,7 +636,7 @@ def problem_submit(request, problem=None, submission=None):
'content_title': mark_safe(escape(_('Submit to %(problem)s')) % {
'problem': format_html('<a href="{0}">{1}</a>',
reverse('problem_detail', args=[problem_object.code]),
problem_object.translated_name(request.LANGUAGE_CODE))
problem_object.translated_name(request.LANGUAGE_CODE)),
}),
'langs': Language.objects.all(),
'no_judges': not form.fields['language'].queryset,

View File

@ -240,5 +240,5 @@ def problem_init_view(request, problem):
'title': _('Generated init.yml for %s') % problem.name,
'content_title': mark_safe(escape(_('Generated init.yml for %s')) % (
format_html('<a href="{1}">{0}</a>', problem.name,
reverse('problem_detail', args=[problem.code]))))
reverse('problem_detail', args=[problem.code])))),
})

View File

@ -51,7 +51,7 @@ class ManageProblemSubmissionView(TitleMixin, ManageProblemSubmissionMixin, Deta
def get_content_title(self):
return mark_safe(escape(_('Managing submissions for %s')) % (
format_html('<a href="{1}">{0}</a>', self.object.name,
reverse('problem_detail', args=[self.object.code]))), )
reverse('problem_detail', args=[self.object.code]))))
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
@ -90,7 +90,7 @@ class RejudgeSubmissionsView(BaseRejudgeSubmissionsView):
status = rejudge_problem_filter.delay(self.object.id, id_range, languages, results)
return redirect_to_task_status(
status, message=_('Rejudging selected submissions for %s...') % (self.object.name,),
redirect=reverse('problem_submissions_rejudge_success', args=[self.object.code, status.id])
redirect=reverse('problem_submissions_rejudge_success', args=[self.object.code, status.id]),
)
@ -105,7 +105,7 @@ class RescoreAllSubmissionsView(ManageProblemSubmissionActionMixin, BaseDetailVi
status = rescore_problem.delay(self.object.id)
return redirect_to_task_status(
status, message=_('Rescoring all submissions for %s...') % (self.object.name,),
redirect=reverse('problem_submissions_rescore_success', args=[self.object.code, status.id])
redirect=reverse('problem_submissions_rescore_success', args=[self.object.code, status.id]),
)

View File

@ -46,7 +46,7 @@ class RankedSubmissions(ProblemSubmissions):
GROUP BY sub.user_id
'''.format(points=points, contest_join=contest_join, constraint=constraint),
params=[self.problem.id, self.contest.id] * 3 if self.in_contest else [self.problem.id] * 3,
alias='best_subs', join_fields=[('id', 'id')]
alias='best_subs', join_fields=[('id', 'id')],
)
if self.in_contest:
@ -69,10 +69,10 @@ class ContestRankedSubmission(ForceContestMixin, RankedSubmissions):
def get_title(self):
if self.problem.is_accessible_by(self.request.user):
return _('Best solutions for %(problem)s in %(contest)s') % {
'problem': self.problem_name, 'contest': self.contest.name
'problem': self.problem_name, 'contest': self.contest.name,
}
return _('Best solutions for problem %(number)s in %(contest)s') % {
'number': self.get_problem_number(self.problem), 'contest': self.contest.name
'number': self.get_problem_number(self.problem), 'contest': self.contest.name,
}
def get_content_title(self):

View File

@ -71,7 +71,7 @@ class RegistrationView(OldRegistrationView):
def register(self, form):
user = super(RegistrationView, self).register(form)
profile, _ = Profile.objects.get_or_create(user=user, defaults={
'language': Language.get_python2()
'language': Language.get_python2(),
})
cleaned_data = form.cleaned_data
@ -104,5 +104,5 @@ class ActivationView(OldActivationView):
def social_auth_error(request):
return render(request, 'generic-message.html', {
'title': gettext('Authentication failure'),
'message': request.GET.get('message')
'message': request.GET.get('message'),
})

View File

@ -103,5 +103,5 @@ def ac_rate(request):
def language(request):
return render(request, 'stats/language.html', {
'title': _('Language statistics'), 'tab': 'language'
'title': _('Language statistics'), 'tab': 'language',
})

View File

@ -58,7 +58,7 @@ class SubmissionDetailBase(LoginRequiredMixin, TitleMixin, SubmissionMixin, Deta
submission = self.object
return _('Submission of %(problem)s by %(user)s') % {
'problem': submission.problem.translated_name(self.request.LANGUAGE_CODE),
'user': submission.user.user.username
'user': submission.user.user.username,
}
def get_content_title(self):

View File

@ -43,7 +43,7 @@ def task_status(request, task_id):
return render(request, 'task_status.html', {
'task_id': task_id, 'task_status': json.dumps(status),
'message': request.GET.get('message', ''), 'redirect': redirect or ''
'message': request.GET.get('message', ''), 'redirect': redirect or '',
})

View File

@ -161,10 +161,10 @@ class TicketStatusChangeView(LoginRequiredMixin, TicketMixin, SingleObjectMixin,
'type': 'ticket-status', 'id': ticket.id,
'open': self.open, 'user': ticket.user_id,
'assignees': list(ticket.assignees.values_list('id', flat=True)),
'title': ticket.title
'title': ticket.title,
})
event.post('ticket-%d' % ticket.id, {
'type': 'ticket-status', 'open': self.open
'type': 'ticket-status', 'open': self.open,
})
return HttpResponse(status=204)
@ -299,5 +299,5 @@ class TicketListDataAjax(TicketMixin, SingleObjectMixin, View):
'id': ticket.id,
'users': (_(', ').join(ticket.assignees.values_list('user__username', flat=True)) or _('no one')),
}, truncatechars(message.body, 200)),
}
},
})

View File

@ -99,12 +99,12 @@ class UserPage(TitleMixin, UserMixin, DetailView):
context['rating'] = rating[0] if rating else None
context['rank'] = Profile.objects.filter(
is_unlisted=False, performance_points__gt=self.object.performance_points
is_unlisted=False, performance_points__gt=self.object.performance_points,
).count() + 1
if rating:
context['rating_rank'] = Profile.objects.filter(
is_unlisted=False, rating__gt=self.object.rating
is_unlisted=False, rating__gt=self.object.rating,
).count() + 1
context['rated_users'] = Profile.objects.filter(is_unlisted=False, rating__isnull=False).count()
context.update(self.object.ratings.aggregate(min_rating=Min('rating'), max_rating=Max('rating'),
@ -135,7 +135,7 @@ class UserAboutPage(UserPage):
'timestamp': (rating.contest.end_time - EPOCH).total_seconds() * 1000,
'date': date_format(rating.contest.end_time, _('M j, Y, G:i')),
'class': rating_class(rating.rating),
'height': '%.3fem' % rating_progress(rating.rating)
'height': '%.3fem' % rating_progress(rating.rating),
} for rating in ratings]))
if ratings:
@ -171,7 +171,7 @@ class UserProblemsPage(UserPage):
process_group(group, problems) for group, problems in itertools.groupby(
remap_keys(result, {
'problem__code': 'code', 'problem__name': 'name', 'problem__points': 'total',
'problem__group__full_name': 'group'
'problem__group__full_name': 'group',
}), itemgetter('group'))
]
breakdown, has_more = get_pp_breakdown(self.object, start=0, end=10)
@ -308,7 +308,7 @@ def user_ranking_redirect(request):
user = get_object_or_404(Profile, user__username=username)
rank = Profile.objects.filter(is_unlisted=False, performance_points__gt=user.performance_points).count()
rank += Profile.objects.filter(
is_unlisted=False, performance_points__exact=user.performance_points, id__lt=user.id
is_unlisted=False, performance_points__exact=user.performance_points, id__lt=user.id,
).count()
page = rank // UserList.paginate_by
return HttpResponseRedirect('%s%s#!%s' % (reverse('user_list'), '?page=%d' % (page + 1) if page else '', username))

View File

@ -43,5 +43,5 @@ class CompressorWidgetMixin(object):
return forms.Media(
css={'all': [result.find('.//link').get('href')]} if self.compress_css else media._css,
js=[result.find('.//script').get('src')] if self.compress_js else media._js
js=[result.find('.//script').get('src')] if self.compress_js else media._js,
)

View File

@ -94,7 +94,7 @@ class Select2Mixin(object):
return forms.Media(
js=(getattr(settings, 'SELECT2_JS_URL', DEFAULT_SELECT2_JS),
'django_select2.js'),
css={'screen': (getattr(settings, 'SELECT2_CSS_URL', DEFAULT_SELECT2_CSS),)}
css={'screen': (getattr(settings, 'SELECT2_CSS_URL', DEFAULT_SELECT2_CSS),)},
)
media = property(_get_media)