diff options
author | Akshen | 2017-10-07 18:27:21 +0530 |
---|---|---|
committer | Akshen | 2017-10-07 18:27:21 +0530 |
commit | f2f781686732ef7fd08c304fc83a202536b1ba1c (patch) | |
tree | ded6a0791044577158926ccae4eb09e6f8d24565 /workshop_app | |
parent | 59d5f503b11ecaa4b6d85b9f1f46bd9334bbfc7c (diff) | |
download | workshop_booking-f2f781686732ef7fd08c304fc83a202536b1ba1c.tar.gz workshop_booking-f2f781686732ef7fd08c304fc83a202536b1ba1c.tar.bz2 workshop_booking-f2f781686732ef7fd08c304fc83a202536b1ba1c.zip |
Adds Share Details and Logging
- Coordinator can share details page with others
- Logging feature added for emails
Diffstat (limited to 'workshop_app')
-rwxr-xr-x | workshop_app/logs/emailconfig.yaml | 20 | ||||
-rw-r--r-- | workshop_app/send_mails.py | 158 | ||||
-rw-r--r-- | workshop_app/templates/workshop_app/view_workshoptype_details.html | 95 | ||||
-rw-r--r-- | workshop_app/templates/workshop_app/view_workshoptype_list.html | 1 | ||||
-rw-r--r-- | workshop_app/urls.py | 1 | ||||
-rw-r--r-- | workshop_app/views.py | 16 |
6 files changed, 236 insertions, 55 deletions
diff --git a/workshop_app/logs/emailconfig.yaml b/workshop_app/logs/emailconfig.yaml new file mode 100755 index 0000000..ab0fa3f --- /dev/null +++ b/workshop_app/logs/emailconfig.yaml @@ -0,0 +1,20 @@ +version: 1 +disable_existing_loggers: False + +formatters: + detailed: + format: '%(asctime)s - %(levelname)s - Function: %(funcName)s() - Line: %(lineno)d - %(message)s' + +handlers: + emaillogfile: + level: INFO + class: logging.handlers.RotatingFileHandler + maxBytes: 10000000 #10MB + backupCount: 9 + formatter: detailed + filename: path/to/emailfile.log + +root: + level: INFO + handlers: + - emaillogfile diff --git a/workshop_app/send_mails.py b/workshop_app/send_mails.py index 32d6f71..a53625e 100644 --- a/workshop_app/send_mails.py +++ b/workshop_app/send_mails.py @@ -1,26 +1,30 @@ __author__ = "Akshen Doke" +import hashlib +import logging +import logging.config +import yaml +import re from django.core.mail import send_mail from textwrap import dedent from random import randint from smtplib import SMTP -import hashlib from django.utils.crypto import get_random_string from string import punctuation, digits try: - from string import letters + from string import letters except ImportError: - from string import ascii_letters as letters + from string import ascii_letters as letters from workshop_portal.settings import ( - EMAIL_HOST, - EMAIL_PORT, - EMAIL_HOST_USER, - EMAIL_HOST_PASSWORD, - EMAIL_USE_TLS, - PRODUCTION_URL, - SENDER_EMAIL, - ADMIN_EMAIL - ) + EMAIL_HOST, + EMAIL_PORT, + EMAIL_HOST_USER, + EMAIL_HOST_PASSWORD, + EMAIL_USE_TLS, + PRODUCTION_URL, + SENDER_EMAIL, + ADMIN_EMAIL + ) from django.core.mail import EmailMultiAlternatives from django.conf import settings from os import listdir, path @@ -31,12 +35,22 @@ from email import encoders from time import sleep from .models import WorkshopType + +def validateEmail(email): + if len(email) > 7: + if re.match("^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$", + email) != None: + return 1 + return 0 + + def generate_activation_key(username): """Generates hashed secret key for email activation""" chars = letters + digits + punctuation secret_key = get_random_string(randint(10,40), chars) return hashlib.sha256((secret_key + username).encode('utf-8')).hexdigest() + def send_smtp_email(request=None, subject=None, message=None, user_position=None, workshop_date=None, workshop_title=None, user_name=None, @@ -64,8 +78,8 @@ def send_smtp_email(request=None, subject=None, message=None, encoders.encode_base64(part) part.add_header('Content-Disposition', "attachment; filename= %s " % f) msg.attach(part) - - + + server = SMTP(EMAIL_HOST, EMAIL_PORT) server.ehlo() server.starttls() @@ -84,33 +98,40 @@ def send_email( request, call_on, institute=None, key=None ): ''' - Email sending function while registration and + Email sending function while registration and booking confirmation. ''' + with open(path.join(settings.LOG_FOLDER, 'emailconfig.yaml'), 'r') as configfile: + config_dict = yaml.load(configfile) + + logging.config.dictConfig(config_dict) + + if call_on == "Registration": message = dedent("""\ - Thank you for registering as a coordinator with us. + Thank you for registering as a coordinator with us. - Please click on the below link to + Please click on the below link to activate your account {0}/activate_user/{1} - - After activation you can proceed to book your dates for + + After activation you can proceed to book your dates for the workshop(s). - In case of queries regarding workshop booking(s), + In case of queries regarding workshop booking(s), revert to this email.""".format(PRODUCTION_URL, key)) + logging.info("New Registration from: %s", request.user.email) try: send_mail( - "Coordinator Registration at FOSSEE, IIT Bombay", message, SENDER_EMAIL, + "Coordinator Registration at FOSSEE, IIT Bombay", message, SENDER_EMAIL, [request.user.email], fail_silently=True ) except Exception: - send_smtp_email(request=request, - subject="Coordinator Registration - FOSSEE, IIT Bombay", + send_smtp_email(request=request, + subject="Coordinator Registration - FOSSEE, IIT Bombay", message=message, other_email=request.user.email, ) @@ -124,41 +145,43 @@ def send_email( request, call_on, Workshop date:{4} Workshop title:{5} - You may accept or reject this booking + You may accept or reject this booking {6}/my_workshops/ .""".format( - user_name, request.user.email, + user_name, request.user.email, request.user.profile.phone_number, request.user.profile.institute, - workshop_date, workshop_title, + workshop_date, workshop_title, PRODUCTION_URL )) + logging.info("Booking Done by{0} for {1} ".format(request.user.email, + other_email)) try: send_mail( - "New FOSSEE Workshop booking on {0}".format(workshop_date), - message, SENDER_EMAIL, [other_email], - fail_silently=True - ) + "New FOSSEE Workshop booking on {0}".format(workshop_date), + message, SENDER_EMAIL, [other_email], + fail_silently=True + ) except Exception: - send_smtp_email(request=request, + send_smtp_email(request=request, subject="New FOSSEE Workshop booking on {0}" .format(workshop_date), message=message, other_email=other_email, ) else: message = dedent("""\ - Thank You for New FOSSEE Workshop booking. + Thank You for New FOSSEE Workshop booking. Workshop date:{0} Workshop title:{1} - Your request has been received and is awaiting instructor + Your request has been received and is awaiting instructor approval/disapproval. You will be notified about the status via email and on {2}/my_workshops/ - Please Note: Unless you get a confirmation email for this workshop with + Please Note: Unless you get a confirmation email for this workshop with the list of instructions, your workshop shall be in the waiting list. - + In case of queries regarding workshop booking(s), revert to this email.""".format( workshop_date, workshop_title, PRODUCTION_URL @@ -167,11 +190,11 @@ def send_email( request, call_on, try: send_mail( "Pending Request for New FOSSEE Workshop booking on {0}" - .format(workshop_date), message, SENDER_EMAIL, + .format(workshop_date), message, SENDER_EMAIL, [request.user.email], fail_silently=True ) except Exception: - send_smtp_email(request=request, + send_smtp_email(request=request, subject="Pending Request for New FOSSEE Workshop booking \ on {0}".format(workshop_date), message=message, other_email=request.user.email, @@ -188,9 +211,11 @@ def send_email( request, call_on, Workshop title:{5} You have accepted this booking. Detailed instructions have - been sent to the coordinator. """.format(user_name, other_email, + been sent to the coordinator. """.format(user_name, other_email, phone_number, institute, workshop_date, workshop_title)) + logging.info("Booking Confirmed by {0} for {1} ".format(request.user.email, + other_email)) subject = "FOSSEE Workshop booking confirmation on {0}".\ format(workshop_date) @@ -215,12 +240,12 @@ def send_email( request, call_on, Workshop date:{3} Workshop title:{4} - Your workshop booking has been accepted. Detailed - instructions are attached below. + Your workshop booking has been accepted. Detailed + instructions are attached below. - In case of queries regarding the workshop + In case of queries regarding the workshop instructions/schedule revert to this email.""".format( - request.user.username, request.user.email, + request.user.username, request.user.email, phone_number, workshop_date, workshop_title )) @@ -254,12 +279,15 @@ def send_email( request, call_on, phone_number, institute, workshop_date, workshop_title)) + logging.info("Booking Rejected by {0} for {1} ".format(request.user.email, + other_email)) + try: send_mail("FOSSEE Workshop booking rejected for {0}" - .format(workshop_date), message, SENDER_EMAIL, + .format(workshop_date), message, SENDER_EMAIL, [request.user.email], fail_silently=True) except Exception: - send_smtp_email(request=request, + send_smtp_email(request=request, subject="FOSSEE Workshop booking rejected for {0}". format(workshop_date), message=message, other_email=request.user.email @@ -271,17 +299,17 @@ def send_email( request, call_on, We regret to inform you that your workshop booking has been rejected due to unavailability of the - instructor. You may try booking other available + instructor. You may try booking other available slots {2}/book/ or you can also Propose a workshop based on your available date.""" .format(workshop_date, workshop_title, PRODUCTION_URL)) try: send_mail("FOSSEE Workshop booking rejected for {0}". - format(workshop_date), message, SENDER_EMAIL, + format(workshop_date), message, SENDER_EMAIL, [other_email], fail_silently=True) except Exception: - send_smtp_email(request=request, + send_smtp_email(request=request, subject="FOSSEE Workshop booking rejected for {0}". format(workshop_date), message=message, other_email=other_email @@ -294,12 +322,15 @@ def send_email( request, call_on, Workshop date:{0} Workshop title:{1}""" .format(workshop_date, workshop_title)) + + logging.info("Workshop Deleted by {0} for {1} ".format(request.user.email, + workshop_date)) try: send_mail("FOSSEE workshop deleted for {0}".format(workshop_date), - message, SENDER_EMAIL, [request.user.email], + message, SENDER_EMAIL, [request.user.email], fail_silently=True) except Exception: - send_smtp_email(request=request, + send_smtp_email(request=request, subject="FOSSEE Workshop deleted for {0}". format(workshop_date), message=message, other_email=request.user.email @@ -324,6 +355,33 @@ def send_email( request, call_on, phone_number, institute, workshop_date, workshop_title, PRODUCTION_URL)) + + logging.info("Workshop Proposed by {0} for {1} ".format(request.user.email, + workshop_date)) + send_mail("Proposed Workshop on {0}". format(workshop_date), message, SENDER_EMAIL, - [other_email], fail_silently=False)
\ No newline at end of file + [other_email], fail_silently=False) + + elif call_on == 'ShareMail': + + for eid in other_email: + if validateEmail(eid): + message = dedent("""\ + Hi {0}, + + I am Sharing with you FOSSEE's Python Workshop List + {1}/view_workshoptype_details + You can register {2}/register and start booking/proposing + workshops for your school, college, university/company. + + Regards, + {3} + """.format(eid, PRODUCTION_URL, PRODUCTION_URL, + request.user.email) + ) + logging.info("Sharing Email Send to: %s ", eid) + send_mail("Hey Checkout FOSSEE's Python Workshop List", message, + SENDER_EMAIL, [eid]) + else: + logging.warning("Invalid EmailId: %s ", eid) diff --git a/workshop_app/templates/workshop_app/view_workshoptype_details.html b/workshop_app/templates/workshop_app/view_workshoptype_details.html index 60d63a4..625434a 100644 --- a/workshop_app/templates/workshop_app/view_workshoptype_details.html +++ b/workshop_app/templates/workshop_app/view_workshoptype_details.html @@ -7,10 +7,50 @@ {% block extra %} <!-- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> --> - + <style> + /* The Modal (background) */ + .modal { + display: none; /* Hidden by default */ + position: fixed; /* Stay in place */ + z-index: 1; /* Sit on top */ + padding-top: 100px; /* Location of the box */ + left: 0; + top: 0; + width: 100%; /* Full width */ + height: 100%; /* Full height */ + overflow: auto; /* Enable scroll if needed */ + background-color: rgb(0,0,0); /* Fallback color */ + background-color: rgba(0,0,0,0.4); /* Black w/ opacity */ + } + + /* Modal Content */ + .modal-content { + background-color: #fefefe; + margin: auto; + padding: 20px; + border: 1px solid #888; + width: 80%; + } + + /* The Close Button */ + .close { + color: #aaaaaa; + float: right; + font-size: 28px; + font-weight: bold; + } + + .close:hover, + .close:focus { + color: #000; + text-decoration: none; + cursor: pointer; + } + </style> + <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> -{% endblock %} + {% endblock %} {% block header %} <nav class="navbar navbar-default navbar-custom"> @@ -67,13 +107,31 @@ <td>{{ w.workshoptype_name }}</td> <td>{{ w.workshoptype_duration }}</td> <td><a href="{{URL_ROOT}}/file_view/{{ w.id }}" class="btn btn-default btn-sm" class="accordion-toggle" >View Workshop Details</a></td> + </tr> </tbody> {% endfor %} </table> <a style="color: white;" href="{{ URL_ROOT }}/book/"><button class="btn btn-primary btn-lg" style="float: right;">Start Booking Now</button></a> +<button id="mailBtn" class="btn btn-info btn-lg">Share Details</button> </div> + <!-- The Modal --> + <div id="mailModal" class="modal"> + + <!-- Modal content --> + <div class="modal-content"> + <span class="close">×</span> + <p>Separate Multiple Email Id's using <strong> comma (,)</strong></p> + <form action="{{URL_ROOT}}/share_details/" method="POST"> + {% csrf_token %} + <label > Email: </label> + <input name="email" type='email' multiple> + <input type='submit'> + </form> + </div> + </div> + <!-- Page Navigation --> <div class="container"> @@ -100,5 +158,34 @@ </ul> </nav> </div> - </div> -{% endblock %}
\ No newline at end of file + </div> <script> + // Get the modal + var modal = document.getElementById("mailModal"); + + // Get the button that opens the modal + var btn = document.getElementById("mailBtn"); + + // Get the <span> element that closes the modal + var span = document.getElementsByClassName("close")[0]; + + // When the user clicks the button, open the modal + btn.onclick = function() { + modal.style.display = "block"; + } + + // When the user clicks on <span> (x), close the modal + span.onclick = function() { + modal.style.display = "none"; + } + + // When the user clicks anywhere outside of the modal, close it + window.onclick = function(event) { + if (event.target == modal) { + modal.style.display = "none"; + } + } + + + </script> + +{% endblock %} diff --git a/workshop_app/templates/workshop_app/view_workshoptype_list.html b/workshop_app/templates/workshop_app/view_workshoptype_list.html index 1777307..3e3221b 100644 --- a/workshop_app/templates/workshop_app/view_workshoptype_list.html +++ b/workshop_app/templates/workshop_app/view_workshoptype_list.html @@ -61,6 +61,7 @@ <td>{{ w.workshoptype_duration }}</td> <td><a class="btn btn-default btn-sm" href="{{URL_ROOT}}/file_view/{{ w.id }}">View Workshop Details</a></td> {% if request.user.profile.position == 'coordinator' %} + {% endif %} </tr> </tbody> diff --git a/workshop_app/urls.py b/workshop_app/urls.py index bccfb86..f5e9bd5 100644 --- a/workshop_app/urls.py +++ b/workshop_app/urls.py @@ -46,6 +46,7 @@ urlpatterns = [ url(r'^propose_workshop/$', views.propose_workshop), url(r'^workshop_stats/$', views.workshop_stats), url(r'^testimonials/$', views.testimonials), + url(r'^share_details/$', views.share_details), url(r'^file_view/(?P<workshop_title>[\w|\W]+)$', views.file_view), url(r'^jsi18n/$', django.views.i18n.javascript_catalog, js_info_dict), diff --git a/workshop_app/views.py b/workshop_app/views.py index 1075eae..3f4237a 100644 --- a/workshop_app/views.py +++ b/workshop_app/views.py @@ -31,6 +31,7 @@ from zipfile import ZipFile from django.contrib import messages import datetime as dt import csv +import logging try: from StringIO import StringIO as string_io except ImportError: @@ -1133,4 +1134,17 @@ def workshop_stats(request): "india_map": states }) else: - redirect('/manage/') + return redirect('/manage/') + + +@login_required +def share_details(request): + user = request.user + if is_instructor(user): + return redirect('/manage/') + else: + if request.method == 'POST': + email_list = (request.POST.get('email').split(',')) + send_email(request, call_on='ShareMail', other_email=email_list) + return redirect('/view_workshoptype_details/') + |