From c896740957ee487e48563a4794dee77784d96d46 Mon Sep 17 00:00:00 2001 From: jalsol Date: Mon, 10 Apr 2023 17:09:33 +0700 Subject: [PATCH 1/7] Set cooldown for non-superusers between comments --- dmoj/settings.py | 3 +++ judge/comments.py | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/dmoj/settings.py b/dmoj/settings.py index afd870930..6f8cb47f4 100755 --- a/dmoj/settings.py +++ b/dmoj/settings.py @@ -98,6 +98,9 @@ VNOJ_TAG_PROBLEM_MIN_RATING = 1900 # Minimum rating to be able to tag a problem +# Cooldown time (minutes) between each comment +VNOJ_COMMENT_COOLDOWN = 10 + # Some problems have a lot of testcases, and each testcase # has about 5~6 fields, so we need to raise this DATA_UPLOAD_MAX_NUMBER_FIELDS = 3000 diff --git a/judge/comments.py b/judge/comments.py index 4e8d88dcc..35b31a9fc 100644 --- a/judge/comments.py +++ b/judge/comments.py @@ -1,3 +1,5 @@ +from datetime import datetime + from django import forms from django.conf import settings from django.contrib.auth.decorators import login_required @@ -72,6 +74,18 @@ def post(self, request, *args, **kwargs): if self.is_comment_locked(): return HttpResponseForbidden() + if not request.user.is_superuser: + user_latest_comments = Comment.get_newest_visible_comments(viewer=request.user, + author=request.user.profile, + n=1) + + if not request.user.is_superuser and len(user_latest_comments) > 0: + time_diff = (datetime.now(timezone.utc) - user_latest_comments[0].time).seconds + if time_diff < settings.VNOJ_COMMENT_COOLDOWN * 60: + return HttpResponseBadRequest(_('You can only comment after {0} minutes' + 'since your latest comment') + .format(settings.VNOJ_COMMENT_COOLDOWN), content_type='text/plain') + parent = request.POST.get('parent') if parent: if len(parent) > 10: From 08c3d042c37db9992ad198b8529d08b8166865e8 Mon Sep 17 00:00:00 2001 From: jalsol Date: Mon, 10 Apr 2023 20:50:16 +0700 Subject: [PATCH 2/7] Delete unnecessary condition; Update message --- judge/comments.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/judge/comments.py b/judge/comments.py index 35b31a9fc..b006b11f9 100644 --- a/judge/comments.py +++ b/judge/comments.py @@ -79,10 +79,10 @@ def post(self, request, *args, **kwargs): author=request.user.profile, n=1) - if not request.user.is_superuser and len(user_latest_comments) > 0: + if len(user_latest_comments) > 0: time_diff = (datetime.now(timezone.utc) - user_latest_comments[0].time).seconds if time_diff < settings.VNOJ_COMMENT_COOLDOWN * 60: - return HttpResponseBadRequest(_('You can only comment after {0} minutes' + return HttpResponseBadRequest(_('You can only comment after {0} minutes ' 'since your latest comment') .format(settings.VNOJ_COMMENT_COOLDOWN), content_type='text/plain') From 181fd1c719338740502ba57a2b192f9f361e8cb3 Mon Sep 17 00:00:00 2001 From: jalsol Date: Mon, 10 Apr 2023 21:07:41 +0700 Subject: [PATCH 3/7] Set cooldown for non-superusers between blogs --- dmoj/settings.py | 3 +++ judge/views/blog.py | 20 ++++++++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/dmoj/settings.py b/dmoj/settings.py index 6f8cb47f4..4fe766527 100755 --- a/dmoj/settings.py +++ b/dmoj/settings.py @@ -101,6 +101,9 @@ # Cooldown time (minutes) between each comment VNOJ_COMMENT_COOLDOWN = 10 +# Cooldown time (minutes) between each blog post +VNOJ_BLOG_COOLDOWN = 3 * 60 + # Some problems have a lot of testcases, and each testcase # has about 5~6 fields, so we need to raise this DATA_UPLOAD_MAX_NUMBER_FIELDS = 3000 diff --git a/judge/views/blog.py b/judge/views/blog.py index 4b25b6ec6..ea90fd5ef 100644 --- a/judge/views/blog.py +++ b/judge/views/blog.py @@ -1,3 +1,5 @@ +from datetime import datetime + from django.conf import settings from django.contrib.auth.decorators import login_required from django.core.exceptions import PermissionDenied @@ -295,13 +297,27 @@ def form_valid(self, form): def dispatch(self, request, *args, **kwargs): if not request.user.is_authenticated: raise PermissionDenied() + + user = request.user + # hasattr(self, 'organization') -> admin org - if request.official_contest_mode or request.user.profile.problem_count < settings.VNOJ_BLOG_MIN_PROBLEM_COUNT \ - and not request.user.is_superuser and not hasattr(self, 'organization'): + if request.official_contest_mode or user.profile.problem_count < settings.VNOJ_BLOG_MIN_PROBLEM_COUNT \ + and not user.is_superuser and not hasattr(self, 'organization'): return generic_message(request, _('Permission denied'), _('You cannot create blog post.\n' 'Note: You need to solve at least %d problems to create new blog post.') % settings.VNOJ_BLOG_MIN_PROBLEM_COUNT) + + if not user.is_superuser: + user_latest_blog = BlogPost.objects.filter(publish_on__lte=timezone.now(), authors__in=[user.profile]) \ + .order_by('-publish_on')[:1] + + if len(user_latest_blog) > 0: + time_diff = (datetime.now(timezone.utc) - user_latest_blog[0].publish_on).seconds + if time_diff < settings.VNOJ_BLOG_COOLDOWN * 60: + return HttpResponseBadRequest(_('You can only create a blog after {0} minutes ' + 'since your latest blog') + .format(settings.VNOJ_BLOG_COOLDOWN), content_type='text/plain') return super().dispatch(request, *args, **kwargs) From e258921adc77b40b6e5ea7448b371baa0a3b2ec4 Mon Sep 17 00:00:00 2001 From: jalsol Date: Tue, 2 May 2023 23:55:02 +0700 Subject: [PATCH 4/7] Replace the query to find a user's latest comment --- judge/comments.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/judge/comments.py b/judge/comments.py index b006b11f9..49b285e97 100644 --- a/judge/comments.py +++ b/judge/comments.py @@ -75,9 +75,7 @@ def post(self, request, *args, **kwargs): return HttpResponseForbidden() if not request.user.is_superuser: - user_latest_comments = Comment.get_newest_visible_comments(viewer=request.user, - author=request.user.profile, - n=1) + user_latest_comments = Comment.objects.filter(author=request.profile).order_by('-time')[:1] if len(user_latest_comments) > 0: time_diff = (datetime.now(timezone.utc) - user_latest_comments[0].time).seconds From 40a98a42c397c1c44fdf601bcaf6d9bc3330a3ab Mon Sep 17 00:00:00 2001 From: jalsol Date: Sun, 14 May 2023 12:03:19 +0700 Subject: [PATCH 5/7] Modify cooldown time - Cooldown time are now in seconds instead of minutes - Each user can now comment every 60 seconds instead of 10 minutes --- dmoj/settings.py | 8 ++++---- judge/comments.py | 4 ++-- judge/views/blog.py | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dmoj/settings.py b/dmoj/settings.py index 4fe766527..5c35440e5 100755 --- a/dmoj/settings.py +++ b/dmoj/settings.py @@ -98,11 +98,11 @@ VNOJ_TAG_PROBLEM_MIN_RATING = 1900 # Minimum rating to be able to tag a problem -# Cooldown time (minutes) between each comment -VNOJ_COMMENT_COOLDOWN = 10 +# Cooldown time (seconds) between each comment +VNOJ_COMMENT_COOLDOWN = 60 -# Cooldown time (minutes) between each blog post -VNOJ_BLOG_COOLDOWN = 3 * 60 +# Cooldown time (seconds) between each blog post +VNOJ_BLOG_COOLDOWN = 3 * 60 * 60 # Some problems have a lot of testcases, and each testcase # has about 5~6 fields, so we need to raise this diff --git a/judge/comments.py b/judge/comments.py index 49b285e97..8f47a2227 100644 --- a/judge/comments.py +++ b/judge/comments.py @@ -79,8 +79,8 @@ def post(self, request, *args, **kwargs): if len(user_latest_comments) > 0: time_diff = (datetime.now(timezone.utc) - user_latest_comments[0].time).seconds - if time_diff < settings.VNOJ_COMMENT_COOLDOWN * 60: - return HttpResponseBadRequest(_('You can only comment after {0} minutes ' + if time_diff < settings.VNOJ_COMMENT_COOLDOWN: + return HttpResponseBadRequest(_('You can only comment after {0} seconds ' 'since your latest comment') .format(settings.VNOJ_COMMENT_COOLDOWN), content_type='text/plain') diff --git a/judge/views/blog.py b/judge/views/blog.py index ea90fd5ef..e67db88bd 100644 --- a/judge/views/blog.py +++ b/judge/views/blog.py @@ -314,8 +314,8 @@ def dispatch(self, request, *args, **kwargs): if len(user_latest_blog) > 0: time_diff = (datetime.now(timezone.utc) - user_latest_blog[0].publish_on).seconds - if time_diff < settings.VNOJ_BLOG_COOLDOWN * 60: - return HttpResponseBadRequest(_('You can only create a blog after {0} minutes ' + if time_diff < settings.VNOJ_BLOG_COOLDOWN: + return HttpResponseBadRequest(_('You can only create a blog after {0} seconds ' 'since your latest blog') .format(settings.VNOJ_BLOG_COOLDOWN), content_type='text/plain') return super().dispatch(request, *args, **kwargs) From 23e1bc29832ecca3a7e7def4e7206a4904ddb543 Mon Sep 17 00:00:00 2001 From: jalsol Date: Sun, 14 May 2023 12:46:11 +0700 Subject: [PATCH 6/7] Display remaining time instead of cooldown limit - This should be friendlier and more informative to users - The time format is M:S instead of S since "179 minutes and 59 seconds" is more intuitive than "10799 seconds" --- judge/comments.py | 7 ++++--- judge/views/blog.py | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/judge/comments.py b/judge/comments.py index 8f47a2227..1332b35e6 100644 --- a/judge/comments.py +++ b/judge/comments.py @@ -80,9 +80,10 @@ def post(self, request, *args, **kwargs): if len(user_latest_comments) > 0: time_diff = (datetime.now(timezone.utc) - user_latest_comments[0].time).seconds if time_diff < settings.VNOJ_COMMENT_COOLDOWN: - return HttpResponseBadRequest(_('You can only comment after {0} seconds ' - 'since your latest comment') - .format(settings.VNOJ_COMMENT_COOLDOWN), content_type='text/plain') + remaining_minutes, remaining_seconds = divmod(settings.VNOJ_COMMENT_COOLDOWN - time_diff, 60) + return HttpResponseBadRequest(_('You can only comment after {0} minutes and {1} seconds.') + .format(remaining_minutes, remaining_seconds), + content_type='text/plain') parent = request.POST.get('parent') if parent: diff --git a/judge/views/blog.py b/judge/views/blog.py index e67db88bd..6e16ff451 100644 --- a/judge/views/blog.py +++ b/judge/views/blog.py @@ -315,9 +315,10 @@ def dispatch(self, request, *args, **kwargs): if len(user_latest_blog) > 0: time_diff = (datetime.now(timezone.utc) - user_latest_blog[0].publish_on).seconds if time_diff < settings.VNOJ_BLOG_COOLDOWN: - return HttpResponseBadRequest(_('You can only create a blog after {0} seconds ' - 'since your latest blog') - .format(settings.VNOJ_BLOG_COOLDOWN), content_type='text/plain') + remaining_minutes, remaining_seconds = divmod(settings.VNOJ_BLOG_COOLDOWN - time_diff, 60) + return HttpResponseBadRequest(_('You can only create a blog after {0} minutes and {1} seconds.') + .format(remaining_minutes, remaining_seconds), + content_type='text/plain') return super().dispatch(request, *args, **kwargs) From d9ff91d4463cd346f6d5868a1ca08c70ee8a374f Mon Sep 17 00:00:00 2001 From: jalsol Date: Sun, 14 May 2023 12:57:42 +0700 Subject: [PATCH 7/7] Use .first() instead of [:1] --- judge/comments.py | 6 +++--- judge/views/blog.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/judge/comments.py b/judge/comments.py index 1332b35e6..8d60ff841 100644 --- a/judge/comments.py +++ b/judge/comments.py @@ -75,10 +75,10 @@ def post(self, request, *args, **kwargs): return HttpResponseForbidden() if not request.user.is_superuser: - user_latest_comments = Comment.objects.filter(author=request.profile).order_by('-time')[:1] + user_latest_comment = Comment.objects.filter(author=request.profile).order_by('-time').first() - if len(user_latest_comments) > 0: - time_diff = (datetime.now(timezone.utc) - user_latest_comments[0].time).seconds + if user_latest_comment is not None: + time_diff = (datetime.now(timezone.utc) - user_latest_comment.time).seconds if time_diff < settings.VNOJ_COMMENT_COOLDOWN: remaining_minutes, remaining_seconds = divmod(settings.VNOJ_COMMENT_COOLDOWN - time_diff, 60) return HttpResponseBadRequest(_('You can only comment after {0} minutes and {1} seconds.') diff --git a/judge/views/blog.py b/judge/views/blog.py index 6e16ff451..f97bb75ef 100644 --- a/judge/views/blog.py +++ b/judge/views/blog.py @@ -310,10 +310,10 @@ def dispatch(self, request, *args, **kwargs): if not user.is_superuser: user_latest_blog = BlogPost.objects.filter(publish_on__lte=timezone.now(), authors__in=[user.profile]) \ - .order_by('-publish_on')[:1] + .order_by('-publish_on').first() - if len(user_latest_blog) > 0: - time_diff = (datetime.now(timezone.utc) - user_latest_blog[0].publish_on).seconds + if user_latest_blog is not None: + time_diff = (datetime.now(timezone.utc) - user_latest_blog.publish_on).seconds if time_diff < settings.VNOJ_BLOG_COOLDOWN: remaining_minutes, remaining_seconds = divmod(settings.VNOJ_BLOG_COOLDOWN - time_diff, 60) return HttpResponseBadRequest(_('You can only create a blog after {0} minutes and {1} seconds.')