forked from zimka/course_shifts
-
Notifications
You must be signed in to change notification settings - Fork 0
zimka/master -- initial #2
Closed
Closed
Changes from 11 commits
Commits
Show all changes
36 commits
Select commit
Hold shift + click to select a range
87b38c4
Course Shift Models
zimka c21a02c
Models improvements
zimka 6852a6f
Basic tests passed
zimka 9a6b110
README added
zimka 520ff08
Model update, tests for settings
zimka f8cf126
Added manager for operations on user
zimka 7c9e565
Manager update and manager tests
zimka f137170
Review fixes
zimka dcb6a53
Logging, formating and small fix
zimka a5bcd51
Manager and tests refactoring
zimka 8591f0a
Manager and tests refactoring 2
zimka cbfae55
Manager and test refactoring 3
zimka 22b261a
Field Override Provider added
zimka b940d4f
Settings serializer and api added
zimka a008c6f
Added settings edit view
zimka 006febb
Added list and detail api for course shifts
zimka 89e9b5b
Added shift edit view; GET part
zimka 83f872d
Added shift edit view; PATCH, POST and DELETE parts
zimka 2b80f45
Added user api and view
zimka 7b8d665
UI fixes
zimka d24cb92
Edx files that are modified to make feature work
zimka 99b441c
Added student shift enrollment at course enrollment
zimka 49859b1
Fix error messages disappear after view re-rendering
zimka d7f2a9b
README update, shift start_date change bug fix
zimka b5dfcd8
Merge pull request #3 from zimka/develop
martynovp 9ecab23
Create setup.py
martynovp e9403e6
Move app into course_shifts
martynovp a634269
Code style fixes
martynovp 1da7990
Migrations
martynovp 0f5ce6e
Instructor dahboard templates
martynovp 2fff757
Add course field check for feature enabling
zimka c01427b
Change from djangoapp to package
zimka 2e33fbc
Api permission change, add 'get user shift'
zimka 0d1f011
Fix provider error for FieldData other than Lms
zimka 6ac8ac8
Readme, docstrings and tests update
zimka 5795675
Remove edx static from repo
zimka File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
Description | ||
----------- | ||
This is django app based on OpenEdx Ficus release `"open-release/ficus.2" | ||
<https://github.com/edx/edx-platform/tree/open-release/ficus.2>`_ | ||
that should provide the way for student to move forward all due dates for given course according to the rules defined by the course staff. | ||
Similar feature at the Coursera is called "Session Switch": when activated, course has several sessions with the same content but different deadlines and student can switch them at will. This feature can be useful when student have missed some deadlines but still wants to | ||
finish the course and get credit. | ||
|
||
There are several differences between this app and course rerun/CCX: | ||
|
||
1. The content of the course is the same in all course shifts. Therefore it should be easier for staff to upgrade such course if necessary. It also doesn't spend additional resources. | ||
|
||
2. Forum is shared between all course shifts. | ||
|
||
3. Students can use this function when they want, and therefore course schedule becomes more flexible. | ||
|
||
Details | ||
------- | ||
Feature is implemented via additional FieldOverrideProvider and CourseUserGroups, similar to the way it's done for 'INDIVIDUAL_DUE_DATES' feature. | ||
Every course student is associated with some CourseUserGroup, and provider checks for membership and shift due dates accordingly. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
from datetime import timedelta | ||
from logging import getLogger | ||
|
||
from django.utils import timezone | ||
from models import CourseShiftGroup, CourseShiftGroupMembership, CourseShiftSettings | ||
|
||
|
||
date_now = lambda: timezone.now().date() | ||
log = getLogger(__name__) | ||
|
||
|
||
class CourseShiftManager(object): | ||
""" | ||
Provides the interface to perform operations on users and | ||
course shifts: user transfer between shifts, due date calculation, | ||
active shifts etc. | ||
""" | ||
|
||
def __init__(self, course_key): | ||
self.course_key = course_key | ||
self.settings = CourseShiftSettings.get_course_settings(self.course_key) | ||
|
||
@property | ||
def is_shift_enabled(self): | ||
return self.settings.is_shift_enabled | ||
|
||
def get_user_shift(self, user, course_key): | ||
""" | ||
Returns user's shift group for given course. | ||
""" | ||
if not self.settings.is_shift_enabled: | ||
return | ||
|
||
membership = CourseShiftGroupMembership.get_user_membership(user, course_key) | ||
if membership: | ||
return membership.course_shift_group | ||
|
||
def get_all_shifts(self): | ||
return CourseShiftGroup.get_course_shifts(self.course_key) | ||
|
||
def get_active_shifts(self, user=None): | ||
""" | ||
Returns shifts that are are active at this moment according to the settings, | ||
i.e. enrollment have started but haven't finished yet. | ||
If user is given and he has membership all started shifts are considered | ||
as active | ||
""" | ||
if not self.settings.is_shift_enabled: | ||
return [] | ||
all_shifts = CourseShiftGroup.get_course_shifts(self.course_key) | ||
if not all_shifts: | ||
return [] | ||
|
||
now = date_now() | ||
active_shifts = [] | ||
current_start_date = None | ||
if user: | ||
current_group = self.get_user_shift(user, self.course_key) | ||
current_start_date = current_group and current_group.start_date | ||
|
||
for shift in all_shifts: | ||
enroll_start = shift.start_date - timedelta(days=self.settings.enroll_before_days) | ||
enroll_finish = shift.start_date + timedelta(days=self.settings.enroll_after_days) | ||
if current_start_date and current_start_date < shift.start_date: | ||
enroll_finish = now | ||
|
||
if enroll_start < now <= enroll_finish: | ||
active_shifts.append(shift) | ||
|
||
return active_shifts | ||
|
||
def sign_user_on_shift(self, user, shift, course_key): | ||
""" | ||
Transfers user to given shift group. User's enrollment is not checked | ||
because at course enrollment user should be firstly transfered to shift and | ||
only then enrolled on course. | ||
:param user: user to enroll on shift | ||
:param shift: CourseShiftGroup to enroll | ||
:param course_key: to which course shift_to (and shift_from if not None) belongs | ||
""" | ||
if shift.course_key != course_key: | ||
raise ValueError("Shift's course_key: '{}', given course_key:'{}'".format( | ||
str(shift.course_key), | ||
str(course_key) | ||
)) | ||
|
||
membership = CourseShiftGroupMembership.get_user_membership(user=user, course_key=course_key) | ||
shift_from = membership and membership.course_shift_group | ||
if shift_from == shift: | ||
return membership | ||
|
||
active_shifts = self.get_active_shifts(user) | ||
if shift not in active_shifts: | ||
raise ValueError("Shift {} is not in active shifts: {}".format( | ||
str(shift), | ||
str(active_shifts) | ||
)) | ||
|
||
return CourseShiftGroupMembership.transfer_user(user, shift_from, shift) | ||
|
||
def create_shift(self, start_date): | ||
""" | ||
Creates plan with given start date. | ||
""" | ||
if not self.settings.is_shift_enabled: | ||
return ValueError("Can't create shift: feature is turned off for course") | ||
if self.settings.is_autostart: | ||
raise ValueError("Can't create shift in autostart mode") | ||
|
||
name = self.settings.build_name(start_date) | ||
days_shift = self.settings.calculate_days_add(start_date) | ||
shift, created = CourseShiftGroup.create( | ||
name=name, | ||
course_key=self.course_key, | ||
start_date=start_date, | ||
days_shift=days_shift | ||
) | ||
return shift | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
пустая строка тут нужна :)