diff options
author | ankitjavalkar | 2020-05-21 13:51:15 +0530 |
---|---|---|
committer | GitHub | 2020-05-21 13:51:15 +0530 |
commit | 8396869fd7750742e4910b9fe0f8a7683a6769ab (patch) | |
tree | 545ba2b1aaf436066313d801cedfee5d14a25772 | |
parent | 9487f85e6731147c4580c53383c24faae35ebd72 (diff) | |
parent | d26c6509865c38c9fcffff404786d381c97e8b0d (diff) | |
download | workshop_booking-8396869fd7750742e4910b9fe0f8a7683a6769ab.tar.gz workshop_booking-8396869fd7750742e4910b9fe0f8a7683a6769ab.tar.bz2 workshop_booking-8396869fd7750742e4910b9fe0f8a7683a6769ab.zip |
Merge pull request #131 from pnshiralkar/workshop-comments
Workshop comments
-rw-r--r-- | workshop_app/admin.py | 9 | ||||
-rw-r--r-- | workshop_app/forms.py | 28 | ||||
-rw-r--r-- | workshop_app/models.py | 16 | ||||
-rw-r--r-- | workshop_app/send_mails.py | 16 | ||||
-rw-r--r-- | workshop_app/templates/workshop_app/base.html | 11 | ||||
-rw-r--r-- | workshop_app/templates/workshop_app/workshop_details.html | 86 | ||||
-rw-r--r-- | workshop_app/templates/workshop_app/workshop_status_coordinator.html | 6 | ||||
-rw-r--r-- | workshop_app/templates/workshop_app/workshop_status_instructor.html | 8 | ||||
-rw-r--r-- | workshop_app/urls.py | 5 | ||||
-rw-r--r-- | workshop_app/views.py | 31 |
10 files changed, 171 insertions, 45 deletions
diff --git a/workshop_app/admin.py b/workshop_app/admin.py index 4e3d333..988351f 100644 --- a/workshop_app/admin.py +++ b/workshop_app/admin.py @@ -6,7 +6,7 @@ from django.http import HttpResponse from .models import ( Profile, WorkshopType, Workshop, - Testimonial, ProfileComments, Banner, AttachmentFile + Testimonial, Comment, Banner, AttachmentFile ) try: @@ -117,8 +117,9 @@ class TestimonialAdmin(admin.ModelAdmin): download_csv.short_description = "Download CSV file for selected stats." -class ProfileCommentAdmin(admin.ModelAdmin): - list_display = ['comment', 'created_date', 'coordinator', 'instructor'] +class CommentAdmin(admin.ModelAdmin): + list_display = ['workshop', 'comment', 'created_date', 'author', 'public'] + list_filter = ['workshop', 'author', 'created_date', 'public'] # Register your models here. @@ -126,6 +127,6 @@ admin.site.register(Profile, ProfileAdmin) admin.site.register(WorkshopType, WorkshopTypeAdmin) admin.site.register(Workshop, WorkshopAdmin) admin.site.register(Testimonial, TestimonialAdmin) -admin.site.register(ProfileComments, ProfileCommentAdmin) +admin.site.register(Comment, CommentAdmin) admin.site.register(Banner) admin.site.register(AttachmentFile) diff --git a/workshop_app/forms.py b/workshop_app/forms.py index 4bef28c..46049f0 100644 --- a/workshop_app/forms.py +++ b/workshop_app/forms.py @@ -1,10 +1,9 @@ from string import punctuation, digits from django import forms -from django.forms import inlineformset_factory from django.utils import timezone -from .models import (Profile, Workshop, ProfileComments, department_choices, title, source, states, WorkshopType, +from .models import (Profile, Workshop, Comment, department_choices, title, source, states, WorkshopType, AttachmentFile) try: @@ -172,24 +171,27 @@ class WorkshopForm(forms.ModelForm): } -class ProfileCommentsForm(forms.ModelForm): +class CommentsForm(forms.ModelForm): """ - Instructors will post comments on Coordinators profile + Users will post comments on workshops """ def __init__(self, *args, **kwargs): - super(ProfileCommentsForm, self).__init__(*args, **kwargs) - self.fields['comment'].label = "" - self.fields['comment'].widget.attrs['rows'] = 5 - self.fields['comment'].widget.attrs['cols'] = 95 + kwargs.setdefault('label_suffix', '') + super(CommentsForm, self).__init__(*args, **kwargs) + self.fields['comment'].required = True + self.fields['public'].label = "Public" class Meta: - model = ProfileComments - exclude = ['coordinator_profile', 'instructor_profile', - 'created_date' - ] + model = Comment + exclude = ['author', 'created_date', 'workshop'] widgets = { - 'comments': forms.CharField(), + 'comment': forms.Textarea(attrs={ + 'class': 'form-control', + }), + 'public': forms.CheckboxInput(attrs={ + 'class': 'form-check-input', + }) } diff --git a/workshop_app/models.py b/workshop_app/models.py index b43600f..d690a7e 100644 --- a/workshop_app/models.py +++ b/workshop_app/models.py @@ -200,26 +200,26 @@ class Testimonial(models.Model): ) -class ProfileComments(models.Model): +class Comment(models.Model): """ - Contains comments posted by instructors on coordinator profile + Contains comments posted by users on workshop instances """ - coordinator = models.ForeignKey(User, - on_delete=models.CASCADE) + author = models.ForeignKey(User, on_delete=models.CASCADE) comment = models.TextField() - instructor = models.ForeignKey(User, related_name="%(app_label)s_%(class)s_related", on_delete=models.CASCADE) + public = models.BooleanField(default=True) created_date = models.DateTimeField(default=timezone.now) + workshop = models.ForeignKey(Workshop, on_delete=models.CASCADE) def __str__(self): - return u"{0} | {1}".format( + return u"{0} | {1} | {2}".format( self.comment, self.created_date, - self.coordinator, - self.instructor + self.author, ) + class Banner(models.Model): """ Add HTML for banner display on homepage diff --git a/workshop_app/send_mails.py b/workshop_app/send_mails.py index a704ee1..d4a11b7 100644 --- a/workshop_app/send_mails.py +++ b/workshop_app/send_mails.py @@ -3,6 +3,8 @@ __author__ = "Akshen Doke" import hashlib import logging import logging.config +import os + import yaml import re from django.core.mail import send_mail @@ -225,7 +227,10 @@ def send_email( request, call_on, format(workshop_date) msg = EmailMultiAlternatives(subject, message, SENDER_EMAIL, [request.user.email]) attachment_paths = path.join(settings.MEDIA_ROOT, workshop_title.replace(" ","_")) - files = listdir(attachment_paths) + if os.path.exists(attachment_paths): + files = listdir(attachment_paths) + else: + files = [] for f in files: attachment = open(path.join(attachment_paths, f), 'rb') part = MIMEBase('application', 'octet-stream') @@ -257,7 +262,10 @@ def send_email( request, call_on, format(workshop_date) msg = EmailMultiAlternatives(subject, message, SENDER_EMAIL, [other_email]) attachment_paths = path.join(settings.MEDIA_ROOT, workshop_title.replace(" ","_")) - files = listdir(attachment_paths) + if os.path.exists(attachment_paths): + files = listdir(attachment_paths) + else: + files = [] for f in files: attachment = open(path.join(attachment_paths, f), 'rb') part = MIMEBase('application', 'octet-stream') @@ -392,7 +400,7 @@ def send_email( request, call_on, workshop_date, new_workshop_date)) logging.info("Workshop Date Changed Done by {0} from {1} to {2}" - .format(request.user.email, + .format(request.user.email, new_workshop_date, workshop_date)) try: send_mail( @@ -419,7 +427,7 @@ def send_email( request, call_on, try: send_mail( - "FOSSEE Python Workshop Date Changed", + "FOSSEE Python Workshop Date Changed", message, SENDER_EMAIL, [other_email], fail_silently=True ) diff --git a/workshop_app/templates/workshop_app/base.html b/workshop_app/templates/workshop_app/base.html index ae404e7..398c38b 100644 --- a/workshop_app/templates/workshop_app/base.html +++ b/workshop_app/templates/workshop_app/base.html @@ -43,7 +43,7 @@ <ul class="navbar-nav mr-auto"> {% if request.user.profile.position == 'coordinator' %} <li class="nav-item"> - <a class="nav-link" href="{% url 'workshop_status_instructor' %}">Workshop Status</a> + <a class="nav-link" href="{% url 'workshop_status_coordinator' %}">Workshop Status</a> </li> <li class="nav-item"> <a class="nav-link" href="{% url 'propose_workshop' %}">Propose Workshop</a> @@ -91,10 +91,11 @@ </nav> {% endblock %} -{% block content %} - <h1>Base Template Content. Please override me</h1> -{% endblock %} - +<div class="container-fluid" style="margin-bottom: 44px"> + {% block content %} + <h1>Base Template Content. Please override me</h1> + {% endblock %} +</div> </body> <footer class="footer"> diff --git a/workshop_app/templates/workshop_app/workshop_details.html b/workshop_app/templates/workshop_app/workshop_details.html new file mode 100644 index 0000000..388b204 --- /dev/null +++ b/workshop_app/templates/workshop_app/workshop_details.html @@ -0,0 +1,86 @@ +{% extends 'workshop_app/base.html' %} + +{% block title %} + View Workshop details +{% endblock %} + +{% block content %} + <div class="container"> + <table class="table table-bordered"> + <tr> + <th><label for="id_first_name">Workshop Type :</label></th> + <td><label for="id_first_name"><a + href="{% url 'workshop_type_details' workshop.workshop_type_id %}">{{ workshop.workshop_type }}</a></label> + </td> + </tr> + <tr> + <th><label for="id_last_name">Date :</label></th> + <td><label for="id_last_name">{{ workshop.date }}</label></td> + </tr> + <tr> + <th><label for="id_email">Coordinator :</label></th> + <td><label for="id_email"><a + href="{% url 'view_profile' workshop.coordinator_id %}">{{ workshop.coordinator }}</a></label> + </td> + </tr> + {% if workshop.status %} + <tr> + <th><label for="id_institute">Status :</label></th> + <td><span class="badge badge-success">{{ workshop.get_status }}</span></td> + </tr> + <tr> + <th><label for="id_phone_number">Instructor :</label></th> + <td><label for="id_email"><a + href="{% url 'view_profile' workshop.instructor_id %}">{{ workshop.instructor }}</a></label> + </td> + </tr> + {% else %} + <tr> + <th><label for="id_institute">Status :</label></th> + <td><span class="badge badge-warning">{{ workshop.get_status }}</span></td> + </tr> + {% endif %} + </table> + <br> + <div class="container"> + <h2 class="text-center">Comments</h2> + <br> + {% for comment in workshop_comments %} + <div class="card my-2"> + <div class="card-header"> + <div class="row"> + <div class="ml-3 font-weight-bold"><a + href="{% url 'view_profile' comment.author_id %}">{{ comment.author }}</a></div> + {% if not comment.public %} + <div class="ml-1"><span class="badge badge-dark">Hidden</span></div> + {% endif %} + <div class="ml-3 text-muted">{{ comment.created_date }}</div> + </div> + </div> + <div class="card-body"> + <p>{{ comment.comment }}</p> + </div> + </div> + {% endfor %} + <br><br> + <div class="card mt-2 mb-5"> + <form method="post"> + <div class="card-header"> + <div class="row"> + <div class="mx-3 font-weight-bold">Post a comment</div> + {% if request.user.profile.position == 'instructor' %} + <div class="ml-5">{{ form.public }} Public</div> + <div class="ml-1 text-muted">(Non-public comments are visible only to instructors)</div> + {% endif %} + </div> + </div> + <div class="card-body"> + {{ form.comment }} + </div> + <button type="submit" class="float-right btn btn-primary btn-md m-2">Post</button> + </form> + </div> + </div> + </div> + +{% endblock %}
\ No newline at end of file diff --git a/workshop_app/templates/workshop_app/workshop_status_coordinator.html b/workshop_app/templates/workshop_app/workshop_status_coordinator.html index 00e28b3..e1c790a 100644 --- a/workshop_app/templates/workshop_app/workshop_status_coordinator.html +++ b/workshop_app/templates/workshop_app/workshop_status_coordinator.html @@ -33,8 +33,8 @@ <table class="table table-striped"> <thead> <tr> - <th>Instructor Name</th> <th>Workshop Name</th> + <th>Instructor Name</th> <th>Workshop Day</th> <th>Status</th> </tr> @@ -44,8 +44,8 @@ <tbody> <tr> {% if workshop.status %} + <td><a href="{% url 'workshop_details' workshop.id %}" >{{ workshop.workshop_type |capfirst }}</a></td> <td>{{ workshop.instructor.get_full_name }}</td> - <td>{{ workshop.workshop_type |capfirst }}</td> <td>{{ workshop.date | date }}</td> <td><span class="badge badge-success">{{ workshop.get_status }}</span></td> {% endif %} @@ -73,7 +73,7 @@ <tbody> <tr> {% if not workshop.status and workshop.tnc_accepted %} - <td>{{ workshop.workshop_type }}</td> + <td><a href="{% url 'workshop_details' workshop.id %}" >{{ workshop.workshop_type |capfirst }}</a></td> <td>{{ workshop.date | date }}</td> <td><span class="badge badge-warning">{{ workshop.get_status }}</span></td> {% endif %} diff --git a/workshop_app/templates/workshop_app/workshop_status_instructor.html b/workshop_app/templates/workshop_app/workshop_status_instructor.html index ef64a70..8657b8d 100644 --- a/workshop_app/templates/workshop_app/workshop_status_instructor.html +++ b/workshop_app/templates/workshop_app/workshop_status_instructor.html @@ -42,9 +42,9 @@ <table class="table table-striped"> <thead> <tr> + <th>Workshop Name</th> <th>Coordinator Name</th> <th>Institute</th> - <th>Workshop Name</th> <th>Workshop Day</th> <th>Status</th> </tr> @@ -53,12 +53,12 @@ <tbody> <tr> {% if workshop.status %} + <td><a href="{% url 'workshop_details' workshop.id %}" >{{ workshop.workshop_type |capfirst }}</a></td> <td> <a href="{% url 'view_profile' workshop.coordinator.profile.user.id %}"> {{ workshop.coordinator.get_full_name }}</a> </td> <td>{{ workshop.coordinator.profile.institute }}</td> - <td>{{ workshop.workshop_type |capfirst }}</td> <td>{{ workshop.date | date }} {% if workshop.date > today %} @@ -97,9 +97,9 @@ <table class="table table-striped"> <thead> <tr> + <th>Workshop Name</th> <th>Coordinator Name</th> <th>Institute</th> - <th>Workshop Name</th> <th>Workshop Day</th> <th>Status</th> <th>Action</th> @@ -110,12 +110,12 @@ <tbody> <tr> {% if not workshop.status and workshop.tnc_accepted %} + <td><a href="{% url 'workshop_details' workshop.id %}" >{{ workshop.workshop_type |capfirst }}</a></td> <td> <a href="{% url 'view_profile' workshop.coordinator.profile.user.id %}"> {{ workshop.coordinator.get_full_name }}</a> </td> <td>{{ workshop.coordinator.profile.institute }}</td> - <td>{{ workshop.workshop_type }}</td> <td>{{ workshop.date | date }}</td> <td><span class="badge badge-warning">{{ workshop.get_status }}</span></td> <td> diff --git a/workshop_app/urls.py b/workshop_app/urls.py index a083e5a..f9c7877 100644 --- a/workshop_app/urls.py +++ b/workshop_app/urls.py @@ -29,11 +29,12 @@ urlpatterns = [ url(r'^dashboard$', views.workshop_status_instructor, name='workshop_status_instructor'), url(r'^accept_workshop/(?P<workshop_id>\d+)', views.accept_workshop, name='accept_workshop'), url(r'^change_workshop_date/(?P<workshop_id>\d+)$', views.change_workshop_date, name='change_workshop_date'), + url(r'^workshops/(?P<workshop_id>\d+)$', views.workshop_details, name='workshop_details'), + url(r'^workshop_type_details/(?P<workshop_type_id>\d+)$', views.workshop_type_details, name='workshop_type_details'), + url(r'^workshop_type_tnc/(?P<workshop_type_id>\d+)$', views.workshop_type_tnc, name='workshop_type_tnc'), url(r'^propose_workshop/$', views.propose_workshop, name='propose_workshop'), url(r'^add_workshop_type$', views.add_workshop_type, name='add_workshop_type'), url(r'^delete_attachment_file/(?P<file_id>\d+)$', views.delete_attachment_file, name='delete_attachment_file'), url(r'^workshop_types/$', views.workshop_type_list, name='workshop_type_list'), - url(r'^workshop_type_details/(?P<workshop_type_id>\d+)$', views.workshop_type_details, name='workshop_type_details'), url(r'^view_profile/(?P<user_id>\d+)$', views.view_comment_profile, name='view_profile'), - url(r'^workshop_type_tnc/(?P<workshop_type_id>\d+)$', views.workshop_type_tnc, name='workshop_type_tnc'), ] diff --git a/workshop_app/views.py b/workshop_app/views.py index 05ebf94..3f24a2f 100644 --- a/workshop_app/views.py +++ b/workshop_app/views.py @@ -17,11 +17,11 @@ from django.utils import timezone from .forms import ( UserRegistrationForm, UserLoginForm, - ProfileForm, WorkshopForm, WorkshopTypeForm + ProfileForm, WorkshopForm, CommentsForm, WorkshopTypeForm ) from .models import ( Profile, User, - Workshop, + Workshop, Comment, WorkshopType, AttachmentFile ) from .send_mails import send_email @@ -416,6 +416,33 @@ def workshop_type_list(request): @login_required +def workshop_details(request, workshop_id): + workshop = Workshop.objects.filter(id=workshop_id) + if not workshop.exists(): + raise Http404 + workshop = workshop.first() + if request.method == 'POST': + form = CommentsForm(request.POST) + if form.is_valid(): + form_data = form.save(commit=False) + if not is_instructor(request.user): + form_data.public = True + form_data.author = request.user + form_data.created_date = timezone.now() + form_data.workshop = workshop + form.save() + else: + print(form.errors) + if is_instructor(request.user): + workshop_comments = Comment.objects.filter(workshop=workshop) + else: + workshop_comments = Comment.objects.filter(workshop=workshop, public=True) + return render(request, 'workshop_app/workshop_details.html', + {'workshop': workshop, 'workshop_comments': workshop_comments, + 'form': CommentsForm(initial={'public': True})}) + + +@login_required def add_workshop_type(request): if not is_instructor(request.user): return redirect(get_landing_page(request.user)) |