diff options
-rw-r--r-- | .gitignore | 3 | ||||
-rw-r--r-- | requirements.txt | 4 | ||||
-rw-r--r-- | workshop_app/forms.py | 8 | ||||
-rw-r--r-- | workshop_app/models.py | 39 | ||||
-rw-r--r-- | workshop_app/send_mails.py | 55 | ||||
-rw-r--r-- | workshop_app/static/workshop_app/img/img1.png | bin | 0 -> 19947 bytes | |||
-rw-r--r-- | workshop_app/static/workshop_app/img/img2.png | bin | 0 -> 14023 bytes | |||
-rw-r--r-- | workshop_app/templates/workshop_app/base.html | 2 | ||||
-rw-r--r-- | workshop_app/templates/workshop_app/booking.html | 34 | ||||
-rw-r--r-- | workshop_app/templates/workshop_app/create_workshop.html | 11 | ||||
-rw-r--r-- | workshop_app/templates/workshop_app/index.html | 20 | ||||
-rw-r--r-- | workshop_app/templates/workshop_app/view_course_list.html | 1 | ||||
-rw-r--r-- | workshop_app/views.py | 142 | ||||
-rw-r--r-- | workshop_portal/urls.py | 1 |
14 files changed, 227 insertions, 93 deletions
@@ -96,3 +96,6 @@ db.sqlite3 # Django Migration files migrations/ + +#MAC OS specific +.DS_Store diff --git a/requirements.txt b/requirements.txt index 73747b4..d40ba0a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,8 @@ appdirs==1.4.0 -Django==1.10.4 +Django==1.9 +django-recurrence==1.4.1 packaging==16.8 pyparsing==2.1.10 python-dateutil==2.6.0 +pytz==2016.10 six==1.10.0 diff --git a/workshop_app/forms.py b/workshop_app/forms.py index eb74a99..fa0834c 100644 --- a/workshop_app/forms.py +++ b/workshop_app/forms.py @@ -40,7 +40,9 @@ class UserRegistrationForm(forms.Form): help_text='Institute/Organization') department = forms.CharField(max_length=64, help_text='Department you work \ study at') - position = forms.ChoiceField(help_text='If you are an instructor please \ + position = forms.ChoiceField(help_text='Instructors, please wait \ + for our admin approval, if your instructor \ + account is not activated in 7 days, please\ mail us at python[at]fossee[dot]in', choices=position_choices ) @@ -132,6 +134,10 @@ class ProfileForm(forms.ModelForm): class CreateWorkshop(forms.ModelForm): """Instructors can create Workshops based on the courses available.""" + def __init__( self, *args, **kwargs ): + super(CreateWorkshop, self).__init__( *args, **kwargs ) + self.fields['recurrences'].label = " " #the trick to hide field :) + class Meta: model = Workshop fields = ['workshop_title', 'recurrences'] diff --git a/workshop_app/models.py b/workshop_app/models.py index a16c6a3..096ce5d 100644 --- a/workshop_app/models.py +++ b/workshop_app/models.py @@ -50,12 +50,13 @@ class Course(models.Model): course_name = models.CharField(max_length=120) course_description = models.TextField() - course_duration = models.CharField(max_length=12) + course_duration = models.CharField(max_length=32) def __str__(self): return u"{0} {1}".format(self.course_name, self.course_duration) + class Workshop(models.Model): """Instructor Creates workshop based on Courses available""" @@ -63,26 +64,38 @@ class Workshop(models.Model): workshop_instructor = models.ForeignKey(User, on_delete=models.CASCADE) workshop_title = models.ForeignKey( Course, on_delete=models.CASCADE,\ - help_text='Select the course you \ - would like to create a workshop for' + help_text='Select the course for which \ + you would like to create a workshop.' ) - + #For recurring workshops source: django-recurrence recurrences = RecurrenceField() - #status = models.BooleanField() Book, Pending, Booked def __str__(self): return u"{0} | {1} ".format(self.workshop_title, self.workshop_instructor) -# class completed_Workshop(models.Model): -# """ -# Contains Data of Booked/Completed Workshops -# """ +class RequestedWorkshop(models.Model): + """ + Contains Data of Booked/Completed Workshops + """ + + requested_workshop_instructor = models.ForeignKey( + User, + on_delete=models.CASCADE + ) + requested_workshop_coordinator = models.ForeignKey( + User, + related_name="%(app_label)s_%(class)s_related" + ) + status = models.CharField( + max_length=32, default="Pending", + choices=status_choices + ) + requested_workshop_title = models.ForeignKey( + Workshop, + on_delete=models.CASCADE + ) -# workshop_instructor = models.ForeignKey(User, on_delete=models.CASCADE) -# workshop_coordinator = models.ForeignKey(User) -# status = models.CharField(max_length=32, choices=status_choices) -# workshop_title = models.ForeignKey(Course, on_delete=models.CASCADE) diff --git a/workshop_app/send_mails.py b/workshop_app/send_mails.py new file mode 100644 index 0000000..4eff778 --- /dev/null +++ b/workshop_app/send_mails.py @@ -0,0 +1,55 @@ +from django.core.mail import send_mail +from workshop_portal.settings import ( + EMAIL_HOST, + EMAIL_PORT, + EMAIL_HOST_USER, + EMAIL_HOST_PASSWORD, + EMAIL_USE_TLS + ) + +def send_email(request, call_on, user_position=None): + ''' + Email sending function while registration and + booking confirmation. + ''' + + if call_on == 'Registration': + if user_position == 'instructor': + message = 'Thank You for Registering on this platform. \n \ + Since you have ask for Instructor Profile, \n \ + we will get back to you soon after verifying your \n \ + profile. \ + In case if you don\'t get any response within 3days, \ + Please contact us at ' + send_mail( + 'Welcome to FOSSEE', message, EMAIL_HOST_USER, + [request.user.email], fail_silently=False + ) + #Send a mail to admin as well as a notification. + else: + message = 'Thank You for Registering on this platform.\n \ + Rules. \n \ If you face any issue during \ + your session please contact fossee.' + send_mail( + 'Welcome to FOSSEE', message, EMAIL_HOST_USER, + [request.user.email], fail_silently=False + ) + + elif call_on == 'Booking': + if user_position == 'instructor': + message = 'You got a workshop booking request \ + from user name ' + send_mail( + 'Python Workshop Booking | FOSSEE', message, EMAIL_HOST_USER, + [request.user.email], fail_silently=False + ) + + else: + message = 'Thank You for Booking on this platform.\n \ + Rules to be added \ + If you face any issue during your session please contact \ + fossee.' + send_mail( + 'Python Workshop Booking | FOSSEE', message, EMAIL_HOST_USER, + [request.user.email], fail_silently=False + ) diff --git a/workshop_app/static/workshop_app/img/img1.png b/workshop_app/static/workshop_app/img/img1.png Binary files differnew file mode 100644 index 0000000..07dc07f --- /dev/null +++ b/workshop_app/static/workshop_app/img/img1.png diff --git a/workshop_app/static/workshop_app/img/img2.png b/workshop_app/static/workshop_app/img/img2.png Binary files differnew file mode 100644 index 0000000..0e47923 --- /dev/null +++ b/workshop_app/static/workshop_app/img/img2.png diff --git a/workshop_app/templates/workshop_app/base.html b/workshop_app/templates/workshop_app/base.html index 9971dd4..fef8840 100644 --- a/workshop_app/templates/workshop_app/base.html +++ b/workshop_app/templates/workshop_app/base.html @@ -21,7 +21,7 @@ {% block extra %} {% endblock %} -<body> +<body style="overflow: scroll;"> {% block header %} <nav class="navbar navbar-inverse"> diff --git a/workshop_app/templates/workshop_app/booking.html b/workshop_app/templates/workshop_app/booking.html index 4657b4a..5089d77 100644 --- a/workshop_app/templates/workshop_app/booking.html +++ b/workshop_app/templates/workshop_app/booking.html @@ -5,7 +5,28 @@ {% endblock %} {% block extra %} + + <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> + <script type="text/javascript"> + function sendData(d){ + var URL = "{{ URL_ROOT }}/book_workshop/"; + console.log(d); + $.ajax({ + url: URL, + type: "POST", + data: { + d, + csrfmiddlewaretoken: $("input[name=csrfmiddlewaretoken]").val() + }, + + success:function(response){ + alert("success: " + response); + + } + }); + } + </script> {% endblock %} {% block header %} @@ -30,6 +51,7 @@ <table class="table table-hover"> <thead> <tr> + <th>Instructor Name</th> <th>Course Name</th> <th>Course Day</th> @@ -37,19 +59,23 @@ </tr> </thead> {% csrf_token %} + {% for workshop in workshop_details %} <tbody> + <tr> - <td>{{ workshop.1.0 }}</td> - <td>{{ workshop.1.1 }}</td> - <td>{{ workshop.0 }}</td> - <td><button id="book-btn" class="btn btn-primary btn-sm">Book</button></td> + <td id="instructor-name">{{ workshop.1.0 }}</td> + <td id="course-name">{{ workshop.1.1 }}</td> + <td id="workshop-date{{ forloop.counter }}">{{ workshop.0 }}</td> + <td><button class="btn btn-primary btn-sm" id="book-btn" onClick="sendData('{{workshop.0}},{{workshop.1.2}},{{workshop.1.3}}')" > Book</button></td> </tr> + </tbody> {% endfor %} </table> </div> + <!-- Page Navigation --> <div class="container"> <div class="Page-Nav" align="center"> <nav aria-label="Page navigation"> diff --git a/workshop_app/templates/workshop_app/create_workshop.html b/workshop_app/templates/workshop_app/create_workshop.html index e643594..e38bf1a 100644 --- a/workshop_app/templates/workshop_app/create_workshop.html +++ b/workshop_app/templates/workshop_app/create_workshop.html @@ -6,15 +6,10 @@ {% block extra %} - <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> + <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css"> - <script src="https://code.jquery.com/jquery-1.12.4.js"></script> - <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> - <script> - $( function() { - $( "#id_date" ).datepicker(); - } ); - </script> + <script src="https://code.jquery.com/jquery-1.12.4.js"></script> + <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> {% endblock %} diff --git a/workshop_app/templates/workshop_app/index.html b/workshop_app/templates/workshop_app/index.html index f0923bb..a7664ed 100644 --- a/workshop_app/templates/workshop_app/index.html +++ b/workshop_app/templates/workshop_app/index.html @@ -7,4 +7,24 @@ Welcome {% endblock %} </head> + + {% block content %} + <div class="container"> + <div class="jumbotron container-fluid"> + <h3>Why should you attend Python workshop</h3> + <p>Python is widely used in organizations like <b>Google, Yahoo, Zope, Walt Disney , IBM etc.</b> It is easy to earn and widely used in scientific computing. If you are new to programming, python is the best place to start exploring the power of programming. Moreover that, you can easy integrate python with your existing projects.Python has an extensive set of libraries and well documented user guide.</p> + </div> + <div class="row"> + <div class="col-lg-6"> + FOSSEE python workshop is designed by keeping students and faculties of India in prime focus. Workshop content is designed without any assumption about prior knowledge of participants. It takes you by hand from basic to advanced level in 3 days. + <img src="{{ URL_ROOT }}/static/workshop_app/img/img1.png" style="width:304px;height:228px;"> + </div> + <div class="col-lg-6"> + FOSSEE has imparted <b>“Introduction to Scientific Computing using python”</b> workshop to 1364 students from 20+ colleges spread across different states in India in 2017.This number is increasing and you can also become part of this incredible initiative by organizing FOSSEE workshop at your college. Visit <a href=http://www.fossee.in/fossee-stats target="_blank">stats</a> for details on statistics. + <img src="{{ URL_ROOT }}/static/workshop_app/img/img2.png" style="width:304px;height:228px;"> + </div> + </div> + </div> + {% endblock %} + </html>
\ No newline at end of file diff --git a/workshop_app/templates/workshop_app/view_course_list.html b/workshop_app/templates/workshop_app/view_course_list.html index 68c3009..e5c10e6 100644 --- a/workshop_app/templates/workshop_app/view_course_list.html +++ b/workshop_app/templates/workshop_app/view_course_list.html @@ -72,6 +72,7 @@ </div> +<!-- Page Navigation --> <div class="container"> <div class="Page-Nav" align="center"> diff --git a/workshop_app/views.py b/workshop_app/views.py index 1fe5084..da277bd 100644 --- a/workshop_app/views.py +++ b/workshop_app/views.py @@ -3,25 +3,24 @@ from .forms import ( UserRegistrationForm, UserLoginForm, ProfileForm, CreateWorkshop ) -from .models import Profile, User, has_profile, Workshop, Course +from .models import ( + Profile, User, + has_profile, Workshop, + Course, RequestedWorkshop + ) from django.template import RequestContext from datetime import datetime, date from django.contrib.auth import login, logout, authenticate from django.contrib.auth.decorators import login_required from django.contrib import messages from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger -from django.core.mail import send_mail from django.shortcuts import render, redirect from django.db import IntegrityError from collections import OrderedDict from dateutil.parser import parse -from workshop_portal.settings import ( - EMAIL_HOST, - EMAIL_PORT, - EMAIL_HOST_USER, - EMAIL_HOST_PASSWORD, - EMAIL_USE_TLS - ) +from .send_mails import send_email +from django.http import HttpResponse + def index(request): '''Landing Page''' @@ -103,27 +102,28 @@ def book(request): if user.groups.filter(name='instructor').count() > 0: return redirect('/manage/') workshop_details = Workshop.objects.all() + workshop_occurence = {} for workshops in workshop_details: dates = workshops.recurrences.between( datetime(2017, 3, 12, 0, 0, 0), - datetime(2017, 12, 31, 0, 0, 0), #Needs to be changed + datetime(2017, 12, 31, 0, 0, 0), #Needs to be changed yearly inc=True ) - + for d in range(len(dates)): workshop_occurence[dates[d].strftime("%d-%m-%Y")] = [ workshops.workshop_instructor, - workshops.workshop_title + workshops.workshop_title, + workshops.workshop_instructor_id, + workshops.workshop_title_id ] - + # workshop_occurence = OrderedDict(sorted(workshop_occurence.items())) workshop_occurence = list(workshop_occurence.items()) - - - #Show upto 3 Workshops per page + #Show upto 6 Workshops per page paginator = Paginator(workshop_occurence, 6) page = request.GET.get('page') try: @@ -144,25 +144,72 @@ def book(request): return redirect('/login/') @login_required +def book_workshop(request): + ''' + Function for Updating requested_workshop table + ''' + if request.method == 'POST': + user_position = request.user.profile.position + client_data = request.body.decode("utf-8").split("&") + client_data = client_data[0].split("%2C") + + print(Workshop.objects.filter(workshop_title_id=client_data[2])) + + send_email(request, call_on='Booking', + user_position=user_position) + + instructor_profile = Profile.objects.filter(user=client_data[1]) + workshop_list = Workshop.objects.get( + workshop_instructor=client_data[1] + ) + workshop_recurrence_list = workshop_list.recurrences.between( + datetime(2017, 3, 12, 0, 0, 0), + datetime(2017, 12, 31, 0, 0, 0), + inc=True + ) + for d in workshop_recurrence_list: + if client_data[0][2:] == (d.strftime("%d-%m-%Y")): + rW_obj = RequestedWorkshop() + rW_obj.requested_workshop_instructor = User.objects.get( + id=client_data[1] + ) + rW_obj.requested_workshop_coordinator = request.user + #To be changed + rW_obj.requested_workshop_title = Workshop.objects.all() + + rW_obj.save() + + + + return HttpResponse(instructor_profile) + else: + pass + + + +@login_required def manage(request): user = request.user if user.is_authenticated(): #Move user to the group via admin if user.groups.filter(name='instructor').count() > 0: try: - workshop_details = Workshop.objects.get(workshop_instructor=user) + #Can't Handle Multiple objects Fix this asap + workshop_details = Workshop.objects.get( + workshop_instructor=user.id + ) workshop_occurence_list = workshop_details.recurrences.between( - datetime(2017, 3, 12, 0, 0, 0), - datetime(2017, 12, 31, 0, 0, 0), - inc=True - ) + datetime(2017, 3, 12, 0, 0, 0), + datetime(2017, 12, 31, 0, 0, 0), + inc=True + ) for i in range(len(workshop_occurence_list)): workshop_occurence_list[i] = [{ - "user": str(user), - "workshop": workshop_details, - "date": workshop_occurence_list[i].date - }] - + "user": str(user), + "workshop": workshop_details, + "date": workshop_occurence_list[i].date + }] + #Show upto 3 Workshops per page paginator = Paginator(workshop_occurence_list, 3) @@ -170,14 +217,14 @@ def manage(request): try: workshops = paginator.page(page) except PageNotAnInteger: - #If page is not an integer, deliver first page. + #If page is not an integer, deliver first page. workshops = paginator.page(1) except EmptyPage: - #If page is out of range(e.g 999999), deliver last page. + #If page is out of range(e.g 999999), deliver last page. workshops = paginator.page(paginator.num_pages) - except: workshops = None + return render( request, "workshop_app/manage.html", {"workshop_occurence_list": workshops} @@ -234,8 +281,6 @@ def create_workshop(request): '''Instructor creates workshops''' user = request.user - - if is_instructor(user): if request.method == 'POST': form = CreateWorkshop(request.POST) @@ -261,7 +306,7 @@ def view_course_list(request): user = request.user if is_instructor(user): course_list = Course.objects.all() - paginator = Paginator(course_list, 9) #Show upto 12 Courses per page + paginator = Paginator(course_list, 6) #Show upto 12 Courses per page page = request.GET.get('page') try: @@ -292,36 +337,3 @@ def view_course_details(request): else: return redirect('/book/') - -def send_email(request, call_on, user_position=None): - ''' - Email sending function while registration and - booking confirmation. - ''' - - if call_on == 'Registration': - if user_position == 'instructor': - message = 'Thank You for Registering on this platform. \n \ - Since you have ask for Instructor Profile, \n \ - we will get back to you soon after verifying your \n \ - profile. \ - In case if you don\'t get any response within 3days, \ - Please contact us at ' - send_mail( - 'Welcome to FOSSEE', message, EMAIL_HOST_USER, - [request.user.email], fail_silently=False - ) - #Send a mail to admin as well as a notification. - else: - message = 'Thank You for Registering on this platform.\n \ - Rules. \n \ - If you face any issue during your session please contact \ - fossee.' - send_mail( - 'Welcome to FOSSEE', message, EMAIL_HOST_USER, - [request.user.email], fail_silently=False - ) - - elif call_on == 'Booking': - pass - diff --git a/workshop_portal/urls.py b/workshop_portal/urls.py index 9612014..54eb3b7 100644 --- a/workshop_portal/urls.py +++ b/workshop_portal/urls.py @@ -32,6 +32,7 @@ urlpatterns = [ url(r'^view_profile/$', views.view_profile), url(r'^edit_profile/$', views.edit_profile), url(r'^book/$', views.book), + url(r'^book_workshop/$', views.book_workshop), url(r'^manage/$', views.manage), url(r'^view_course_list/$', views.view_course_list), url(r'^view_course_details/$', views.view_course_details), |