Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvement for unidirectional feedback #199

Merged
merged 3 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions frontend/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,10 @@ class UnidirectionalFeedback(models.Model):

def __str__(self) -> str:
return f"{self.user} 对题目 {self.challenge_id} 的反馈"

@property
def json(self):
return {
"contents": self.contents,
"datetime": self.submit_datetime,
}
13 changes: 9 additions & 4 deletions frontend/templates/challenge_feedback.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,28 @@ <h1>提交对题目 {{challenge_name}} 的反馈</h1>
<div v-else>
<p>你对该题目上一次提交反馈在 {{ human_latest_submit() }},需要等待提交后一小时方可再次提交。</p>
</div>
<div v-if="latest_feedback">
<hr />
<p>上一次提交的内容:</p>
<p style="white-space: pre-line;">{{ latest_feedback.contents }}</p>
</div>
</div>
{% endverbatim %}
{{ too_frequent|json_script:'too-frequent' }}
{{ latest_submit|json_script:'latest-submit' }}
{{ latest_feedback.json|json_script:'latest-feedback' }}
<script>
app = new Vue({
el: '#app',
data: {
too_frequent: JSON.parse(document.getElementById('too-frequent').textContent),
latest_submit: JSON.parse(document.getElementById('latest-submit').textContent),
latest_feedback: JSON.parse(document.getElementById('latest-feedback').textContent),
},
methods: {
human_latest_submit() {
if (!this.latest_submit) {
if (!this.latest_feedback.datetime) {
return ""
}
const date = new Date(this.latest_submit)
const date = new Date(this.latest_feedback.datetime)
return date.toLocaleString()
}
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/templates/hub.html
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ <h1>{{ opened.name }}</h1>
<input type="text" name="flag" class="pure-input-rounded" maxlength="200" autocomplete="off" :placeholder="opened.prompt">
<button type="submit" class="pure-button pure-input-rounded">提交</button>
</form>
<a :href="get_feedback_url(opened)">需要提交反馈?</a>
<p><a :href="get_feedback_url(opened)">需要提交反馈?</a></p>
</div>
<div class="main-body" v-else v-html="page_content"></div>
</div>
Expand Down
26 changes: 16 additions & 10 deletions frontend/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from django.contrib.admin import site
from django.contrib.auth import logout
from django.http import Http404, JsonResponse
from django.urls import reverse
from django.shortcuts import redirect
from django.template.response import TemplateResponse
from django.views import View
Expand Down Expand Up @@ -247,10 +248,15 @@ def check(self, challenge_id):
except Error as e:
return None

def redirect_with_challenge_hash(self, challenge_name):
url = reverse("hub") + "#" + quote(challenge_name)
return redirect(url)

def check_frequency(self, challenge_id):
request = self.request
matched_feedbacks = UnidirectionalFeedback.objects.filter(challenge_id=challenge_id, user=request.user)
too_frequent = False
latest_feedback = None
latest = None
if matched_feedbacks:
latest_feedback = matched_feedbacks.latest('submit_datetime')
Expand All @@ -260,14 +266,14 @@ def check_frequency(self, challenge_id):
if current - latest <= timedelta(hours=1):
too_frequent = True

return too_frequent, latest
return too_frequent, latest_feedback

def return_template(self, challenge_name, too_frequent, latest):
def return_template(self, challenge_name, too_frequent, latest_feedback):
return TemplateResponse(self.request, 'challenge_feedback.html', {
"feedback": Feedback.get(),
"challenge_name": challenge_name,
"too_frequent": too_frequent,
"latest_submit": latest,
"latest_feedback": latest_feedback,
})

def get(self, request, challenge_id):
Expand All @@ -281,23 +287,23 @@ def get(self, request, challenge_id):
return redirect('hub')
challenge_name = challenge.name

too_frequent, latest = self.check_frequency(challenge_id)
too_frequent, latest_feedback = self.check_frequency(challenge_id)

return self.return_template(challenge_name, too_frequent, latest)
return self.return_template(challenge_name, too_frequent, latest_feedback)

def post(self, request, challenge_id):
challenge = self.check(challenge_id)
if not challenge:
return redirect('hub')
challenge_name = challenge.name
too_frequent, latest = self.check_frequency(challenge_id)
too_frequent, latest_feedback = self.check_frequency(challenge_id)
if too_frequent:
messages.error(request, "提交反馈太过频繁。")
return redirect('hub')
return self.return_template(challenge_name, too_frequent, latest_feedback)
contents = request.POST.get("contents")
if len(contents) > 1024:
messages.error(request, "提交内容超过字数限制。")
return self.return_template(challenge_name, too_frequent, latest)
return self.return_template(challenge_name, too_frequent, latest_feedback)
user = User.get(Context.from_request(request), request.user.pk)
# send to user-defined endpoint
if settings.FEEDBACK_ENDPOINT:
Expand All @@ -318,12 +324,12 @@ def post(self, request, challenge_id):
except (requests.exceptions.RequestException, requests.exceptions.HTTPError) as e:
messages.error(request, "反馈发送失败,请向管理员反馈此问题。")
logger.exception("反馈发送失败")
return self.return_template(challenge_name, too_frequent, latest)
return self.return_template(challenge_name, too_frequent, latest_feedback)
feedback = UnidirectionalFeedback.objects.create(challenge_id=challenge_id, user=request.user, contents=contents)
feedback.save()

messages.success(request, "反馈提交成功。")
return redirect('hub')
return self.redirect_with_challenge_hash(challenge_name)


class ScoreView(View):
Expand Down