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

Add a new service to allow Anonymous Users to vote on xblock-poll #314

Merged
merged 3 commits into from
Nov 23, 2023
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
3 changes: 2 additions & 1 deletion lms/djangoapps/courseware/module_render.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
from lms.djangoapps.courseware.model_data import DjangoKeyValueStore, FieldDataCache
from edxmako.shortcuts import render_to_string
from lms.djangoapps.courseware.field_overrides import OverrideFieldData
from lms.djangoapps.courseware.services import UserStateService
from lms.djangoapps.courseware.services import UserStateService, AnonymousUserPollService
from lms.djangoapps.grades.api import GradesUtilService
from lms.djangoapps.grades.api import signals as grades_signals
from lms.djangoapps.lms_xblock.field_data import LmsFieldData
Expand Down Expand Up @@ -819,6 +819,7 @@ def rebind_noauth_module_to_user(module, real_user):
'gating': GatingService(),
'grade_utils': GradesUtilService(course_id=course_id),
'user_state': UserStateService(),
'anonymous_user_poll': AnonymousUserPollService(),
},
get_user_role=lambda: get_user_role(user, course_id),
descriptor_runtime=descriptor._runtime, # pylint: disable=protected-access
Expand Down
53 changes: 53 additions & 0 deletions lms/djangoapps/courseware/services.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
from lms.djangoapps.courseware.models import StudentModule
from student.models import get_user_by_username_or_email

from xblock.reference.plugins import Service
from lms.djangoapps.courseware.models import XModuleUserStateSummaryField


class UserStateService(object):
"""
Expand Down Expand Up @@ -39,3 +42,53 @@ def get_state_as_dict(self, username_or_email, block_id):
return json.loads(student_module.state)
except StudentModule.DoesNotExist:
return {}




class AnonymousUserPollService(Service):
"""
Service to allow anonymous users to vote on xblock polls
"""

def vote(self, choice, result, usage_id):
"""
Updates the tally in the database for the anonymous users votes on polls
Also, clears the dirty fields so the LMS does not try to update as well

Args:
choice (string): The choice of vote selected by user
result (dict): The response dictionary to return to frontend
usage_id (UsageKey): usage_id of the poll

Returns:
dict: Return the result to the handler function
"""
tally = self.get_tally(usage_id)
# If tally does not exist, do not update and allow the LMS to handle it
if not tally:
return result, False
tally[choice] += 1
# Update tally in the db
XModuleUserStateSummaryField.objects.filter(usage_id=usage_id, field_name="tally").update(value=json.dumps(tally))
result['success'] = True
result['can_vote'] = True
result['submissions_count'] = 1

return result, True

def get_tally(self, usage_id):
"""
Get the tally of the poll from the database

Args:
usage_id (UsageKey): the usage_id of the poll to filter by

Returns:
dict: Tally of the poll that calls this function
"""
query_set = XModuleUserStateSummaryField.objects.filter(usage_id=usage_id, field_name="tally").first()
if not query_set:
return None
# Tally is a dict stored as string, convert to json
return json.loads(query_set.value)