From 348f2bc4f727b27abd9878334e886527479d260c Mon Sep 17 00:00:00 2001
From: adityacp
Date: Fri, 17 Apr 2020 16:54:35 +0530
Subject: Merge monitor, grade user and regrade intosingle dashboard
---
online_test/__init__.py | 6 +
online_test/celery.py | 19 ++
online_test/settings.py | 12 +
yaksh/middleware/get_notifications.py | 21 ++
yaksh/tasks.py | 83 ++++++
yaksh/templates/manage.html | 30 ++-
yaksh/templates/yaksh/grade_user.html | 109 +++++++-
yaksh/templates/yaksh/monitor.html | 366 +++++++++++---------------
yaksh/templates/yaksh/regrade.html | 175 ------------
yaksh/templates/yaksh/user_data.html | 5 -
yaksh/templates/yaksh/view_notifications.html | 60 +++++
yaksh/urls.py | 26 +-
yaksh/views.py | 119 +++++----
13 files changed, 562 insertions(+), 469 deletions(-)
create mode 100644 online_test/celery.py
create mode 100644 yaksh/middleware/get_notifications.py
create mode 100644 yaksh/tasks.py
delete mode 100644 yaksh/templates/yaksh/regrade.html
create mode 100644 yaksh/templates/yaksh/view_notifications.html
diff --git a/online_test/__init__.py b/online_test/__init__.py
index ef91994..07d5e33 100644
--- a/online_test/__init__.py
+++ b/online_test/__init__.py
@@ -1 +1,7 @@
+from __future__ import absolute_import, unicode_literals
+
+from .celery import app as celery_app
+
+__all__ = ('celery_app',)
+
__version__ = '0.14.0'
diff --git a/online_test/celery.py b/online_test/celery.py
new file mode 100644
index 0000000..582f8a1
--- /dev/null
+++ b/online_test/celery.py
@@ -0,0 +1,19 @@
+from __future__ import absolute_import, unicode_literals
+
+import os
+from django.conf import settings
+from celery import Celery
+
+# set the default Django settings module for the 'celery' program.
+os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'online_test.settings')
+
+app = Celery('online_test')
+
+# Using a string here means the worker doesn't have to serialize
+# the configuration object to child processes.
+# - namespace='CELERY' means all celery-related configuration keys
+# should have a `CELERY_` prefix.
+app.config_from_object('django.conf:settings', namespace='CELERY')
+
+# Load task modules from all registered Django app configs.
+app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
diff --git a/online_test/settings.py b/online_test/settings.py
index 7b9a231..aa373c4 100644
--- a/online_test/settings.py
+++ b/online_test/settings.py
@@ -45,6 +45,8 @@ INSTALLED_APPS = (
'taggit',
'social_django',
'grades',
+ 'django_celery_beat',
+ 'notifications_plugin',
)
MIDDLEWARE = (
@@ -53,6 +55,7 @@ MIDDLEWARE = (
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'yaksh.middleware.one_session_per_user.OneSessionPerUserMiddleware',
+ 'yaksh.middleware.get_notifications.NotificationMiddleware',
'yaksh.middleware.user_time_zone.TimezoneMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
@@ -164,6 +167,7 @@ TEMPLATES = [
'social_django.context_processors.backends',
'social_django.context_processors.login_redirect',
'django.contrib.messages.context_processors.messages',
+ 'django.template.context_processors.request',
],
'debug': True, # make this False in production
}
@@ -208,3 +212,11 @@ AUTH_PASSWORD_VALIDATORS = [
]
TAGGIT_CASE_INSENSITIVE = True
+
+# Celery parameters
+CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers.DatabaseScheduler'
+CELERY_TASK_SERIALIZER = 'json'
+CELERY_RESULT_SERIALIZER = 'json'
+CELERY_ACCEPT_CONTENT = ['json']
+CELERY_TIMEZONE = 'Asia/Kolkata'
+CELERY_BROKER_URL = 'redis://localhost'
diff --git a/yaksh/middleware/get_notifications.py b/yaksh/middleware/get_notifications.py
new file mode 100644
index 0000000..d211ad3
--- /dev/null
+++ b/yaksh/middleware/get_notifications.py
@@ -0,0 +1,21 @@
+from notifications_plugin.models import Notification
+
+class NotificationMiddleware(object):
+ """ Middleware to get user's notifications """
+ def __init__(self, get_response):
+ self.get_response = get_response
+
+ def __call__(self, request):
+ # Code to be executed for each request before
+ # the view (and later middleware) are called.
+ user = request.user
+ if user.is_authenticated:
+ notifications = Notification.objects.get_unread_receiver_notifications(
+ user.id
+ ).count()
+ request.custom_notifications = notifications
+ response = self.get_response(request)
+
+ # Code to be executed for each request/response after
+ # the view is called.
+ return response
diff --git a/yaksh/tasks.py b/yaksh/tasks.py
new file mode 100644
index 0000000..c68faa9
--- /dev/null
+++ b/yaksh/tasks.py
@@ -0,0 +1,83 @@
+# Python Imports
+from __future__ import absolute_import, unicode_literals
+from textwrap import dedent
+
+# Django and celery imports
+from celery import shared_task
+from celery.utils.log import get_task_logger
+from django.urls import reverse
+from django.shortcuts import get_object_or_404
+
+# Local imports
+from .models import Course, QuestionPaper, Quiz, AnswerPaper, CourseStatus
+from notifications_plugin.models import NotificationMessage, Notification
+
+
+@shared_task
+def regrade_papers(data):
+ question_id = data.get("question_id")
+ questionpaper_id = data.get("questionpaper_id")
+ answerpaper_id = data.get("answerpaper_id")
+ course_id = data.get("course_id")
+ user_id = data.get("user_id")
+ quiz_id = data.get("quiz_id")
+ quiz_name = data.get("quiz_name")
+ course_name = data.get("course_name")
+
+ logger = get_task_logger(__name__)
+
+ try:
+ if answerpaper_id is not None and question_id is None:
+ # Regrade specific user for all questions
+ answerpaper = AnswerPaper.objects.get(id=answerpaper_id)
+ for question in answerpaper.questions.all():
+ answerpaper.regrade(question.id)
+ course_status = CourseStatus.objects.filter(
+ user=answerpaper.user, course=answerpaper.course)
+ if course_status.exists():
+ course_status.first().set_grade()
+ url = reverse("yaksh:grade_user",
+ args=[quiz_id, answerpaper.user_id, course_id])
+
+ elif answerpaper_id is not None and question_id is not None:
+ # Regrade specific user for a specific question
+ answerpaper = AnswerPaper.objects.get(pk=answerpaper_id)
+ answerpaper.regrade(question_id)
+ course_status = CourseStatus.objects.filter(user=answerpaper.user,
+ course=answerpaper.course)
+ if course_status.exists():
+ course_status.first().set_grade()
+ url = reverse("yaksh:grade_user",
+ args=[quiz_id, answerpaper.user_id, course_id])
+
+ elif questionpaper_id is not None and question_id is not None:
+ # Regrade all users for a specific question
+ answerpapers = AnswerPaper.objects.filter(
+ questions=question_id,
+ question_paper_id=questionpaper_id, course_id=course_id)
+ for answerpaper in answerpapers:
+ answerpaper.regrade(question_id)
+ course_status = CourseStatus.objects.filter(
+ user=answerpaper.user, course=answerpaper.course)
+ if course_status.exists():
+ course_status.first().set_grade()
+ url = reverse("yaksh:grade_user", args=[quiz_id, course_id])
+
+ message = dedent("""
+ Quiz re-evaluation is complete Click here to view
+ """.format(url)
+ )
+ nm = NotificationMessage.objects.add_single_message(
+ user_id, "{0} re-evaluation status".format(quiz_name),
+ message, "success"
+ )
+ except Exception as e:
+ nm = NotificationMessage.objects.add_single_message(
+ user_id, "{0} re-evaluation status".format(quiz_name),
+ "Unable to regrade {0}. Try again later".format(quiz_name),
+ "warning"
+ )
+ logger.error(e)
+ notification = Notification.objects.add_single_notification(
+ user_id, nm.id
+ )
diff --git a/yaksh/templates/manage.html b/yaksh/templates/manage.html
index 8e74494..1b3527d 100644
--- a/yaksh/templates/manage.html
+++ b/yaksh/templates/manage.html
@@ -12,13 +12,33 @@
+
+
+ Notifications
+ {% if request.custom_notifications > 0 %}
+
+ {{request.custom_notifications}}
+
+ {% endif %}
+
+
{{user.get_full_name|title}}
diff --git a/yaksh/templates/yaksh/grade_user.html b/yaksh/templates/yaksh/grade_user.html
index 7206525..223ff36 100644
--- a/yaksh/templates/yaksh/grade_user.html
+++ b/yaksh/templates/yaksh/grade_user.html
@@ -2,9 +2,9 @@
{% load custom_filters %}
{% load static %}
-{% block title %} Grade User {% endblock %}
+{% block title %} Grader {% endblock %}
-{% block pagetitle %} Grade User {% endblock pagetitle %}
+{% block pagetitle %} Grader {% endblock pagetitle %}
{% block script %}
{% endif %}
{% endblock %}
{% block content %}
- {# ############################################################### #}
- {# This is rendered when we are just viewing exam/monitor #}
- {% if objects %}
- {% include "yaksh/paginator.html" %}
-
- {% for course in objects %}
-
-
-
-
- {% with course.get_quizzes as quizzes %}
- {% if quizzes %}
-
- {% for quiz in quizzes %}
-
-
-
- {{quiz.description}}
-
-
-
-
- {% endfor %}
-
- {% else %}
-
-
- No Quizzes
-
-
- {% endif %}
- {% endwith %}
-
-
-
-
- {% endfor %}
-
- {% include "yaksh/paginator.html" %}
-
- {% elif msg == 'Monitor' and not objects %}
-
-
-
No courses to monitor
-
- {% endif %}
- {# ############################################################### #}
- {# This is rendered when we are just viewing exam/monitor/quiz_num #}
- {% if msg != "Monitor" %}
- {% if quiz %}
- {% if papers %}
-
-
-
-
- Course Name: 
- {{course.name}}
-
-
- Quiz Name: 
- {{quiz.description}}
-
-
- Number of papers:  
- {{papers|length}}
-
-
- Papers Completed:  
-
- {% completed papers as completed_papers %}
- {{completed_papers}}
-
-
-
- Papers in progress:  
-
- {% inprogress papers as inprogress_papers %}
- {{ inprogress_papers }}
-
-
-
-
+ {% if quiz %}
+ {% if papers %}
+
+
+
+
+ Course Name: 
+ {{course.name}}
+
+
+ Quiz Name: 
+ {{quiz.description}}
+
+
+ Number of papers:  
+ {{papers|length}}
+
+
+ Papers Completed:  
+
+ {% completed papers as completed_papers %}
+ {{completed_papers}}
+
+
+
+ Papers in progress:  
+
+ {% inprogress papers as inprogress_papers %}
+ {{ inprogress_papers }}
+
+
+
-
-
-
-
-
- Download CSV
-
-
+
+
+
+
+
+
+ Download CSV
+
+
+
+
+ Auto-Refreshes every 30 seconds
-
-
-
-
- Name
- Username
- Roll No
- Institute
- Marks
- Attempts
- Time
- Status
-
-
-
- {% for paper in latest_attempts %}
-
-
- {{ paper.user.get_full_name.title }}
- {{ paper.user.username }}
- {{ paper.user.profile.roll_number }}
- {{ paper.user.profile.institute }}
- {{ paper.marks_obtained }}
- {{ paper.answers.count }}
- {{ paper.time_left }}
- {{ paper.status }}
-
- {% endfor %}
-
-
-
-
+
+
+
+
+ Sr No.
+ Name
+ Username
+ Roll No
+ Institute
+ Marks
+ Attempts
+ Time
+ Status
+
+
+
+ {% for paper in latest_attempts %}
+
+ {{forloop.counter}}
+
+ {{ paper.user.get_full_name.title }}
+ {{ paper.user.username }}
+ {{ paper.user.profile.roll_number }}
+ {{ paper.user.profile.institute }}
+ {{ paper.marks_obtained }}
+ {{ paper.answers.count }}
+ {{ paper.time_left }}
+ {{ paper.status }}
+
+ {% endfor %}
+
+
+
+
+
-
-
-
+
+
- {% else %}
-
-
-
- No Users Found for {{ quiz.description }}
-
-
- {% endif %} {# if papers #}
- {% else %}
-
No Quiz Found
- {% endif %}
- {% endif %}
+
+ {% else %}
+
+
+
+ No Users Found for {{ quiz.description }}
+
+
+
+ {% endif %} {# if papers #}
+ {% else %}
+
No Quiz Found
+ {% endif %}
{% endblock %}
diff --git a/yaksh/templates/yaksh/regrade.html b/yaksh/templates/yaksh/regrade.html
deleted file mode 100644
index c70e470..0000000
--- a/yaksh/templates/yaksh/regrade.html
+++ /dev/null
@@ -1,175 +0,0 @@
-{% extends "manage.html" %}
-
-{% block pagetitle %} Grader {% endblock pagetitle %}
-
-{% block content %}
-
-
-
-
-
-
-
-
-
Regrade
-
- Question wise regrade
- You can regrade a question for all answerpapers for a given quiz.
- Quiz wise regrade
- You can regrade an answerpaper for a quiz or a question for the same.
- User wise regrade
- You can regrade an answerpaper for an user or a question for the same.
-
-
-
-
- {% for course in courses %}
-
-
-
-
-
- {% for quiz in course.get_quizzes %}
-
Quiz: {{ quiz }}
-
- {% with questionpaper=quiz.questionpaper_set.get %}
-
Questions:
-
- {% for question in questionpaper.fixed_questions.all %}
- {{ question.summary }}
- Regrade
-
- {% endfor %}
- {% for random_set in questionpaper.random_questions.all %}
- {% for question in random_set.questions.all %}
- {{ question.summary }}
- Regrade
-
- {% endfor %}
- {% endfor %}
-
- {% endwith %}
-
- {% endfor %}
-
-
-
-
- {% endfor %}
-
-
-
-
-
- {% for course in courses %}
-
-
-
-
-
- {% for quiz in course.get_quizzes %}
-
Quiz: {{ quiz }}
-
-
- {% for answerpaper in quiz.questionpaper_set.get.answerpaper_set.all %}
-
- Username: {{ answerpaper.user.username }}; Name: {{ answerpaper.user.get_full_name }}; Attempt Number: {{ answerpaper.attempt_number}}
- Regrade whole paper
-
-
- {% for question in answerpaper.questions.all %}
- {{ question.summary }}
- Regrade
-
- {% endfor %}
-
- {% endfor %}
-
-
- {% endfor %}
-
-
-
-
- {% endfor %}
-
-
-
-
-
-
- {% for course in courses %}
-
-
-
-
- {% for user in course.students.all %}
-
Answer Papers for {{ user.get_full_name }}
-
-
- {% for answerpaper in user.answerpaper_set.all %}
- Quiz: {{answerpaper.question_paper.quiz.description }}; Attempt Number: {{ answerpaper.attempt_number }}
- Regrade whole paper
-
-
- {% for question in answerpaper.questions.all %}
- {{ question.summary }}
- Regrade
-
- {% endfor %}
-
- {% endfor %}
-
-
- {% endfor %}
-
-
-
- {% endfor %}
-
-
-
-
-
-
-
-{% if details %}
-
-
-
- {% for detail in details %}
- {% if detail.0 %}
-
- Graded Successfully
- {% else%}
-
- Did not Grade
- {% endif %}
- {{ detail.1|linebreaks }}
-
- {% endfor %}
-
-
-
- {% endif %}
-
-{% endblock %}
diff --git a/yaksh/templates/yaksh/user_data.html b/yaksh/templates/yaksh/user_data.html
index 6547851..6252fb3 100644
--- a/yaksh/templates/yaksh/user_data.html
+++ b/yaksh/templates/yaksh/user_data.html
@@ -33,11 +33,6 @@
{% endwith %}
-
-
- Grade User
-
-
{% for paper in data.papers %}
Attempt Number:
diff --git a/yaksh/templates/yaksh/view_notifications.html b/yaksh/templates/yaksh/view_notifications.html
new file mode 100644
index 0000000..72f90f8
--- /dev/null
+++ b/yaksh/templates/yaksh/view_notifications.html
@@ -0,0 +1,60 @@
+{% extends template %}
+{% block title %} Notifications {% endblock %}
+{% block pagetitle %} Notifications {% endblock %}
+
+{% block main %}
+
+ {% if messages %}
+ {% for message in messages %}
+
+
+
+
+ {{ message }}
+
+ {% endfor %}
+ {% endif %}
+ {% if notifications %}
+
+ {% else %}
+
+
+
No Notifications Found
+
+ {% endif %}
+
+{% endblock %}
\ No newline at end of file
diff --git a/yaksh/urls.py b/yaksh/urls.py
index bdc3330..52c196b 100644
--- a/yaksh/urls.py
+++ b/yaksh/urls.py
@@ -1,4 +1,5 @@
from django.conf.urls import url
+from django.urls import path
from yaksh import views
urlpatterns = [
@@ -144,17 +145,14 @@ urlpatterns = [
name="download_questions"),
url(r'^manage/upload_questions/$', views.show_all_questions,
name="upload_questions"),
- url(r'^manage/grader/$', views.grader, name='grader'),
- url(r'^manage/regrade/question/(?P\d+)/(?P\d+)/$',
- views.regrade, name='regrade'),
- url(r'^manage/regrade/questionpaper/(?P\d+)/'
- '(?P\d+)/(?P\d+)/$',
- views.regrade, name='regrade'),
- url(r'^manage/regrade/answerpaper/(?P\d+)/'
- '(?P\d+)/(?P\d+)/$',
- views.regrade, name='regrade'),
- url(r'^manage/regrade/paper/(?P\d+)/(?P\d+)/$',
- views.regrade, name='regrade'),
+ url(r'^manage/regrade/paper/question/(?P\d+)/'
+ '(?P\d+)/(?P\d+)/$',
+ views.regrade, name='regrade_by_quiz'),
+ url(r'^manage/regrade/user/(?P\d+)/(?P\d+)/'
+ '(?P\d+)/$', views.regrade, name='regrade_by_user'),
+ url(r'^manage/regrade/user/question/(?P\d+)/'
+ '(?P\d+)/(?P\d+)/'
+ '(?P\d+)/', views.regrade, name='regrade_by_question'),
url(r'^manage/(?Pgodmode|usermode)/(?P\d+)/'
'(?P\d+)/$', views.test_quiz, name="test_quiz"),
url(r'^manage/create_demo_course/$', views.create_demo_course,
@@ -205,4 +203,10 @@ urlpatterns = [
views.course_teachers, name="course_teachers"),
url(r'^manage/download/course/progress/(?P\d+)',
views.download_course_progress, name="download_course_progress"),
+ path('view/notifications', views.view_notifications,
+ name="view_notifications"),
+ path('mark/notifications/',
+ views.mark_notification, name="mark_notification"),
+ path('mark/notifications', views.mark_notification,
+ name="mark_notification"),
]
diff --git a/yaksh/views.py b/yaksh/views.py
index 9efcbe9..10b0e08 100644
--- a/yaksh/views.py
+++ b/yaksh/views.py
@@ -52,6 +52,8 @@ from .file_utils import extract_files, is_csv
from .send_emails import (send_user_mail,
generate_activation_key, send_bulk_mail)
from .decorators import email_verified, has_profile
+from .tasks import regrade_papers
+from notifications_plugin.models import Notification
def my_redirect(url):
@@ -439,6 +441,7 @@ def prof_manage(request, msg=None):
courses = Course.objects.get_queryset().filter(
Q(creator=user) | Q(teachers=user),
is_trial=False).distinct().order_by("-active")
+
paginator = Paginator(courses, 20)
page = request.GET.get('page')
courses = paginator.get_page(page)
@@ -1268,18 +1271,6 @@ def monitor(request, quiz_id=None, course_id=None):
if not is_moderator(user):
raise Http404('You are not allowed to view this page!')
- if quiz_id is None:
- courses = Course.objects.filter(
- Q(creator=user) | Q(teachers=user),
- is_trial=False
- ).order_by("-active").distinct()
- paginator = Paginator(courses, 30)
- page = request.GET.get('page')
- courses = paginator.get_page(page)
- context = {
- "papers": [], "objects": courses, "msg": "Monitor"
- }
- return my_render_to_response(request, 'yaksh/monitor.html', context)
# quiz_id is not None.
try:
quiz = get_object_or_404(Quiz, id=quiz_id)
@@ -1716,7 +1707,7 @@ def download_quiz_csv(request, course_id, quiz_id):
@login_required
@email_verified
def grade_user(request, quiz_id=None, user_id=None, attempt_number=None,
- course_id=None):
+ course_id=None, extra_context=None):
"""Present an interface with which we can easily grade a user's papers
and update all their marks and also give comments for each paper.
"""
@@ -1775,6 +1766,7 @@ def grade_user(request, quiz_id=None, user_id=None, attempt_number=None,
context = {
"data": data,
"quiz_id": quiz_id,
+ "quiz": quiz,
"users": user_details,
"attempts": attempts,
"user_id": user_id,
@@ -1801,7 +1793,8 @@ def grade_user(request, quiz_id=None, user_id=None, attempt_number=None,
course_id=course.id, user_id=user.id)
if course_status.exists():
course_status.first().set_grade()
-
+ if extra_context:
+ context.update(extra_context)
return my_render_to_response(request, 'yaksh/grade_user.html', context)
@@ -2057,56 +2050,31 @@ def create_demo_course(request):
@login_required
@email_verified
-def grader(request, extra_context=None):
- user = request.user
- if not is_moderator(user):
- raise Http404('You are not allowed to view this page!')
- courses = Course.objects.filter(is_trial=False)
- user_courses = list(courses.filter(creator=user)) + \
- list(courses.filter(teachers=user))
- context = {'courses': user_courses}
- if extra_context:
- context.update(extra_context)
- return my_render_to_response(request, 'yaksh/regrade.html', context)
-
-
-@login_required
-@email_verified
-def regrade(request, course_id, question_id=None, answerpaper_id=None,
- questionpaper_id=None):
+def regrade(request, course_id, questionpaper_id, question_id=None,
+ answerpaper_id=None):
user = request.user
course = get_object_or_404(Course, pk=course_id)
if not is_moderator(user) or (course.is_creator(user) and
course.is_teacher(user)):
raise Http404('You are not allowed to view this page!')
+ questionpaper = get_object_or_404(QuestionPaper, pk=questionpaper_id)
details = []
- if answerpaper_id is not None and question_id is None:
- answerpaper = get_object_or_404(AnswerPaper, pk=answerpaper_id)
- for question in answerpaper.questions.all():
- details.append(answerpaper.regrade(question.id))
- course_status = CourseStatus.objects.filter(
- user=answerpaper.user, course=answerpaper.course)
- if course_status.exists():
- course_status.first().set_grade()
- if questionpaper_id is not None and question_id is not None:
- answerpapers = AnswerPaper.objects.filter(
- questions=question_id,
- question_paper_id=questionpaper_id, course_id=course_id)
- for answerpaper in answerpapers:
- details.append(answerpaper.regrade(question_id))
- course_status = CourseStatus.objects.filter(
- user=answerpaper.user, course=answerpaper.course)
- if course_status.exists():
- course_status.first().set_grade()
- if answerpaper_id is not None and question_id is not None:
- answerpaper = get_object_or_404(AnswerPaper, pk=answerpaper_id)
- details.append(answerpaper.regrade(question_id))
- course_status = CourseStatus.objects.filter(user=answerpaper.user,
- course=answerpaper.course)
- if course_status.exists():
- course_status.first().set_grade()
-
- return grader(request, extra_context={'details': details})
+ quiz = questionpaper.quiz
+ data = {"user_id": user.id, "course_id": course_id,
+ "questionpaper_id": questionpaper_id, "question_id": question_id,
+ "answerpaper_id": answerpaper_id, "quiz_id": quiz.id,
+ "quiz_name": quiz.description, "course_name": course.name
+ }
+ regrade_papers.delay(data)
+ msg = dedent("""
+ {0} is submitted for re-evaluation. You will receive a
+ notification for the re-evaluation status
+ """.format(quiz.description)
+ )
+ messages.info(request, msg)
+ return redirect(
+ reverse("yaksh:grade_user", args=[quiz.id, course_id])
+ )
@login_required
@@ -3191,3 +3159,38 @@ def download_course_progress(request, course_id):
for student in stud_details:
writer.writerow(student)
return response
+
+
+@login_required
+@email_verified
+def view_notifications(request):
+ user = request.user
+ notifcations = Notification.objects.get_unread_receiver_notifications(
+ user.id
+ )
+ if is_moderator(user):
+ template = "manage.html"
+ else:
+ template = "user.html"
+ context = {"template": template, "notifications": notifcations,
+ "current_date_time": timezone.now()}
+ return my_render_to_response(
+ request, 'yaksh/view_notifications.html', context
+ )
+
+
+@login_required
+@email_verified
+def mark_notification(request, message_uid=None):
+ user = request.user
+ if message_uid:
+ Notification.objects.mark_single_notification(
+ user.id, message_uid, True
+ )
+ else:
+ if request.method == 'POST':
+ msg_uuids = request.POST.getlist("uid")
+ Notification.objects.mark_bulk_msg_notifications(
+ user.id, msg_uuids, True)
+ messages.success(request, "Marked notifcation(s) as read")
+ return redirect(reverse("yaksh:view_notifications"))
--
cgit