Advertisement
Guest User

Untitled

a guest
May 21st, 2017
542
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 15.99 KB | None | 0 0
  1. # ---- IMPORTS ----
  2. # Imports for handing HTTP requests and responses
  3. from django.shortcuts import render_to_response
  4. from django.template import RequestContext
  5. from django.http import Http404, HttpResponseRedirect
  6. from django.core.urlresolvers import reverse
  7.  
  8. # Import for handling Users
  9. from django.contrib.auth.decorators import login_required
  10. from django.contrib.auth.models import User
  11.  
  12. # Models and model handling
  13. from django.shortcuts import get_object_or_404
  14. from models import Section, Folder, Lab
  15.  
  16. # Forms
  17. from django import forms
  18. from widgets import SelectDateTimeWidget   # Custom widget for selecting date and time for this site.
  19.                                            # It doesn't work properly.
  20.  
  21. # ---- FORMS FOR SECTION LISTING ----
  22.  
  23. class UserField(forms.ModelChoiceField):
  24.     """
  25.    Extension of the ModelChoiceField.  ModelChoiceField allows creates a choice field (default widget
  26.    is a select element) and fills it with data from a provided queryset.  This adds on custom
  27.    labeling so as to show users in a better format.  Ex: "(cjp5235): Provias, Colton J."
  28.    """
  29.  
  30.     def label_from_instance(self, obj):
  31.         return "(%s): %s, %s" % (obj.username, obj.last_name, obj.first_name)
  32.  
  33.  
  34. class AddUserForm(forms.Form):
  35.     """
  36.    Form for adding a new user to the database.
  37.    """
  38.     psu_id = forms.RegexField(label='PSU ID', regex=r'^[a-zA-Z]+[0-9]+$', max_length=30)
  39.     first_name = forms.CharField()
  40.     last_name = forms.CharField()
  41.     password = forms.CharField(widget=forms.PasswordInput)
  42.     confirm_password = forms.CharField(widget=forms.PasswordInput)
  43.  
  44.     def clean_psu_id(self):
  45.         """
  46.        Check to make sure that the PSU ID is not already in the database
  47.        """
  48.         try:
  49.             # This will throw a User.DoesNotExist exception if it can't find the PSU ID in the DB.
  50.             user = User.objects.get(username__iexact=self.cleaned_data['psu_id'])
  51.         except User.DoesNotExist:
  52.             return self.cleaned_data['psu_id']
  53.         raise forms.ValidationError('This PSU ID is already in the system.')
  54.  
  55.     def clean(self):
  56.         """
  57.        Check to make sure the passwords match.  Note: clean is not field specific, so it can handle
  58.        multiple fields simultaneously much more easily.  Plus, the errors are returned as
  59.        non-field-errors, which of course allow for the error to be displayed separately from the
  60.        fields (ex: above the form).
  61.        """
  62.         # Make sure the password fields aren't blank before checking them:
  63.         if 'password' in self.cleaned_data and 'confirm_password' in self.cleaned_data:
  64.             if self.cleaned_data['password'] != self.cleaned_data['confirm_password']:
  65.                 raise forms.ValidationError('Passwords do not match.')
  66.         return self.cleaned_data
  67.  
  68.     def save(self):
  69.         """
  70.        The form has been proven valid (clean) at this point.  All of the data within it is now saved
  71.        to a new user account.
  72.        """
  73.         # Create the user using the create_user(username, email, password) method of the UserManager
  74.         user = User.objects.create_user(self.cleaned_data['psu_id'],
  75.                 self.cleaned_data['psu_id'] + '@psu.edu', self.cleaned_data['password'])
  76.  
  77.         # Set the first name, last name, save the user, and return the user model for further editing
  78.         # if needed
  79.         user.first_name = self.cleaned_data['first_name']
  80.         user.last_name = self.cleaned_data['last_name']
  81.         user.save()
  82.         return user
  83.  
  84. # ---- VIEWS FOR SECTION LISTING ----
  85.  
  86. @login_required
  87. def sections(request):
  88.     """
  89.    Displays a list of sections in the system.
  90.    TODO: Restrict display for non-staff accounts so as to only display courses currently in.
  91.    """
  92.     sections = Section.objects.all()
  93.     return render_to_response('sections/main.html', {'sections': sections},
  94.             context_instance=RequestContext(request))
  95.  
  96.  
  97. @login_required
  98. def section_edit(request):
  99.     """
  100.    Returns the editor for each section (requested via AJAX request).
  101.    """
  102.     # If the section exists, fetch it.  Otherwise, throw an Http404 exception which will stop the
  103.     # AJAX request.
  104.     section = get_object_or_404(Section, pk=request.GET['s'])
  105.     return render_to_response('sections/section_edit.html', {'section': section},
  106.             context_instance=RequestContext(request))
  107.  
  108. @login_required
  109. def section_display(request):
  110.     """
  111.    Returns the normal display of each section.  Should be displayed after closing the editor for
  112.    each section.
  113.    """
  114.     section = get_object_or_404(Section, pk=request.GET['s'])
  115.     return render_to_response('sections/section_listing.html', {'section': section},
  116.             context_instance=RequestContext(request))
  117.  
  118. @login_required
  119. def section_instructors_add(request):
  120.     """
  121.    Lets an instructor be added to a section.
  122.    """
  123.     section = get_object_or_404(Section, pk=request.GET['s'])
  124.  
  125.     # Fetch a list of users that aren't involved in the section as an instructor or student.
  126.     users = User.objects.exclude(id__in=section.instructors.values_list('id', flat=True)).exclude(
  127.             id__in=section.students.values_list('id', flat=True))
  128.     if request.POST:        # A request has been submitted to add a user as an instructor
  129.         try:
  130.             user = users.get(pk=int(request.POST['user']))  # Will throw a DoesNotExist exception if
  131.                                                             # the user is not found.
  132.             section.instructors.add(user)                   # Add the user to the course
  133.  
  134.             # A very sneaky trick.  Send a bit of javascript code that will trigger the editor to be
  135.             # reloaded to show the new instructor.
  136.             return render_to_response('sections/section_refresh.html', {'section_id': section.id},
  137.                     context_instance=RequestContext(request))
  138.         except User.DoesNotExist:
  139.             pass                    # Do nothing!
  140.     # Display the form for adding an instructor to the course
  141.     return render_to_response('sections/section_instructor_add.html', {
  142.                 'users': users, 'section_id': section.id
  143.             }, context_instance=RequestContext(request))
  144.  
  145. @login_required
  146. def section_instructors_add_new(request):
  147.     """
  148.    Allows for a new user to be added as an instructor to a section.
  149.    """
  150.     section = get_object_or_404(Section, pk=request.GET['s'])
  151.     if request.POST:            # Check to see if anything was submitted
  152.         # Something was submitted.  Fill the received values into the AddUserForm!
  153.         form = AddUserForm(request.POST)
  154.         if form.is_valid():     # Is the form clean/valid?
  155.             # The form is clean, so run the save function and get the User object returned
  156.             user = form.save()
  157.  
  158.             # Add user as an instructor to the course and refresh the editor
  159.             section.instructors.add(user)
  160.             section.save()
  161.             return render_to_response('sections/section_refresh.html', {'section_id': section.id},
  162.                     context_instance=RequestContext(request))
  163.     else:                       # No form submitted, so display a blank form.
  164.         form = AddUserForm()
  165.  
  166.     # Display the form.  Errors will be displayed if the form was submitted but did not pass the
  167.     # is_valid test
  168.     return render_to_response('sections/section_instructor_add_new.html', {'form': form,
  169.             'section_id': section.id}, context_instance=RequestContext(request))
  170.  
  171. @login_required
  172. def section_instructors_remove(request):
  173.     """
  174.    Removes an instructor from a section
  175.    """
  176.     section = get_object_or_404(Section, pk=request.GET['s'])
  177.     user = get_object_or_404(User, pk=request.GET['u'])
  178.     section.instructors.remove(user)
  179.  
  180.     # Display the updated editor
  181.     return render_to_response('sections/section_edit.html', {'section': section},
  182.             context_instance=RequestContext(request))
  183.  
  184.  
  185. @login_required
  186. def section_students_add(request):
  187.     """
  188.    Allow for a student to be added to a course.  Just like the section_instructors_add above.
  189.    """
  190.     section = get_object_or_404(Section, pk=request.GET['s'])
  191.     users = User.objects.exclude(id__in=section.instructors.values_list('id', flat=True)).exclude(
  192.             id__in=section.students.values_list('id', flat=True))
  193.     if request.POST:
  194.         try:
  195.             user = users.get(pk=int(request.POST['user']))
  196.             section.students.add(user)
  197.             return render_to_response('sections/section_refresh.html', {'section_id': section.id},
  198.                     context_instance=RequestContext(request))
  199.         except User.DoesNotExist:
  200.             pass
  201.     return render_to_response('sections/section_student_add.html', {'users': users,
  202.             'section_id': section.id}, context_instance=RequestContext(request))
  203.  
  204. @login_required
  205. def section_students_add_new(request):
  206.     """
  207.    Allows for a brand new student to be added to the course.  Acts just like
  208.    section_instructors_add_new above.
  209.    POSSIBLE TODO: Make a generic view out of these to better abide by the DRY principle.
  210.    """
  211.     section = get_object_or_404(Section, pk=request.GET['s'])
  212.     if request.POST:
  213.         form = AddUserForm(request.POST)
  214.         if form.is_valid():
  215.             user = form.save()
  216.             section.students.add(user)      # Add the student to the course
  217.             section.save()
  218.             return render_to_response('sections/section_refresh.html', {'section_id': section.id},
  219.                     context_instance=RequestContext(request))
  220.     else:
  221.         form = AddUserForm()
  222.     return render_to_response('sections/section_student_add_new.html', {'form': form,
  223.             'section_id': section.id}, context_instance=RequestContext(request))
  224.  
  225. @login_required
  226. def section_students_remove(request):
  227.     """
  228.    Allows for a student to be removed...once again like a similar function above.
  229.    """
  230.     section = get_object_or_404(Section, pk=request.GET['s'])
  231.     user = get_object_or_404(User, pk=request.GET['u'])
  232.     section.students.remove(user)
  233.     return render_to_response('sections/section_edit.html', {'section': section},
  234.             context_instance=RequestContext(request))
  235.  
  236.  
  237. # ---- FORMS FOR FOLDER VIEWS ----
  238.  
  239. class AddFolderForm(forms.Form):
  240.     """
  241.    A very simple form for adding a folder to the section.
  242.    """
  243.     name = forms.CharField()
  244.  
  245.     def save(self, section):
  246.         """
  247.        Add a folder, save it, and return it, all in one line!
  248.        """
  249.         return Folder(name=self.cleaned_data['name'], section=section).save()
  250.  
  251.  
  252. class AddLabForm(forms.Form):
  253.     """
  254.    A more complex, yet still simple form for adding labs to folders.
  255.    """
  256.  
  257.     # Form fields.  CharFields are TextInputs unless otherwise stated.
  258.     name = forms.CharField()
  259.     description = forms.CharField(widget=forms.Textarea)
  260.     start_time = forms.DateTimeField(widget=SelectDateTimeWidget) # Painful widget!  It barely works!
  261.     end_time = forms.DateTimeField(widget=SelectDateTimeWidget)
  262.     has_introduction = forms.BooleanField(required=False)         # Apparently a boolean field can
  263.     has_discussion = forms.BooleanField(required=False)           # throw an exception if false.
  264.     has_input_files = forms.BooleanField(required=False)          # Thus why it isn't required.
  265.     has_output_files = forms.BooleanField(required=False)
  266.     max_team_size = forms.IntegerField(initial=1)                 # Default to solo work.
  267.  
  268.     def save(self, folder):
  269.         """
  270.        Create a new Lab object, save it, and return it.  Simple.
  271.        Also, use the folder passed as an argument as the folder for the Lab object.
  272.        """
  273.         return Lab(
  274.             name = self.cleaned_data['name'],
  275.             folder = folder,
  276.             description = self.cleaned_data['description'],
  277.             start_time = self.cleaned_data['start_time'],
  278.             end_time = self.cleaned_data['end_time'],
  279.             has_introduction = self.cleaned_data['has_introduction'],
  280.             has_discussion = self.cleaned_data['has_discussion'],
  281.             has_input_files = self.cleaned_data['has_input_files'],
  282.             has_output_files = self.cleaned_data['has_output_files'],
  283.             max_team_size = self.cleaned_data['max_team_size']
  284.         ).save()
  285.  
  286.  
  287. # ---- VIEWS FOR FOLDERS ----
  288.  
  289. @login_required
  290. def folder(request, section_id, folder_id=0):
  291.     """
  292.    An extremely confusing function that needs to be cleaned up.  It works, though!
  293.    """
  294.     section = get_object_or_404(Section, pk=section_id)
  295.     try:
  296.         # Check to see if the instructor exists.  If so, create the AddFolderForm
  297.         section.instructors.get(pk=request.user.id)
  298.         if request.POST:
  299.             form = AddFolderForm(request.POST)
  300.             if 'description' not in request.POST:   # The form submitted is indeed the AddFolderForm
  301.                 if form.is_valid():                 # rather than the AddLabForm
  302.                     form.save(section)
  303.                     form = AddFolderForm()          # Display a fresh form!
  304.         else:
  305.             form = AddFolderForm()
  306.     except User.DoesNotExist:                       # The user is not an instructor, so set form to
  307.         form = None                                 # None
  308.  
  309.     if folder_id == 0:                              # We are in the base of each section.
  310.         folders = section.folder_set.all()
  311.         return render_to_response('folders/folder_list.html', {'folders': folders, 'section': section,
  312.                 'form': form}, context_instance=RequestContext(request))
  313.  
  314.     # At this point, assume that we are within a folder itself
  315.     try:
  316.         # Get the folder and make sure it's a part of the section, all in one quick query statement!
  317.         folder = section.folder_set.get(pk=folder_id)
  318.     except Folder.DoesNotExist:
  319.         raise Http404
  320.  
  321.     # Final processing of the AddLabForm
  322.     if form is not None:        # If form is None, then the user was proven not to be an instructor
  323.                                 # earlier.  Don't bother with the form.
  324.         if request.POST:        # Lab form was submitted.  Validate it, save it, and provide a new one!
  325.             form = AddLabForm(request.POST)
  326.             if form.is_valid():
  327.                 form.save(folder)
  328.                 form = AddLabForm()
  329.         else:
  330.             form = AddLabForm()
  331.  
  332.     # Display the list of labs
  333.     return render_to_response('folders/lab_list.html', {'folder': folder, 'section': section,
  334.             'form': form}, context_instance=RequestContext(request))
  335.  
  336.  
  337. @login_required
  338. def folder_remove(request, section_id, folder_id):
  339.     """
  340.    Display a confirmation for removing a folder.  If there is POST data, continue with the removal.
  341.    """
  342.     section = get_object_or_404(Section, pk=section_id)
  343.     try:
  344.         # Get the folder and make sure that the user is an instructor
  345.         folder = section.folder_set.get(pk=folder_id)
  346.         section.instructors.get(pk=request.user.id)
  347.     except (Folder.DoesNotExist, User.DoesNotExist):    # Something's fishy.  Hide behind a 404!
  348.         raise Http404
  349.     if request.POST:        # The confirmation form was submitted.  Just delete the folder!
  350.         folder.delete()
  351.         # Go to the main page of the section.
  352.         return HttpResponseRedirect(reverse('folder-base', args=(section.id,)))
  353.     return render_to_response('folders/delete_confirm.html', {'folder': folder,
  354.             'section': section}, context_instance=RequestContext(request))
  355.  
  356. # ---- LAB VIEWS ----
  357.  
  358. @login_required
  359. def lab_list(request, lab_id):
  360.     """
  361.    Display a list of LabData objects.  Most of this is handled in the templates.  Nothing to see
  362.    here!
  363.    """
  364.     lab = get_object_or_404(Lab, pk=lab_id)
  365.     return render_to_response('labs/list.html', {'lab': lab}, context_instance=RequestContext(request))
  366.  
  367. """
  368. TODO:
  369. -LabData Detail
  370. -Parser Integration
  371. -ASCI File Uploading
  372. -Binary File Uploading
  373. -Archiving for downloading
  374. -Access Restrictions
  375. -PDF Generation
  376. """
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement