Files
edx-platform/common/djangoapps/student/management/commands/bulk_unenroll.py
Awais Qureshi 2dcaf9d5a6 BOM-2375-student-part1
pyupgrade in student app.
2021-03-08 18:29:25 +05:00

90 lines
3.0 KiB
Python

"""
Un-enroll Bulk users course wide as well as specified in csv
"""
import logging
import unicodecsv
from django.core.management.base import BaseCommand
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
from common.djangoapps.student.models import CourseEnrollment, BulkUnenrollConfiguration
logger = logging.getLogger(__name__) # pylint: disable=invalid-name
class Command(BaseCommand):
"""
Management command to un-enroll course enrollments at once.
"""
help = """"
Un-enroll bulk users from the courses.
It expect that the data will be provided in a csv file format with
first row being the header and columns will be either one of the
following:
| username | course_id |
OR
| course_id |
Example:
$ ... bulk_unenroll --csv_path=foo.csv
$ ... bulk_unenroll --csv_path=foo.csv --commit
"""
commit = False
def add_arguments(self, parser):
parser.add_argument(
'-p', '--csv_path',
metavar='csv_path',
dest='csv_path',
required=False,
help='Path to CSV file.')
parser.add_argument(
'--commit',
action='store_true',
help='Save the changes, without this flag only a dry run will be performed and nothing will be changed')
def handle(self, *args, **options):
csv_path = options['csv_path']
self.commit = options['commit']
if csv_path:
with open(csv_path, 'rb') as csv_file:
self.unenroll_users_from_csv(csv_file)
else:
csv_file = BulkUnenrollConfiguration.current().csv_file
self.unenroll_users_from_csv(csv_file)
def unenroll_users_from_csv(self, csv_file):
"""
Un-enroll the given set of users provided in csv
"""
reader = list(unicodecsv.DictReader(csv_file))
for row in reader:
self.unenroll_learners(row.get('course_id'), username=row.get('username', None))
def unenroll_learners(self, course_id, username=None):
"""
Un-enroll learners from course_id(s)
"""
try:
course_key = CourseKey.from_string(course_id)
except InvalidKeyError:
msg = f'Invalid course id {course_id}, skipping un-enrollement.'
logger.warning(msg)
return
enrollments = CourseEnrollment.objects.filter(course_id=course_key, is_active=True)
if username:
enrollments = enrollments.filter(user__username=username)
logger.info(f"Processing [{course_id}] with [{enrollments.count()}] enrollments.")
if self.commit:
for enrollment in enrollments:
enrollment.update_enrollment(is_active=False, skip_refund=True)
logger.info(
"User [{}] have been successfully unenrolled from the course: {}".format(
enrollment.user.username, course_key
)
)