diff options
Diffstat (limited to 'allotter')
-rw-r--r-- | allotter/__init__.py | 2 | ||||
-rw-r--r-- | allotter/admin.py | 7 | ||||
-rw-r--r-- | allotter/forms.py | 110 | ||||
-rw-r--r-- | allotter/management/__init__.py | 0 | ||||
-rw-r--r-- | allotter/management/commands/__init__.py | 0 | ||||
-rw-r--r-- | allotter/management/commands/loadexam.py | 40 | ||||
-rw-r--r-- | allotter/management/commands/loadoptions.py | 60 | ||||
-rw-r--r-- | allotter/management/commands/loadusers.py | 65 | ||||
-rw-r--r-- | allotter/models.py | 136 | ||||
-rw-r--r-- | allotter/templatetags/__init__.py | 0 | ||||
-rw-r--r-- | allotter/templatetags/range_filter.py | 27 | ||||
-rw-r--r-- | allotter/tests.py | 16 | ||||
-rw-r--r-- | allotter/urls.py | 11 | ||||
-rw-r--r-- | allotter/views.py | 260 |
14 files changed, 0 insertions, 734 deletions
diff --git a/allotter/__init__.py b/allotter/__init__.py deleted file mode 100644 index b48e5a0..0000000 --- a/allotter/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -import os - diff --git a/allotter/admin.py b/allotter/admin.py deleted file mode 100644 index 0c14e78..0000000 --- a/allotter/admin.py +++ /dev/null @@ -1,7 +0,0 @@ -from allotter.models import Exam, Option, Application, Profile -from django.contrib import admin - -admin.site.register(Exam) -admin.site.register(Option) -admin.site.register(Application) -admin.site.register(Profile) diff --git a/allotter/forms.py b/allotter/forms.py deleted file mode 100644 index 65e4cf6..0000000 --- a/allotter/forms.py +++ /dev/null @@ -1,110 +0,0 @@ - -from django import forms -from allotter.models import Profile -from django.forms.extras.widgets import SelectDateWidget - -from django.utils.encoding import * - -from django.contrib.auth import authenticate -from django.contrib.auth.models import User - -from string import digits - -BIRTH_YEAR_CHOICES = ('1986','1987','1988','1989','1990','1991') - - -class UserLoginForm(forms.Form): - - ##Registration Number as Username - username = forms.IntegerField(label="Registration Number", - help_text="As on your Examination ID Card") - - ##Application number as password - password = forms.CharField(label = "Application Number", - max_length=10, help_text="As on your Examination ID Card") - - dob = forms.DateField(label="Date of Birth", - widget=SelectDateWidget(years=BIRTH_YEAR_CHOICES), - initial=datetime.date.today) - - def clean_username(self): - u_name = self.cleaned_data["username"] - - if not u_name: - raise forms.ValidationError("Enter an username.") - - ##Verifies whether username contains only digits and is not - ##longer than 7, i.e Username == Registration Number. - if str(u_name).strip(digits) or len(str(u_name)) != 7: - msg = "Invalid Registration Number" - raise forms.ValidationError(msg) - - ##Verifying whether the user already exists in the database - ##Raising error otherwise - try: - User.objects.get(username__exact = u_name) - return u_name - except User.DoesNotExist: - raise forms.ValidationError("Entered Registration Number haven't appeared for JAM Exam.") - - def clean_password(self): - - pwd = self.cleaned_data['password'] - - ##Verifying the length of application number and whether it contains - ##only digits. - - if str(pwd).strip(digits) and len(pwd) != 5: - msg = "Not a valid Application Number" - raise forms.ValidationError(msg) - - return pwd - - def clean(self): - super(UserLoginForm, self).clean() - u_name, pwd = self.cleaned_data.get('username'), self.cleaned_data.get('password') - dob = self.cleaned_data['dob'] - try: - current_user = User.objects.get(username__exact = u_name) - profile = current_user.get_profile() - if profile.dob != dob: - raise forms.ValidationError("Date of Birth doesn't match.") - except User.DoesNotExist: - raise forms.ValidationError("Correct the following errors and try logging in again.") - - - ##Authentication part - user = authenticate(username = u_name, password = pwd) - if not user: - raise forms.ValidationError("Application Number or Registration Number doesn't match.") - return user - - -class UserDetailsForm(forms.Form): - - def __init__(self, user, *args, **kwargs): - self.user = user - super(UserDetailsForm, self).__init__(*args, **kwargs) - - email = forms.EmailField(label="Email Address", - help_text="Enter a valid email id if you have any.") - phone_number = forms.IntegerField(label="Phone number", - help_text="10 digit number with code") - - - def clean_phone_number(self): - pno = self.cleaned_data['phone_number'] - if str(pno).strip(digits) or len(str(pno)) != 10: - raise forms.ValidationError("Not a valid phone number") - return pno - - def save(self): - cleaned_data = self.cleaned_data - user_profile = self.user.get_profile() - - user_profile.secondary_email = self.cleaned_data['email'] - user_profile.phone_number = self.cleaned_data['phone_number'] - - user_profile.save() - - diff --git a/allotter/management/__init__.py b/allotter/management/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/allotter/management/__init__.py +++ /dev/null diff --git a/allotter/management/commands/__init__.py b/allotter/management/commands/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/allotter/management/commands/__init__.py +++ /dev/null diff --git a/allotter/management/commands/loadexam.py b/allotter/management/commands/loadexam.py deleted file mode 100644 index 2fedb66..0000000 --- a/allotter/management/commands/loadexam.py +++ /dev/null @@ -1,40 +0,0 @@ -from csv import reader -from django.core.management.base import BaseCommand, CommandError -from allotter.models import Exam - -class Command(BaseCommand): - args = '<file_name...>' - help = "Give the filename of the csv file that has all the exam code and exam name relation" - - def handle(self, *args, **options): - - clean_exam() - - for fname in args: - load_exam(fname) - - self.stdout.write('Done\n') - - -def clean_exam(): - """Removes all the objects from the database, required as if not done there might be a case of multile entries""" - data = Exam.objects.all() - data.delete() - -def load_exam(filename): - """Load exam code and exam name from the given csv file. The file should - declare a list of "exam_code;exam_name". - """ - try: - csvFile = open(filename, 'rb') - except IOError as (errno,strerror): - print "I/O error({0}): {1}".format(errno, strerror) - - csvReader = reader(csvFile, delimiter=";") - - for data in csvReader: - new_exam = Exam.objects.create() - new_exam.exam_code = data[0] - new_exam.exam_name = data[1] - new_exam.save() - print "Added ({0} : {1})".format(data[0], data[1])
\ No newline at end of file diff --git a/allotter/management/commands/loadoptions.py b/allotter/management/commands/loadoptions.py deleted file mode 100644 index f7c01e6..0000000 --- a/allotter/management/commands/loadoptions.py +++ /dev/null @@ -1,60 +0,0 @@ -from optparse import make_option -from csv import reader -from django.core.management.base import BaseCommand -from allotter.models import Exam, Option - -class Command(BaseCommand): - option_list = BaseCommand.option_list + ( - make_option('--pcc',metavar='Paper course code file name', type=str), - make_option('--cc',metavar='Course code file name', type=str), - ) - help = "Give the filenames of the csv files that has all the option code, name and exam code relation" - - def handle(self, *args, **options): - - clean_option() - - load_option(options) - - self.stdout.write('Done\n') - - -def clean_option(): - """Removes all the objects from the database, required as if not done there might be a case of multiple entries""" - data = Option.objects.all() - data.delete() - -def load_option(options): - """Load option code and option name from the given csv file. The file should - declare a list of "exam_code,option_code,option,code". - """ - paperCourseFileName=options.get('pcc') - courseCodeFileName=options.get('cc') - try: - paperCourseFile = open(paperCourseFileName, 'rb') - except IOError as (errno,strerror): - print "I/O error({0}): {1}".format(errno, strerror) - - try: - courseCodeFile = open(courseCodeFileName, 'rb') - except IOError as (errno,strerror): - print "I/O error({0}): {1}".format(errno, strerror) - - paperReader = reader(paperCourseFile, delimiter=",") - courseReader = reader(courseCodeFile, delimiter=",") - - courseDict = {} - - for data in courseReader: - courseDict[int(data[0])]=data[1] - - for data in paperReader: - exam = Exam.objects.get(exam_code=data[0]) - for value in data[1:len(data)]: - try: - new_option = Option.objects.get(opt_code=value) - except Option.DoesNotExist: - new_option = Option(opt_name=courseDict[int(value)],opt_code=value) - new_option.save() - new_option.exam.add(exam) - print "Added (option {0} with code {1} and exam {2})".format(courseDict[int(value)],value,exam)
\ No newline at end of file diff --git a/allotter/management/commands/loadusers.py b/allotter/management/commands/loadusers.py deleted file mode 100644 index 99fd075..0000000 --- a/allotter/management/commands/loadusers.py +++ /dev/null @@ -1,65 +0,0 @@ -from optparse import make_option -from datetime import datetime -from csv import DictReader -from django.core.management.base import BaseCommand -from allotter.models import Exam, Application, User, Profile - -class Command(BaseCommand): - option_list = BaseCommand.option_list + ( - make_option('--usdf',metavar='User details file name', type=str), - ) - help = "Give the filename of the csv files that has all the details of the users" - - def handle(self, *args, **options): - - clean_users() - - load_users(options) - - self.stdout.write('Done\n') - - -def clean_users(): - """Removes all the objects from the database, required as if not done there might be a case of multiple entries""" - User.objects.filter(is_superuser=False).delete() - -def load_users(options): - """Load option code and option name from the given csv file. The file should - declare a list of "exam_code,option_code,option,code". - """ - userDetailsFileName=options.get('usdf') - try: - userDetailsFile = open(userDetailsFileName, 'rb') - except IOError as (errno,strerror): - print "I/O error({0}): {1}".format(errno, strerror) - - - userReader = DictReader(userDetailsFile, delimiter=":") - - - for data in userReader: - appno = data['AppNo.'] - regno = data['Reg.No.'] - new_user = User.objects.create_user(regno, password=appno, email="") - application = Application(user=new_user) - application.np = int(data['NP']) - if data['P1'].strip(): - application.first_paper = Exam.objects.get(exam_code=data['P1']) - try: - application.second_paper = Exam.objects.get(exam_code=data['P2']) - except: - pass - else: - application.first_paper = Exam.objects.get(exam_code=data['P2']) - - - application.nat = data['Nat'] - application.gender = data['Gdr'] - application.cent = data['Cent'] - application.cgy = data['Cgy'] - application.save() - dob = datetime.strptime(data['DOB'], "%d/%m/%y") - new_profile = Profile(user=new_user, application=application) - new_profile.dob = dob - new_profile.save() - print "Added user with {0} and {1} with dob as {2}".format(appno,regno,dob)
\ No newline at end of file diff --git a/allotter/models.py b/allotter/models.py deleted file mode 100644 index 9da8213..0000000 --- a/allotter/models.py +++ /dev/null @@ -1,136 +0,0 @@ -from django.db import models -from django.contrib.auth.models import User - -##EXAMINATION_SUBJECTS = ( -## ("Physics", "Physics"), -## ("Mathematics", "Mathematics"), -## ("Chemistry", "Chemistry"), -## ) - -##CATEGORIES = ( -## ("GEN", "GEN"), -## ("OBC", "OBC(Non-Creamy Layer)"), -## ("SC", "SC"), -## ("ST", "ST"), -## ) - -##AVAILABLE_OPTIONS = ( -## ("MScChem", "M.Sc Chemisty"), -## ("M.Sc-Physics-IIT-Bombay", "M.Sc Physics IIT Bombay"), -## ("MScMath","M.Sc Mathematics"), -## ("MscHist", "M.Sc History"), -## ("MSc-PhD Dual-Degree-IIT-Bombay", "MSc-PhD Dual Degree IIT Bombay"), -## ("M.Sc Physics-IIT-Madras", "M.Sc Physics IIT Madras"), -## ("M.Sc-Physics-IIT-Guwahati", "M.Sc Physics IIT Guwahati"), -## ("M.Sc-Physics-IIT-KGP", "M.Sc Physics IIT KGP"), -## ("M.Sc-Physics-IIT-Roorkee", "M.Sc Physics IIT Roorkee"), -##) - -##GENDER_CHOICES = ( -## ("M", "Male"), -## ("F", "Female"),) - -##APPLICATION_STATUS = ( -## ("I", "Incomplete"), -## ("Submitted", "Submitted")) - -##BIRTH_YEAR_CHOICES = ('1989', '1990', '1991') - -class Exam(models.Model): - """ - Table for Examination Codes and Subject names. - """ - ##PH for Physics, CY for Chemistry - exam_code = models.CharField(max_length=100, - verbose_name=u"Test Paper code", - help_text=u"Unique code for the Test") - - exam_name = models.CharField(max_length=100, - verbose_name=u"Test Paper", - help_text=u"Subject name of the Test") - - def __unicode__(self): - return self.exam_name - - -class Option(models.Model): - """ - Options Table, Foreign Keyed with Examination. - """ - - opt_name = models.CharField(max_length=100, - verbose_name=u"Programme name", - help_text=u"Programme Title") - - opt_code = models.IntegerField(max_length=3, - verbose_name=u"Programme Code") - - opt_location = models.CharField(max_length=30, - verbose_name=u"Programme Location", - help_text=u"Offered by which IIT") - - exam = models.ManyToManyField(Exam) - - class Meta: - verbose_name_plural = "Options" - - def __unicode__(self): - return unicode(self.opt_code) - - -class Application(models.Model): - """An application for the student - one per student - """ - user = models.OneToOneField(User) - - ##To be filled by applicant - options_selected = models.CharField(max_length=5000,help_text="CSV formatted list of options", blank=True) - - ##Prefilled fields - np = models.IntegerField(max_length=2, help_text="Number of Test Papers") - - ##Mandatory First Subject - first_paper = models.ForeignKey(Exam, related_name="first_paper") - - ##Second subject can be left blank or null - second_paper = models.ForeignKey(Exam, related_name="second_paper", blank=True, null=True) - - nat = models.CharField(max_length=10, verbose_name="Nationality") - - gender = models.CharField(max_length=2, verbose_name="Gender") - - cent = models.IntegerField(max_length=10, verbose_name="Center Code") - - cgy = models.CharField(max_length=10, verbose_name="Category") - - pd = models.BooleanField(verbose_name="Physical Disability", default=False, blank=True) - - submitted = models.BooleanField(verbose_name="Submission Status", default=False) - - def __unicode__(self): - u = self.user - return u'Application for {0}'.format(u.username) - -class Profile(models.Model): - - user = models.OneToOneField(User) - - #Used for verification purposes - dob = models.DateField(verbose_name=u"Date of Birth", - help_text=u"Date of birth as given in the application") - - secondary_email = models.EmailField(verbose_name=u"Secondary Email", - help_text=u"Email address read from user after authentication") - - phone_number = models.IntegerField(max_length=10, verbose_name="Phone Number", - help_text=u"Phone number read from user after authentication") - - #Application for the Profile - application = models.ForeignKey(Application) - - def __unicode__(self): - u = self.user - return u'User Profile {0}'.format(u.username) - - - diff --git a/allotter/templatetags/__init__.py b/allotter/templatetags/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/allotter/templatetags/__init__.py +++ /dev/null diff --git a/allotter/templatetags/range_filter.py b/allotter/templatetags/range_filter.py deleted file mode 100644 index 1ce43d8..0000000 --- a/allotter/templatetags/range_filter.py +++ /dev/null @@ -1,27 +0,0 @@ -##Credits : http://djangosnippets.org/snippets/1357/ - -from django.template import Library - -register = Library() - -@register.filter -def get_range( value ): - """ - Filter - returns a list containing range made from given value - Usage (in template): - - <ul>{% for i in 3|get_range %} - <li>{{ i }}. Do something</li> - {% endfor %}</ul> - - Results with the HTML: - <ul> - <li>0. Do something</li> - <li>1. Do something</li> - <li>2. Do something</li> - </ul> - - Instead of 3 one may use the variable set in the views - """ - return range( value ) - diff --git a/allotter/tests.py b/allotter/tests.py deleted file mode 100644 index 501deb7..0000000 --- a/allotter/tests.py +++ /dev/null @@ -1,16 +0,0 @@ -""" -This file demonstrates writing tests using the unittest module. These will pass -when you run "manage.py test". - -Replace this with more appropriate tests for your application. -""" - -from django.test import TestCase - - -class SimpleTest(TestCase): - def test_basic_addition(self): - """ - Tests that 1 + 1 always equals 2. - """ - self.assertEqual(1 + 1, 2) diff --git a/allotter/urls.py b/allotter/urls.py deleted file mode 100644 index 6556c62..0000000 --- a/allotter/urls.py +++ /dev/null @@ -1,11 +0,0 @@ -from django.conf.urls.defaults import patterns, url - -urlpatterns = patterns('allotter.views', - url(r'^login/$', 'user_login'), - url(r'^logout/$', 'user_logout'), - url(r'^(?P<reg_no>\d+)/apply/$', 'apply'), - url(r'^(?P<reg_no>\d+)/details/$', 'submit_details'), - url(r'^(?P<reg_no>\d+)/get_pdf/$', 'generate_pdf'), - url(r'^(?P<reg_no>\d+)/submit/$', 'submit_options', name='submit_options'), - url(r'^(?P<reg_no>\d+)/complete/$', 'complete_allotment', name='complete_allotment'), -) diff --git a/allotter/views.py b/allotter/views.py deleted file mode 100644 index fb819fc..0000000 --- a/allotter/views.py +++ /dev/null @@ -1,260 +0,0 @@ -from django.contrib.auth import login, logout, authenticate -from django.contrib.auth.decorators import login_required -from django.shortcuts import render, redirect, get_object_or_404 - -from django.http import Http404 -from django.http import HttpResponse -from django.http import HttpResponseRedirect - -from django.core.urlresolvers import reverse - -from django.contrib.auth.models import User -from allotter.models import Profile, Option, Exam -from allotter.forms import UserLoginForm, UserDetailsForm - -from itertools import chain - -#Reportlab libraries -from reportlab.platypus import Table, TableStyle, SimpleDocTemplate, Paragraph, Spacer -from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle -from reportlab.lib import colors -from reportlab.lib.units import inch -from reportlab.lib.enums import TA_JUSTIFY - -import time - -def user_login(request): - """ - Verify the user credentials and log the user in. - """ - - user = request.user - if user.is_authenticated(): - status = user.get_profile().application.submitted #Getting the submission status - if status: #If already submitted, takes to Completion Page - return HttpResponseRedirect(reverse('allotter.views.complete_allotment', args=(user.username,))) - else: #Otherwise to Option Choosing Page - return HttpResponseRedirect(reverse('allotter.views.apply', args=(user.username,))) - - if request.method == "POST": - form = UserLoginForm(request.POST) - if form.is_valid(): - user = form.cleaned_data - login(request, user) - status = user.get_profile().application.submitted #Getting the submission status - if status: - return HttpResponseRedirect(reverse('allotter.views.complete_allotment', args=(user.username,))) - else: - return HttpResponseRedirect(reverse('allotter.views.submit_details', args=(user.username,))) - else: - context = {"form": form} - return render(request, 'allotter/login.html', context) - else: - form = UserLoginForm() - context = {"form": form} - return render(request, 'allotter/login.html', context) - - -@login_required -def submit_details(request, reg_no): - """ - Get the secondary email address, phone number and save it to the Profile. - """ - user = request.user - - if request.method == "POST": - form = UserDetailsForm(user, request.POST) - if form.is_valid(): - data = form.cleaned_data - form.save() - return redirect("/allotter/apply/") - else: - return render(request, 'allotter/details.html', {'form':form}) - - else: - form = UserDetailsForm(request.user) - context = {"form": form} - return render(request, 'allotter/details.html', context) - -def get_details(user, error_message = ""): - """ - Retrieves the information about Test paper(s) and options available - and returns them in a dictionary(context) for passing to the Template. - """ - user_profile = user.get_profile() - user_application = user_profile.application - np = user_application.np #Number of Papers - first_paper = user_application.first_paper #First Paper Name - options_available_first = Option.objects.filter(exam__exam_name=first_paper).distinct() #Options for First paper - oafl = len(options_available_first) - if np == 2: #If written two exams - second_paper = user_application.second_paper - options_available_second = Option.objects.filter(exam__exam_name=second_paper).distinct() - oasl = len(options_available_second) - context = {'user': user, 'first_paper': first_paper, - 'options_available_first' : options_available_first, - 'second_paper': second_paper, - 'options_available_second' : options_available_second, - 'np' : np, 'options_range': range(1, oafl + oasl + 1, 1), - 'error_message': error_message} - else: #If written only one exam - context = {'user': user, 'first_paper': first_paper, - 'options_available_first' : options_available_first, - 'options_range': range(1, oafl + 1, 1), - 'np' : np, 'error_message' : error_message} - return context - -@login_required -def apply(request, reg_no): - """ - Displays the application page for an authenticated user. - """ - user = request.user - if not(user.is_authenticated()): - return redirect('/allotter/login/') - - context = get_details(user) - - return render(request, 'allotter/apply.html', context) - - -def user_logout(request): - ##Logouts the user. - logout(request) - return redirect ('/allotter/login/') - -#TODO: Extensive Testing - -@login_required -def submit_options(request, reg_no): - """ - Gets the Options and their preference number through the POST object and - stores them as list(sorted according to preferences). Options with None are - ignored. - """ - user = get_object_or_404(User, username=reg_no) - user_profile = user.get_profile() - user_application = user_profile.application - np = user_application.np - first_paper = user_application.first_paper #First Paper Name - options_available_first = Option.objects.filter(exam__exam_name=first_paper).distinct() #Options for First paper - - if np == 2: #If qualified for second paper - second_paper = user_application.second_paper #Second Paper Name - options_available_second = Option.objects.filter(exam__exam_name=second_paper).distinct() #Options for second paper - options_available_list = chain(options_available_first, options_available_second) #chaining the two lists - else: - options_available_list = options_available_first - - options_chosen_list = [] #Initializing empty list for storing options - for option in options_available_list: - option_pref = request.POST[unicode(option.opt_code)] - options_chosen_list.append([option_pref, str(option.opt_code)]) #[preference, option code] - - options_chosen_list.sort() #Sorting by preference - options_code_list = [] - for opt in options_chosen_list: - if int(opt[0]): #ignoring the options for which None was marked - options_code_list.append(opt[1]) - - user_application.options_selected = options_code_list #Saving the data in model - user_application.submitted = True #Submission Status - user_application.save() - return HttpResponseRedirect(reverse('allotter.views.complete_allotment', args=(reg_no,))) - -def complete_allotment(request, reg_no): - """ - Passes the chosen options queryset to the Completion Page Template - """ - user = get_object_or_404(User, username=reg_no) - sec_email = user.get_profile().secondary_email - options_chosen = get_chosen_options(user) - context = {'username': reg_no, 'email': sec_email, - 'options_chosen': options_chosen} - - return render(request, 'allotter/complete.html', context) - - -def get_chosen_options(user): - """ - Reads the options submitted by the user in the Application page - """ - user_profile = user.get_profile() - user_application = user_profile.application - np = user_application.np - ocl = eval(user_application.options_selected) - chosen_options = [] - for oc in ocl: - chosen_options.append(Option.objects.get(opt_code=int(oc))) - return chosen_options - - -@login_required -def generate_pdf(request, reg_no): - """ - The Ugly code for generating the pdf using ReportLab. - """ - - user = get_object_or_404(User, username=reg_no) - user_profile = user.get_profile() - user_application = user_profile.application - np = user_application.np - - response = HttpResponse(mimetype='application/pdf') - response['Content-Disposition'] = 'attachment; filename=JAM2012_Allottment.pdf' - - elements = [] - doc = SimpleDocTemplate(response) - - formatted_time = time.ctime() - styles = getSampleStyleSheet() - styles.add(ParagraphStyle(name='Justify', alignment=TA_JUSTIFY)) - - ptext = '<font size=15>JAM 2012 Allotment.</font>' - elements.append(Paragraph(ptext, styles["Justify"])) - elements.append(Spacer(4, 20)) - - ptext = '<font size=12>Registration Number: %s</font>' % reg_no - elements.append(Paragraph(ptext, styles["Normal"])) - elements.append(Spacer(1, 12)) - - ptext = '<font size=12>Number of Papers Eligible: %s</font>' % np - elements.append(Paragraph(ptext, styles["Normal"])) - elements.append(Spacer(1, 12)) - - ptext = '<font size=12>No options were chosen.</font>' - elements.append(Paragraph(ptext, styles["Normal"])) - elements.append(Spacer(1, 12)) - - data = [] - options = get_chosen_options(user) ##Put a check to show when the options chosen is empty - - if not(options): - doc.build(elements) - return response - - ptext = '<font size=12>Following are the options in order of preference</font>' - elements.append(Paragraph(ptext, styles["Normal"])) - elements.append(Spacer(1, 12)) - - counter = 1 - for opt in options: - data.append([counter, opt.opt_code, opt.opt_location, opt.opt_name]) - counter = counter + 1 - - t = Table(data) - t.setStyle(TableStyle([('GRID',(0,0),(3,len(options)),1,colors.black), - ('TEXTCOLOR',(0,0),(0,-1),colors.green)])) - - elements.append(t) - - ptext = '<font size=12>%s</font>' % formatted_time - elements.append(Paragraph(ptext, styles["Normal"])) - elements.append(Spacer(1, 12)) - - doc.build(elements) - - return response - - - |