def show_quiz(request, course_slug, page_slug): ''' show_Quiz View This view displays a quiz on the screen. The user can then answer the questions and submit the result If the user is trying to view the working_copy, they are shown the regular copy instead. This is to prevent a student from looking at unpublished quizzes. Verifies student has met all prerequisites before displaying questions, if the quiz is hidden. @author Evan Kleist ''' page_slug = safeSlug(page_slug) course = Course.objects.get(slug=course_slug) quiz = Quiz.objects.get(slug=page_slug, course=course) # If the quiz is hidden, make sure prerequisites have been met if (quiz.hidden and not checkPrerequisites(quiz, request.user)): return master_rtr(request, 'page/denied.html', {'course_slug':course_slug, 'prereqs':True}) quizTitle = quiz.text questions = quiz.questions.all().order_by("order") return master_rtr(request, 'page/quiz/viewQuiz.html', \ {'course_slug':course_slug, \ 'quizTitle':quizTitle, \ 'page_slug':page_slug, 'questions':questions})
def display_course_stats(request, course_slug): ''' Displays stats for a given course @author Andrew J. Musselman ''' #Make sure the course is a real course in the DBMS try: course = Course.objects.get(slug=course_slug) except Course.DoesNotExist: raise Http404 #make sure the user has premissions to view stats. enrollment = request.user.enrollments.get(course=course) if enrollment.stats: bestQuizAggregates = getQuizAllAggregates(course) bestUserAggregates = getUserAllAggregates(course) stat_data = {'course':course,\ 'bestQuizAggregates':bestQuizAggregates,\ 'bestUserAggregates':bestUserAggregates, \ 'course_slug':course_slug} return master_rtr(request, 'stats/show_course_stats.html', stat_data) else: #Or else, you don't have premeission to view stats return master_rtr(request, 'stats/invalid_user_premissions.html', \ {'course': course, \ 'course_slug': course_slug})
def add_user(request, course_slug): ''' Handles the commands given by the add user screen pre: none post: db'.contains(user) == true and db'.length == db.length + 1 if !db.contains(user) @author Jon Inloes ''' #retrieve the course course = Course.objects.get(slug=course_slug) #retrieve the currently logged in user enrollment = request.user.enrollments.get(course=course) #check the logged in user's permissions if enrollment.manage: #if the request method was a post determine the command that was given if request.method == 'POST': #if the command was an add try to add the user if request.POST['command'] == 'add': usr = request.POST['username'] try: #if the user exists add it user = User.objects.get(username=usr) addUser(course, user) except User.DoesNotExist: #if the user does not exist print error message return master_rtr(request, 'adduser/failed.html', \ {'course_slug':course_slug, \ 'course': course}) #show the roster screen return HttpResponseRedirect(reverse('courses.views.show_roster', args=[course_slug])) elif request.POST['command'] == 'search': #if the command was a search, search for the user firstname = request.POST['firstname'].strip() lastname = request.POST['lastname'].strip() users = User.objects.filter(first_name = firstname, last_name = lastname) return master_rtr(request, 'adduser/search.html', \ {'course_slug': course_slug, \ 'course':course, \ 'users':users, \ 'firstname': firstname, \ 'lastname': lastname}) else: #display the adduser page return master_rtr(request,'adduser/index.html', {'course_slug': course_slug, 'course': course, 'url': request.path}) else: return master_rtr(request, 'roster/invalid_permissions.html', \ {'course': course, \ 'course_slug': course_slug})
def submitQuiz(request, course_slug, page_slug): ''' submitQuiz View This view is related to the show_quiz view. It first checks to make sure the user has met any prerequisites before being bale to submit the quiz. It also verifies the quiz and course actually exist in the database. It then displays a page displaying their score, and the corresponding path for their score, if one exists. @author Evan Kleist ''' page_slug = safeSlug(page_slug) # Make sure the course actually exists in the database try: course = Course.objects.get(slug=course_slug) except Course.DoesNotExist: raise Http404 # Make sure the quiz actually exists in the database try: quiz = Quiz.objects.get(slug=page_slug, course=course) except Quiz.DoesNotExist: raise Http404 #if the course is private then check that the user is enrolled and has view permissions if course.private: if not request.user.is_authenticated(): return master_rtr(request, 'page/denied.html', {'course_slug':course_slug, 'enrolled':False, 'edit':False, 'loggedIn':False}) try:#try to get the enrollment for this user and check view permission e = quiz.course.roster.get(user=request.user) if not e.view: return master_rtr(request, 'page/denied.html', {'course_slug':course_slug, 'enrolled':True, 'edit':False, 'loggedIn':True}) except ObjectDoesNotExist: # user is not enrolled in this course return master_rtr(request, 'page/denied.html', {'course_slug':course_slug, 'enrolled':False, 'edit':False, 'loggedIn':True}) # Make sure prerequisites are satisfied if (not checkPrerequisites(quiz, request.user)): return master_rtr(request, 'page/denied.html', {'course_slug':course_slug, 'course_slug':course_slug, 'prereqs':True}) maxScore = len(quiz.questions.all()) score = 0 percentage = 100 if (request.method == "POST"): score = scoreQuiz(quiz, request, course_slug, page_slug) if (not (maxScore == 0)): percentage = round(float(score) / float(maxScore), 2) * 100 try: path = matchPath(quiz, percentage) except NoMatchingPath: path = False return master_rtr(request, 'page/quiz/submitQuiz.html', \ {'course_slug':course_slug, \ 'page_slug':page_slug, 'pid':page_slug, 'score':score, 'maxScore':maxScore, 'percentage':percentage, 'path':path})
def create_lesson(request, course_slug, page_slug): ''' Creates a new lesson and shows the user the edit page but does not save the lesson to the database @author Matthew Tytel ''' #enforcing permissions try: e = Enrollment.objects.get(course__slug = course_slug, user = request.user) except Enrollment.DoesNotExist: return custom_403(request, "User cannot create a lesson in the course because the user is not enrolled in this course") if not e.edit: return custom_403(request, "User cannot create a lesson in the course because the user does not have edit permissions on the course") if request.method == "POST" and "Save" in request.POST: name = request.POST["lessonname"].strip() #create a lesson (don't save) this will allow the len < 1 case to #save the content that the user entered, and display course name lesson = CreateLesson(name) lesson.workingCopy = lesson.content = request.POST["content"] lesson.course = Course.objects.get(slug=course_slug) if len(name) < 1: return master_rtr(request, 'page/lesson/edit_lesson.html', \ {'course_slug':course_slug, 'page_slug': page_slug, 'course':course_slug, 'message':'Lesson names must be non-empty', 'lesson':lesson, 'new':True}) if saveNewLesson(request.POST['lessonname'], request.POST['content'], course_slug, page_slug) == 0: return HttpResponseRedirect(reverse('pages.views.show_page', args=[course_slug, lesson.slug])) else: return master_rtr(request, 'page/lesson/edit_lesson.html', \ {'course_slug':course_slug, 'page_slug': page_slug, 'course':course_slug, 'message':'A lesson with that name already exists', 'lesson':lesson, 'new':True}) lesson = CreateLesson('') return master_rtr(request, 'page/lesson/edit_lesson.html', \ {'course_slug':course_slug, \ 'course':course_slug, \ 'page_slug':page_slug, \ 'pid':lesson.name, 'new':True})
def create_course(request): ''' Creates a new course if course name is long enough and the coursename is unique. If not gives an error. Also sets a course to private if the checkbox was checked. @author John Hartquist @author Matthew Tytel ''' data = {} if request.method == "POST": name = request.POST['coursename'].strip() private = False; if "private" in request.POST: private = True; # some basic validation if len(name) < 1: data['message'] = 'A Course name must be at least 1 characters.' else: try: sid = transaction.savepoint() c = CreateCourse(name, User.objects.get(username=request.user.username), private) transaction.savepoint_commit(sid) return HttpResponseRedirect(reverse('pages.views.edit_page', args=[c.slug, c.slug])) except IntegrityError: transaction.savepoint_rollback(sid) data['message'] = 'A Course with that name already exists.' return master_rtr(request, 'courses/create_course.html', data)
def edit_page(request, course_slug, page_slug): ''' This view verifies that a valid course/page pair is given, then verifies that the user has edit permissions, finally it calls the quiz/lesson edit view depending on what kind of page is given. @author Russell Mezzetta @author Evan Kleist ''' #check if the course is a real course in the database try: c = Course.objects.get(slug=course_slug) except Course.DoesNotExist: raise Http404 #check if the page is a real page in the database try: page = c.pages.get(slug=page_slug) except Page.DoesNotExist: raise Http404 #check that user has permissions (edit) if not request.user.is_authenticated(): return master_rtr(request, 'page/denied.html', {'course':course_slug, 'enrolled':False, 'edit':True, 'loggedIn':False}) try: #get user's enrollment to check permissions e = request.user.enrollments.get(course = c) except ObjectDoesNotExist: return master_rtr(request, 'page/denied.html', {'course':course_slug, 'enrolled':False, 'edit':True, 'loggedIn':True}) if not e.edit: return master_rtr(request, 'page/denied.html', {'course':course_slug, 'enrolled':True, 'edit':True, 'loggedIn':True}) #cast the page to a lesson or quiz then call show on it try: page = page.lesson #save this data to UserLastViewed object saveLastViewed(request.user, course_slug, page_slug, True) return edit_lesson(request, course_slug, page_slug) except Lesson.DoesNotExist: try: page = page.quiz #save this data to UserLastViewed object saveLastViewed(request.user, course_slug, page_slug, True) return edit_quiz(request, course_slug, page_slug) except Quiz.DoesNotExist: return Http404
def show_roster(request, course_slug): ''' Displays the roster pre: user.isLoggedIn == true post: if user.manage then show(roster/index.html) else show(roster/invalid_permissions.html) @author Jon Inloes ''' # It is better to get the enrollment by this method, because in this case # the database searches using Primary Keys, which are indexed, instead of # username, which is not indexed. -mgius #enrollment = Enrollment.objects.get(user__username__exact=request.user.username, course__slug__exact=course_slug) failedList = [] #if there are users that failed to be added from a previous command, then retrieve the list if request.session.has_key('badusers'): failedList = request.session['badusers'] del request.session['badusers'] #retreive the current course try: course = Course.objects.get(slug=course_slug) except Course.DoesNotExist: raise Http404 #retrieve the logged in user enrollment = request.user.enrollments.get(course=course) #check the logged in user's enrollment permissions if enrollment.manage: enrollments = course.roster.all(); return master_rtr(request, 'roster/index.html', \ {'course': course, \ 'enrollments': enrollments, \ 'course_slug': course.slug, 'failedList': failedList}) else: return master_rtr(request, 'roster/invalid_permissions.html', \ {'course': course, \ 'course_slug': course.slug })
def show_profile(request): ''' Displays the profile of the user that is currently logged in @pre user.is_authenticated() == True @post @author John Hartquist ''' #print 'in show_profile' #make sure user is logged in if request.user.is_authenticated(): #check if method was post if (request.method=="POST"): if (request.POST["form"] == "Change E-mail"): status = updateEmail(request) if status == 0: return master_rtr(request, 'user/profile.html', {'user': request.user}) else: return master_rtr(request, 'user/profile.html', {'user': request.user, 'emailError': "Invalid E-mail Address"}) if (request.POST["form"] == "Change Password"): status = changePassword(request) if status == 1: return master_rtr(request, 'user/profile.html', {'user': request.user, 'passError': "Incorrect current password"}) elif status == 2: return master_rtr(request, 'user/profile.html', {'user': request.user, 'passError': "Passwords do not match"}) if (request.POST["form"] == "Delete Account"): return master_rtr(request, 'user/confirmDelete.html') if (request.POST["form"] == "Update Name"): status = updateName(request) if status == 0: return master_rtr(request, 'user/profile.html', {'user': request.user, 'nameMessage':"Update Successful" }) if (request.POST["form"] == "Yes"): status = deleteUser(request) if status == 0: return HttpResponseRedirect(reverse('home.views.show_homepage')) return master_rtr(request, 'user/profile.html', {'user':request.user}) else: return master_rtr(request, 'user/notloggedin.html')
def create_quiz(request, course_slug, page_slug): ''' create_Quiz View This view will create a quiz and take the user to the quiz editor screen. @author John Hartquist ''' #enforcing permissions try: e = Enrollment.objects.get(course__slug = course_slug, user = request.user) except Enrollment.DoesNotExist: return custom_403(request, "User cannot create a quiz in the course because the user is not enrolled in this course") if not e.edit: return custom_403(request, "User cannot create a quiz in the course because the user does not have edit permissions on the course") page_slug = safeSlug(page_slug) if request.method == "POST" and "Create Quiz" in request.POST: course = Course.objects.get(slug=course_slug) name = request.POST['name'] if name == "": return master_rtr(request, 'page/quiz/create-quiz.html', {'message': "You may not enter a blank quiz name"}) #exists = Quiz.objects.get(slug=slugify(name)) try: exists = Quiz.objects.get(slug=slugify(name), course=course) return master_rtr(request, 'page/quiz/create-quiz.html', {'message': "Quiz with this name already exists"}) except: newQuiz = Quiz(course=course, name=name, slug=slugify(name), text=name, upToDate=True) insertLastChildPage(newQuiz, Page.objects.get(slug=page_slug, course=course)) newQuiz = Quiz.objects.get(slug=newQuiz.slug, course=course) workingCopy = Quiz(course=newQuiz.course, name=newQuiz.name, slug=(newQuiz.slug + "_workingCopy"), text=newQuiz.name, left=0, right=0) workingCopy.save() return HttpResponseRedirect(reverse('pages.views.edit_page', args=[course_slug, newQuiz.slug])) else: return master_rtr(request, 'page/quiz/create-quiz.html')
def show_register_new_user(request): ''' This def shows the register new user page @pre request is a requestobject @author Russell Mezzetta ''' if request.method == 'POST': #form was submitted username = request.POST['username'] password = request.POST['password'] vpassword = request.POST['verifypassword'] email = request.POST['email'] firstN = request.POST['firstname'] lastN = request.POST['lastname'] #send form data to registerNewUser function ret = registerNewUser(username, password, vpassword, firstN, lastN, email) if ret == 0: #successful registration #return render_to_response('user/login.html', {'message': "User Registration Successful"}) #TODO create a response like "success!" # attempt to enroll the user in their temporary courses, if possible if "anonCourses" in request.session: user = User.objects.get(username=username) for c in request.session['anonCourses']: addUser(c, user, True) return HttpResponseRedirect(reverse('users.views.show_login')) elif ret == 1: errorMsg = "That username is already taken" elif ret == 2: errorMsg = "Passwords do not match" elif ret == 3: errorMsg = "The username field is empty" elif ret == 4: errorMsg = "The password field is empty" else: #ret == 5 errorMsg = "Either first name or last name field is empty" return master_rtr(request, 'user/register-new-user.html', {'message': errorMsg}) else: return master_rtr(request, 'user/register-new-user.html')
def join_course_request(request): ''' Displays the classes a user can join @author Mark Gius ''' courseid = request.POST['courseid'] course = Course.objects.get(id=courseid) if course.private: view = False redirect = False else: view = True redirect = True if request.user.is_authenticated(): user = User.objects.get(username=request.user.username) if addUser(course, user, view): message = "Congratulations, you have been added to %s." % course if course.private: message += " This is a private course, and your enrollment" message += " is pending." else: message = "You are already enrolled in %s" % course redirect = False else: #anonymous user is joining course if "anonCourses" in request.session: if course in request.session['anonCourses']: message = "You are already enrolled in %s" % course redirect = False else: courses = request.session['anonCourses'] courses.append(course) request.session['anonCourses'] = courses message = "You have been temporarily added to %s. Register to make this enrollment permanent" % course #print(request.session['anonCourses']) else: request.session['anonCourses'] = [course] message = "You have been temporarily added to %s" % str(course) user = "******" return master_rtr(request, 'courses/join_course_status.html', \ {'course':course, 'user':user, 'message':message, \ 'redirect':redirect })
def show_chat(request, course_slug): ''' Shows the chat for the course @author Jon Inloes ''' #retrieve the current course try: course = Course.objects.get(slug=course_slug) except Course.DoesNotExist: raise Http404 return master_rtr(request, 'chat/index.html', {'course_slug': course_slug, 'username': request.user.username, 'course': course})
def manage_pending_requests(request, course_slug): ''' Accepts and denies users in the pending request list for a roster pre: user.isLoggedIn = True post: (for username in acceptList course.enrollments.username.view = True and course.enrollments.length' = course.enrollments.length) (for username in denyList course.enrollments.remove(username) and course.enrollments.length' = course.enrollments.length - denyList.length) @author Jon Inloes ''' #retrieve the course course = Course.objects.get(slug=course_slug) #retrieve the logged in user enrollment = request.user.enrollments.get(course=course) #check the logged in user's permissions if enrollment.manage: acceptList = request.POST.getlist('accept') denyList = request.POST.getlist('deny') course = Course.objects.select_related(depth=2).get(slug=course_slug) enrollments = course.roster.all() #for each enrollment in the accept list set the view permission to true for enrollment in enrollments: user = enrollment.user try: acceptList.index(enrollment.user.username) enrollment.view = True enrollment.save() except ValueError: pass try: denyList.index(enrollment.user.username) removeUser(course,user) except ValueError: pass return HttpResponseRedirect(reverse('courses.views.show_roster', \ args=[course_slug])) else: return master_rtr(request, 'roster/invalid_permissions.html', \ {'course': course, 'course_slug': course.slug})
def remove_question(request, course_slug, page_slug, qNum): ''' remove_question View This view confirms deletion of a question. The user can then choose to delete the question or cancel. Upon confirmation, the user is returned back to the quiz editor. @author Evan Kleist ''' page_slug = safeSlug(page_slug) course = Course.objects.get(slug=course_slug) quiz = Quiz.objects.get(slug=page_slug + "_workingCopy", course=course) question = quiz.questions.get(order=qNum) return master_rtr(request, 'page/quiz/remove_question.html', \ {'course_slug':course_slug, 'page_slug':page_slug, 'question':question})
def delete_quiz(request, course_slug, page_slug): ''' delete_quiz View This view confirms deletion of a quiz. The user can then choose to delete the quiz or cancel. If the user deletes the quiz, they are redirected to the course index page. If the user selects cancel, they are redirected back to the quiz editor. @author Evan Kleist ''' page_slug = safeSlug(page_slug) course = Course.objects.get(slug=course_slug) quiz = Quiz.objects.get(slug=page_slug, course = course) return master_rtr(request, 'page/quiz/delete_quiz.html', \ {'course_slug':course_slug, 'page_slug':page_slug, 'quiz':quiz})
def join_course_form(request): ''' Displays a list of unenrolled courses for a user to request to join. @author Mark Gius ''' if request.user.is_authenticated(): enrollmentIds = [e.course.id for e in request.user.enrollments.all()] courses = Course.objects.exclude(id__in=enrollmentIds) else: #anonymous users cannot see private courses if "anonCourses" in request.session: enrollmentIds = [c.id for c in request.session['anonCourses']] courses = Course.objects.exclude(id__in=enrollmentIds).exclude(private=True) else: courses = Course.objects.exclude(private=True) return master_rtr(request, 'courses/join_course_form.html', \ {'join_courses' : courses})
def add_from_file(request, course_slug): ''' Adds usernames from a text file @author Jon Inloes ''' course = Course.objects.get(slug=course_slug) enrollment = request.user.enrollments.get(course=course) failedList = [] if enrollment.manage: #call addUsersFromFile if the user has manage permission failedList = addUsersFromFile(course, request.FILES) request.session['badusers']=failedList return HttpResponseRedirect(reverse('courses.views.show_roster', \ args=[course_slug])) else: return master_rtr(request, 'roster/invalid_permissions.html', \ {'course': course, 'course_slug': course.slug})
def add_path(request, course_slug, page_slug, errors): ''' add_path View This view allows you to add a path to the quiz. The user can then choose to save the path or cancel. Upon submission or cancelation, the user is returned to the quiz editor. @author Evan Kleist ''' page_slug = safeSlug(page_slug) course = Course.objects.get(slug=course_slug) quiz = Quiz.objects.get(slug=page_slug, course = course) allPages = course.pages.all() pages = [] for p in allPages: if (p.slug == safeSlug(p.slug)): pages.append(p) return master_rtr(request, 'page/quiz/path.html', \ {'course_slug':course_slug, 'page_slug':page_slug, 'pages':pages, 'errors':errors})
def edit_path(request, course_slug, page_slug, errors): ''' edit_path View This view allows you to edit an existing path for the quiz. The user can then choose to save the path or cancel. Upon submission or cancelation, the user is returned back to the edit quiz view. @author Evan Kleist ''' page_slug = safeSlug(page_slug) course = Course.objects.get(slug=course_slug) quiz = Quiz.objects.get(slug=page_slug + "_workingCopy", course=course) allPages = course.pages.all() pages = [] for p in allPages: if (p.slug == safeSlug(p.slug)): pages.append(p) path = quiz.paths.get(lowscore=request.POST["path"]) return master_rtr(request, 'page/quiz/path.html', \ {'course_slug':course_slug, 'page_slug':page_slug, 'pages':pages, 'path':path, 'errors':errors})
def show_logout(request): ''' Logs out the current user @pre @post request.user.is_authenticated() == false @author John Hartquist @author Russell Mezzetta ''' #russ--making logout not really log people out in certain cases username = None lastCourseSlug = None if request.user.is_authenticated() == True: if 'rememberme' in request.session: username = request.user.username #logout flushes the contents of the session/cookie logout(request) if username != None: request.session['username'] = username request.session['rememberme'] = True return master_rtr(request, 'user/logout.html')
def show_login(request): ''' This shows the login page and displays any errors. @pre request is a requestobject @post @author Russell Mezzetta ''' #if the user is still logged in, redirect them to homepage, don't show login if request.user.is_authenticated(): #if 'autologin' in request.session and request.session['autologin'] == True: # return HttpResponseRedirect(reverse('home.views.show_homepage')) return HttpResponseRedirect(reverse('home.views.show_homepage')) if request.method == 'POST': #form was submitted username = request.POST['username'] password = request.POST['password'] #checkboxes don't put anything in post if they are unchecked so we have to do a little #extra work. This involves making a list of the possible checkboxes. checkboxList = request.POST.getlist('anonymous') checkboxList += request.POST.getlist('autologin') checkboxList += request.POST.getlist('rememberme') #set the cookie to expire when browser closes(may be changed below) request.session.set_expiry(0) if "anonymous" in checkboxList: #bypass login #if the session has data in it, set it to false, set cookie to expire when browser closes #if 'autologin' in request.session: # request.session['autologin'] = False #if 'rememberme' in request.session: # request.session['rememberme'] = False #clear the session request.session.flush() return HttpResponseRedirect(reverse('home.views.show_homepage')) #all autologin will do is make sure the cookie doesn't expire on browser close if "autologin" in checkboxList: #set cookie/session to expire in 2 weeks (1209600 is # of seconds in 2 weeks) request.session.set_expiry(1209600) request.session['autologin'] = True #else: # request.session['autologin'] = False if "rememberme" in checkboxList: #save this in their session(auto fill username) request.session.set_expiry(1209600) request.session['rememberme'] = True request.session['username'] = username else: request.session['rememberme'] = False request.session['username'] = "" ret = loginWrapper(request, username, password) if ret == 0: #print "successful login" # grab the "next" var from the GET dict, and redirect there if 'next' in request.GET: return HttpResponseRedirect(request.GET['next']) else: # send em to the index return HttpResponseRedirect(reverse('home.views.show_homepage')) elif ret == 1: # Return an 'invalid login' error message. #print "invalid login" return master_rtr(request, 'user/login.html', {'message': "Please try again, Invalid Username/Password"}) else:#ret == 2: # Return a 'disabled account' error message #print "account marked as inactive" return master_rtr(request, 'user/login.html', {'message': "Account marked as inactive, contact System Admins"}) else: #form has not yet been submitted (first time visiting login page) #check if username is in the session so we can prefill the username field if 'username' in request.session: return master_rtr(request, 'user/login.html', {'loginusername':request.session['username']}) else: return master_rtr(request, 'user/login.html')
def edit_quiz(request, course_slug, page_slug): ''' edit_quiz View This view allows an instructor or other priviledged user to edit a quiz. The instructor can add, modify, or remove questions using their respective fields/buttons. The user can also add, remove, and edit other quiz attributes. The modified quiz is then submitted to the database. @author Evan Kleist ''' page_slug = safeSlug(page_slug) # Make sure the course actually exists in the database try: course = Course.objects.get(slug=course_slug) except Course.DoesNotExist: raise Http404 # Make sure the quiz actually exists in the database try: quiz = Quiz.objects.get(slug=(page_slug), course=course) workingCopy = Quiz.objects.get(slug=(page_slug + "_workingCopy"), course=course) except Quiz.DoesNotExist: raise Http404 allPages = Course.objects.get(slug=course_slug).pages.all() questions = workingCopy.questions.all().order_by("order") prerequisites = workingCopy.prerequisites.all() paths = workingCopy.paths.all().order_by("lowscore") prereqs = [] errors = [] pages = [] for p in allPages: if (p.slug == safeSlug(p.slug)): pages.append(p) for p in prerequisites: prereqs.append(p.requiredQuiz.slug) if (request.method == "POST"): if "Save" in request.POST: r = saveQuiz(request, course_slug, page_slug) page_slug = safeSlug(r["quiz_slug"]) errors = r["errors"] if (len(errors) == 0): return HttpResponseRedirect(reverse('pages.views.show_page', args=[course_slug, page_slug])) elif "Cancel" in request.POST: return HttpResponseRedirect(reverse('pages.views.show_page', args=[course_slug, page_slug])) elif "Delete" in request.POST: return delete_quiz(request, course_slug, page_slug) elif "ConfirmDelete" in request.POST: removeQuiz(quiz) return HttpResponseRedirect(reverse('courses.views.show_course', args=[course_slug])) elif "Move" in request.POST: return HttpResponseRedirect(reverse('pages.views.move_page', args=[course_slug, page_slug])) elif "NewMultQuestion" in request.POST: r = saveQuiz(request, course_slug, page_slug) page_slug = safeSlug(r["quiz_slug"]) errors = r["errors"] if (len(errors) == 0): addMultipleChoiceQuestion(workingCopy) return HttpResponseRedirect(request.path) elif "NewCodeQuestion" in request.POST: r = saveQuiz(request, course_slug, page_slug) page_slug = safeSlug(r["quiz_slug"]) errors = r["errors"] if (len(errors) == 0): addCodeQuestion(workingCopy) return HttpResponseRedirect(request.path) elif "Publish" in request.POST: r = saveQuiz(request, course_slug, page_slug) page_slug = safeSlug(r["quiz_slug"]) errors = r["errors"] if (len(errors) == 0): workingCopy = Quiz.objects.get(slug=(page_slug + "_workingCopy"), course = course) errors = publishQuiz(workingCopy) if (len(errors) == 0): return HttpResponseRedirect(reverse('pages.views.show_page', args=[course_slug, page_slug])) elif "Revert" in request.POST: revertQuiz(workingCopy) return HttpResponseRedirect(reverse('pages.views.show_page', args=[course_slug, page_slug])) elif "AddPath" in request.POST: r = saveQuiz(request, course_slug, page_slug) page_slug = safeSlug(r["quiz_slug"]) errors = r["errors"] if (len(errors) == 0): return add_path(request, course_slug, page_slug, errors) elif "SubmitAddPath" in request.POST: errors = addPath(workingCopy, request, course_slug) if (len(errors) == 0): return HttpResponseRedirect(request.path) else: return add_path(request, course_slug, page_slug, errors) elif "EditPath" in request.POST: r = saveQuiz(request, course_slug, page_slug) page_slug = safeSlug(r["quiz_slug"]) errors = r["errors"] if (len(errors) == 0): if ("path" in request.POST): return edit_path(request, course_slug, page_slug, errors) else: errors.append("You must select a path to edit") elif "SubmitEditPath" in request.POST: errors = editPath(workingCopy, request, course_slug) if (len(errors) == 0): return HttpResponseRedirect(request.path) else: return edit_path(request, course_slug, page_slug, errors) elif "RemovePath" in request.POST: r = saveQuiz(request, course_slug, page_slug) page_slug = safeSlug(r["quiz_slug"]) errors = r["errors"] if (len(errors) == 0): if ("path" in request.POST): errors = removePath(workingCopy, request) if (len(errors) == 0): return HttpResponseRedirect(request.path) else: errors.append("You must select a path to remove") for q in questions: if ("removeQuestion%s" % q.order) in request.POST: r = saveQuiz(request, course_slug, page_slug) page_slug = safeSlug(r["quiz_slug"]) errors = r["errors"] if (len(errors) == 0): return remove_question(request, course_slug, page_slug, q.order) if ("confirmRemoveQuestion%s" % q.order) in request.POST: removeQuestion(q) reorderQuestions(workingCopy) return HttpResponseRedirect(request.path) if (isMultipleChoiceQuestion(q)): q = q.multiplechoicequestion if ("addAnswer%s" % q.order) in request.POST: r = saveQuiz(request, course_slug, page_slug) page_slug = safeSlug(r["quiz_slug"]) errors = r["errors"] if (len(errors) == 0): addAnswer(q) return HttpResponseRedirect(request.path) for a in q.answers.all(): if ("removeAnswerQ%sA%s" % (q.order, a.order)) in request.POST: r = saveQuiz(request, course_slug, page_slug) page_slug = safeSlug(r["quiz_slug"]) errors = r["errors"] if (len(errors) == 0): removeAnswer(q, a) return HttpResponseRedirect(request.path) return master_rtr(request, 'page/quiz/edit_quiz.html', {'course_slug':course_slug, 'page_slug':page_slug, 'pages':pages, 'quiz':workingCopy, 'questions':questions, 'prereqs':prereqs, 'errors':errors, 'paths':paths})
def show_lesson(request, course_slug, page_slug, lessonPage, preview=False): ''' This view displays a lesson to the user @author Russell Mezzetta ''' # To get lessonConent now, you need to retreieve the page from the database, cast it to a lesson, and get the "text" attribute #shouldn't have to try/except because previous calls should guarentee the page exists #check request method for prev/next button if request.method == "POST": if "goToNextPage" in request.POST: #redirect to the next page nextPage = getNextPage(lessonPage) if nextPage != None: #args = [course_slug, nextPage.slug] return HttpResponseRedirect(reverse('pages.views.show_page', args=[course_slug, nextPage.slug])) if "goToPrevPage" in request.POST: #redirect to the prev page prevPage = getPrevPage(lessonPage) if prevPage != None: #args = [course_slug, prevPage.slug] return HttpResponseRedirect(reverse('pages.views.show_page', args=[course_slug, prevPage.slug])) if "quitCourse" in request.POST: course = Course.objects.get(slug=course_slug) return master_rtr(request, 'courses/remove_course.html', {'course':course}) if "confirmQuitCourse" in request.POST: course = Course.objects.get(slug=course_slug) if request.POST['confirmQuitCourse'] == "yes": #remove user enrollment for course if request.user.is_authenticated(): try: e = Enrollment.objects.get(user = request.user, course = course) e.delete() #remove all stats for user in course s = Stat.objects.filter(user = request.user, course = course) s.delete() except ObjectDoesNotExist: return HttpResponseRedirect(reverse('home.views.show_homepage')) else: if course in request.session['anonCourses']: #this may look like extra work but it is necessary to get the #lazy session to actually save the data anon = request.session['anonCourses'] anon.remove(course) request.session['anonCourses'] = anon return HttpResponseRedirect(reverse('home.views.show_homepage')) if preview == False: content = lessonPage.content else: content = lessonPage.workingCopy title = lessonPage.name if request.user.is_authenticated(): try: e = Enrollment.objects.get(course__slug=course_slug, user = request.user) if e.edit: create_enabled = True else: create_enabled = False except Enrollment.DoesNotExist: create_enabled = False else: create_enabled = False return master_rtr(request, 'page/lesson/index.html', \ {'course_slug':course_slug, 'page_slug':page_slug, 'content':content, 'lesson_title':title, 'create_enabled':create_enabled})
def show_page(request, course_slug, page_slug, preview=False): ''' This "view" does error checking to verify that the input course/page exist Then it checks that the user has view permissions if they are required Finally it invokes the lesson or quiz view depending on the type of page @author Russell Mezzetta @author Evan Kleist ''' #check if the course is a real course in the database try: course = Course.objects.get(slug=course_slug) except Course.DoesNotExist: #return HttpResponse("ERROR: BAD URL: The course: %s does not exist" % (course_slug)) raise Http404 #check if the page is a real page in the database try: page = Page.objects.get(slug=page_slug, course=course) except Page.DoesNotExist: #return HttpResponse("ERROR: BAD URL: The course: %s does not contain the page: %s." % (course_slug, page_slug)) raise Http404 #if the course is private then check that the user is enrolled and has view permissions if course.private: if not request.user.is_authenticated(): return master_rtr(request, 'page/denied.html', {'course':course, 'enrolled':False, 'edit':False, 'loggedIn':False}) try:#try to get the enrollment for this user and check view permission e = page.course.roster.get(user=request.user) if not e.view: return master_rtr(request, 'page/denied.html', {'course':course, 'enrolled':True, 'edit':False, 'loggedIn':True}) except ObjectDoesNotExist: # user is not enrolled in this course return master_rtr(request, 'page/denied.html', {'course':course, 'enrolled':False, 'edit':False, 'loggedIn':True}) #if preview is set to true then the user MUST have edit permissions to view #b/c this is viewing the working copy, also user must be logged in if preview == True: try: e = course.roster.get(user=request.user) except ObjectDoesNotExist: return master_rtr(request, 'page/denied.html', {'course':course_slug, 'enrolled':False, 'edit':False, 'loggedIn':True}) #make sure user has view and edit permissions if not e.view or not e.edit: return master_rtr(request, 'page/denied.html', {'course':course_slug, 'enrolled':True, 'edit':False, 'loggedIn':True}) #cast the page to a lesson or quiz then call show on it try: page = page.lesson if request.user.is_authenticated(): #save this data to UserLastViewed object saveLastViewed(request.user, course_slug, page_slug, False) return show_lesson(request, course_slug, page_slug, page, preview) except Lesson.DoesNotExist: try: page = page.quiz if request.user.is_authenticated(): #save this data to UserLastViewed object saveLastViewed(request.user, course_slug, page_slug, False) return show_quiz(request, course_slug, page_slug) except Quiz.DoesNotExist: raise Http404
def move_page(request, course_slug, page_slug): ''' This view allows instructors to move pages around in a course. @pre request is a Request object, other two args are strings, request.user.is_authenticated() @author Russell Mezzetta ''' #check if the course is a real course in the database data = {} data['course_slug'] = course_slug data['page_slug'] = page_slug try: data['course'] = Course.objects.get(slug=course_slug) except Course.DoesNotExist: return custom_404(request, "BAD URL: The course: %s does not exist" % (course_slug)) #check that user has edit permissions on the course try: e = request.user.enrollments.get(course = data['course']) if not e.edit: return custom_403(request, "User does not have edit permissions on the course") except ObjectDoesNotExist: return custom_403(request, "User is not enrolled in the course") #check if the page is a real page in the database try: data['page'] = Page.objects.get(slug=page_slug) except Page.DoesNotExist: return custom_404(request, "ERROR: BAD URL: The course: %s does not contain the page: %s." % (course_slug, page_slug)) #check to make sure that we are not trying to move a course-page if data['page'].left == 1: return custom_404(request, "You may not move the home page of a course") #save a list of all pages in the course EXCEPT the given page and exclude #ignored page values (left<=0 or right<=0) data['pagelist'] = data['course'].pages.all().exclude(slug=page_slug).exclude(left__lte=0).exclude(right__lte=0).order_by('left') if request.method == "POST": if "referencePageID" in request.POST and "siblingOrChild" in request.POST: #get the page specified by refPageID from the data['pagelist'] refPage = None for p in data['pagelist']: if p.slug == request.POST['referencePageID']: refPage = p break #refPage should never be none.... #if refPage == None: # return HttpResponse("error, the previously selected page somehow is no longer in the list of pages in this course") #movePage should be passed lessons or quizzes, #cast refPage and data['page'] appropriately p1 = data['page'] try: #to cast to a lesson p1 = p1.lesson except Lesson.DoesNotExist: #try: #to cast to a quiz p1 = p1.quiz #except Quiz.DoesNotExist: # print "warning -- move_page view, page neither quiz nor lesson" p2 = refPage try: #to cast to a lesson p2 = p2.lesson except Lesson.DoesNotExist: #try: #to cast to a quiz p2 = p2.quiz #except Quiz.DoesNotExist: #print "warning -- move_page view, page neither quiz nor lesson" if request.POST['siblingOrChild'] == "sibling": #move page to be the first sibling of refPage movePage(p1, p2) else: #move the page to be the first child of refPage movePageToParent(p1, p2) #after moving the page, redirect them to the edit view of the page return HttpResponseRedirect(reverse('pages.views.edit_page', args=[p1.course.slug, p1.slug])) return master_rtr(request, 'page/move_page.html', data)
def update_roster(request, course_slug): ''' Updates the roster according to the checkboxes on the page pre:none post: for all enrollments in db changed(enrollment) in db' if not removing then db.length = db'.length @author Jon Inloes ''' #retrieve the course course = Course.objects.get(slug=course_slug) #retrieve the currently logged in user enrollment = request.user.enrollments.get(course=course) #check the logged in user's permissions if enrollment.manage: editList = request.POST.getlist('edit') manageList = request.POST.getlist('manage') statsList = request.POST.getlist('stats') removeList = request.POST.getlist('remove') enrollments = Enrollment.objects.select_related(depth=1).\ filter(course__slug__exact=course_slug) #for each enrollment for enrollment in enrollments: changed = False try: editList.index(enrollment.user.username) #if the user does not have edit permission, then set the permission to true if not enrollment.edit: enrollment.edit = True changed = True except ValueError: #if if the user does have edit permission, then set the permission to false if enrollment.edit: enrollment.edit = False changed = True try: manageList.index(enrollment.user.username) #if the user does not have manage permission, then set the permission to true if not enrollment.manage: enrollment.manage = True changed = True except ValueError: #if the user does have manage permission, then set the permission to false if enrollment.manage: enrollment.manage = False changed = True try: statsList.index(enrollment.user.username) #if the user does not have stats permission, then set the permission to true if not enrollment.stats: enrollment.stats = True changed = True except ValueError: #if the user does have stats permission, then set the permission to false if enrollment.stats: enrollment.stats = False changed = True #if the user has changed then update it if changed: enrollment.save() try: removeList.index(enrollment.user.username) #if the remove checkbox was checked attempt to remove the user removeUser(enrollment.course,enrollment.user) except ValueError: pass return HttpResponseRedirect(reverse('courses.views.show_roster', \ args=[course_slug])) else: return master_rtr(request, 'roster/invalid_permissions.html', \ {'course': course, 'course_slug': course.slug})
def edit_lesson(request, course_slug, page_slug): ''' This view displays the lesson editing page This view is only accessed through edit_page. Therefore permission have already been checked. @author Russell Mezzetta @author John Hartquist ''' #common dictionary fields lesson = Course.objects.get(slug=course_slug).pages.get(slug=page_slug) course = Course.objects.get(slug=course_slug) data={'course_slug':course_slug, 'page_slug':page_slug, 'private':course.private } try: lesson = lesson.lesson except Lesson.DoesNotExist: print "OH MY! page is not a lesson???" data['lesson'] = lesson data['unpublished'] = lesson.content != lesson.workingCopy if request.method == "POST": #toggle private or public if (page_slug == course_slug): if "private" in request.POST: course.private = True else: if course.private: Enrollment.objects.filter(course=course).update(view=True) course.private = False data['private'] = course.private course.save() #Saves the working copy of the lesson if "Save" in request.POST: #save the content of the lesson data['lesson'] = lesson = saveLessonWorkingCopy(lesson, request.POST['content']) #check if the name changed name_changed = False if lesson.name != request.POST['lessonname']: ret = {} if page_slug == course_slug: ret = renameCourse(Course.objects.get(slug=course_slug), request.POST['lessonname']) if 'course' in ret: course_slug = ret['course'].slug data['lesson'] = lesson = ret['lesson'] else: ret = saveLessonName(lesson, request.POST['lessonname']) #check if saveLessonName returned error message if 'message' in ret: data['message'] = ret['message'] return master_rtr(request, 'page/lesson/edit_lesson.html', data) elif 'lesson' in ret:#successful name change data['lesson'] = lesson = ret['lesson'] name_changed = True if request.POST['Save'] == "Save": #redirect to this page(redirect b/c name may have changed) if name_changed: return HttpResponseRedirect(reverse('pages.views.edit_page', args=[course_slug, lesson.slug])) else: data['unpublished'] = data['lesson'].workingCopy != data['lesson'].content return master_rtr(request, 'page/lesson/edit_lesson.html', data) elif request.POST['Save'] == "Save/Preview": #redirect to the '/preview' view of this page #(note lesson slug may have changed) return HttpResponseRedirect(reverse('pages.views.show_page_preview', args=[course_slug, lesson.slug])) elif request.POST['Save'] == "Publish": data['lesson'] = publishLessonChanges(lesson) if name_changed: return HttpResponseRedirect(reverse('pages.views.edit_page', args=[course_slug, lesson.slug])) else: data['unpublished'] = False return master_rtr(request, 'page/lesson/edit_lesson.html', data) else: #request.POST['Save'] == "Publish/Preview": publishLessonChanges(lesson) return HttpResponseRedirect(reverse('pages.views.show_page', args=[course_slug, lesson.slug])) #return master_rtr(request, 'page/lesson/edit_lesson.html', data) #display confirmation to remove the lesson from the course elif "Remove" in request.POST: return master_rtr(request, 'page/lesson/remove_lesson.html', data) #this gets called after the above "remove" button is clicked and the user #is asked to confirm elif "confirmRemove" in request.POST: if request.POST['confirmRemove'] == 'yes': if course_slug == page_slug:#remove the course removeCourse(course_slug) else: removeLesson(course_slug, page_slug) return HttpResponseRedirect(reverse('home.views.show_homepage')) else: return master_rtr(request, 'page/lesson/edit_lesson.html', data) #redirects to the move_page view elif "Move" in request.POST: return HttpResponseRedirect(reverse('pages.views.move_page', args=[course_slug, page_slug])) #REMOVED by Russ, left just in case #Publishes the workingCopy #elif "Publish" in request.POST: #save any changes made to working copy before saving the same changes #to the published copy. # lesson.workingCopy = request.POST['content'] # data['lesson'] = publishLessonChanges(lesson) # data['unpublished'] = False # return master_rtr(request, 'page/lesson/edit_lesson.html', data) #Revert the workingCopy to the published copy elif "Revert" in request.POST: data['lesson'] = revertLessonChanges(lesson) data['unpublished'] = False return master_rtr(request, 'page/lesson/edit_lesson.html', data) return master_rtr(request, 'page/lesson/edit_lesson.html', data)