diff options
Diffstat (limited to 'tbc')
-rw-r--r-- | tbc/models.py | 7 | ||||
-rwxr-xr-x | tbc/templates/base.html | 9 | ||||
-rw-r--r-- | tbc/templates/tbc/book-review-details.html | 14 | ||||
-rw-r--r-- | tbc/templates/tbc/book-review.html | 6 | ||||
-rw-r--r-- | tbc/templates/tbc/review-proposal.html | 16 | ||||
-rw-r--r-- | tbc/templates/tbc/submit-sample.html | 2 | ||||
-rwxr-xr-x | tbc/views.py | 116 |
7 files changed, 144 insertions, 26 deletions
diff --git a/tbc/models.py b/tbc/models.py index ec4c35d..15daca9 100644 --- a/tbc/models.py +++ b/tbc/models.py @@ -1,6 +1,7 @@ from django.db import models from django.contrib.auth.models import User from PythonTBC import settings +from django.contrib.admin.models import LogEntry CATEGORY = (("fluid mechanics", "Fluid Mechanics"), @@ -151,6 +152,12 @@ class SampleNotebook(models.Model): return '%s'%(notebook) +class ActivityLog(LogEntry): + proposal_id = models.IntegerField(null=True) + def __unicode__(self): + return 'Activity log for %d' %(proposal_id) + + class AicteBook(models.Model): title = models.TextField() author = models.CharField(max_length=300L) diff --git a/tbc/templates/base.html b/tbc/templates/base.html index 803ad4d..80a8694 100755 --- a/tbc/templates/base.html +++ b/tbc/templates/base.html @@ -207,6 +207,15 @@ </center> <div class="clearfix"></div> {% endif %} + {% if cannot_submit_sample %} + <center> + <div class="alert" style="width:400px;height:25px;"> + <a class="close" data-dismiss="alert" href="#">×</a> + <p>You have not been permitted to send sample notebook.</p> + </div> + </center> + <div class="clearfix"></div> + {% endif %} <div class="row-fluid"> <center><h3>Recent Submissions</h3></center> {% for item in items %} diff --git a/tbc/templates/tbc/book-review-details.html b/tbc/templates/tbc/book-review-details.html index e55c23c..f304a66 100644 --- a/tbc/templates/tbc/book-review-details.html +++ b/tbc/templates/tbc/book-review-details.html @@ -33,4 +33,18 @@ <tr><td>Contributor: <td>{{ book.contributor.user.first_name }} {{ book.contributor.user.last_name }} <tr><td>Email: <td>{{ book.contributor.user.email }}<br> </table> +<table class='table'> + <tr> + <th>User</th> + <th>Time</th> + <th>Activity</th> + </tr> +{% for log in logs %} +<tr> + <td> {{ log.user }} </td> + <td> {{ log.action_time }} </td> + <td> {{ log.change_message }} </td> +</tr> +{% endfor %} +<table> {% endblock %} diff --git a/tbc/templates/tbc/book-review.html b/tbc/templates/tbc/book-review.html index 774998c..98d569a 100644 --- a/tbc/templates/tbc/book-review.html +++ b/tbc/templates/tbc/book-review.html @@ -13,4 +13,10 @@ <li><a href="{% url 'tbc:BookReview' book.id %}">{{ book.title }} {{ book.edition }} Edition</a> {% endfor %} </ol> +<center><h3>Reviewed Books</h3></center> +<ol> +{% for book in approved_books %} +<li><a href="{% url 'tbc:BookReview' book.id %}">{{ book.title }} {{ book.edition }} Edition</a></li> +{% endfor %} +<ol> {% endblock %} diff --git a/tbc/templates/tbc/review-proposal.html b/tbc/templates/tbc/review-proposal.html index a71ebfc..c0ea983 100644 --- a/tbc/templates/tbc/review-proposal.html +++ b/tbc/templates/tbc/review-proposal.html @@ -8,16 +8,16 @@ {% endif %} <ol> {% for proposal in proposals %} - <li><h4>Propsal from {{ proposal.user.user.first_name }} {{ proposal.user.user.last_name }}</h4></li> - <div class="accordion" id="accordion{{ forloop.counter }}"> + <li><h4>Proposal from {{ proposal.user.user.first_name }} {{ proposal.user.user.last_name }}</h4></li> + <div class="accordion" id="accordion1{{ forloop.parentloop.counter }}{{ forloop.counter }}"> {% for textbook in proposal.textbooks.all %} <div class="accordion-group"> <div class="accordion-heading"> - <a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion{{ forloop.counter }}" href="#collapse{{forloop.counter}}"> + <a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion1{{ forloop.parentloop.counter }}{{ forloop.counter }}" href="#collapse1{{ forloop.parentloop.counter }}{{forloop.counter}}"> Book Preference {{ forloop.counter }} - {{ textbook.title }} </a> </div> - <div id="collapse{{forloop.counter}}" class="accordion-body collapse"> + <div id="collapse1{{ forloop.parentloop.counter }}{{forloop.counter}}" class="accordion-body collapse"> <div class="accordion-inner"> Author: {{ textbook.author}}<br> Edition: {{ textbook.edition }}<br> @@ -40,16 +40,16 @@ <hr> <ol> {% for proposal in old_proposals %} - <h4><li>Propsal from {{ proposal.proposal.user.user.first_name }} {{ proposal.proposal.user.user.last_name }}</h4></li> - <div class="accordion" id="accordion{{ forloop.counter }}"> + <h4><li>Proposal from {{ proposal.proposal.user.user.first_name }} {{ proposal.proposal.user.user.last_name }}</h4></li> + <div class="accordion" id="accordion2{{ forloop.counter }}"> {% for textbook in proposal.proposal.textbooks.all %} <div class="accordion-group"> <div class="accordion-heading"> - <a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion{{ forloop.counter }}" href="#collapse{{forloop.counter}}"> + <a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion2{{ forloop.parentloop.counter }}{{ forloop.counter }}" href="#collapse2{{ forloop.parentloop.counter }}{{forloop.counter}}"> Book Preference {{ forloop.counter }} - {{ textbook.title }} </a> </div> - <div id="collapse{{forloop.counter}}" class="accordion-body collapse"> + <div id="collapse2{{ forloop.parentloop.counter }}{{forloop.counter}}" class="accordion-body collapse"> <div class="accordion-inner"> Author: {{ textbook.author}}<br> Edition: {{ textbook.edition }}<br> diff --git a/tbc/templates/tbc/submit-sample.html b/tbc/templates/tbc/submit-sample.html index f259ffc..96f1209 100644 --- a/tbc/templates/tbc/submit-sample.html +++ b/tbc/templates/tbc/submit-sample.html @@ -29,7 +29,7 @@ function validate_content() {% if has_old %} <form action="/submit-sample/{{ proposal.id }}/{{ old_notebook.id }}" name="with-old" method=POST enctype="multipart/form-data" onSubmit="return validate_content();"> {% csrf_token %} - <input type=text id=ch_name_old name=ch_name_old placeholder="{{ old_notebook.title }}"> + <input type=text id=ch_name_old name=ch_name_old value="{{ old_notebook.name }}"> <input type=file id=old_notebook name=old_notebook> <br> <hr> diff --git a/tbc/views.py b/tbc/views.py index 8582538..b93a065 100755 --- a/tbc/views.py +++ b/tbc/views.py @@ -1,8 +1,11 @@ +from django.utils.encoding import force_text +from django.contrib.contenttypes.models import ContentType from django.http import HttpResponse, HttpResponseRedirect from django.shortcuts import render_to_response, redirect from django.views.decorators.csrf import csrf_exempt from django.core.context_processors import csrf from django.contrib.auth import authenticate, login, logout +from django.contrib.admin.models import CHANGE from models import * from tbc.forms import * import os @@ -16,6 +19,19 @@ import json from email.mime.text import MIMEText +def add_log(user, object, flag, message, proposal_id=None): + '''Creates log entry of the user activities.''' + ActivityLog( + user_id=user.id, + content_type_id=ContentType.objects.get_for_model(object).id, + object_id=object.id, + object_repr=force_text(object), + action_flag=flag, + change_message=message, + proposal_id = proposal_id, + ).save() + + def email_send(to,subject,msg): try: smtpObj = smtplib.SMTP('localhost') @@ -90,6 +106,8 @@ def Home(request): context['no_book_alloted'] = True if 'sample_notebook' in request.GET: context['sample_notebook'] = True + if 'cannot_submit_sample' in request.GET: + context['cannot_submit_sample'] =True books = Book.objects.filter(approved=True).order_by("-id")[0:6] for book in books: @@ -120,6 +138,7 @@ def UserLogin(request): curr_user = authenticate(username=username, password=password) if curr_user is not None: login(request, curr_user) + add_log(curr_user, curr_user, CHANGE, 'Logged in') else: form = UserLoginForm() context['form'] = form @@ -147,7 +166,8 @@ def UserRegister(request): if request.method == 'POST': form = UserRegisterForm(request.POST) if form.is_valid(): - form.save() + user = form.save() + add_log(user, user, CHANGE, 'Registered') return HttpResponseRedirect('/login/?signup=done') else: context = {} @@ -166,11 +186,16 @@ def UserProfile(request): user = request.user if user.is_authenticated(): if request.method == 'POST': - form = UserProfileForm(request.POST) + user_profile = Profile.objects.filter(user=user) + if user_profile.exists(): + form = UserProfileForm(request.POST, instance=user_profile[0]) + else: + form = UserProfileForm(request.POST) if form.is_valid(): data = form.save(commit=False) data.user = request.user data.save() + add_log(user, user, CHANGE,'Profile entry') return HttpResponseRedirect('/') else: context = {} @@ -194,6 +219,7 @@ def UserLogout(request): user = request.user if user.is_authenticated() and user.is_active: logout(request) + add_log(user, user, CHANGE, 'Logged out') return redirect('/?logout=done') @@ -250,6 +276,7 @@ def UpdatePassword(request): if new_password == confirm: user.set_password(new_password) user.save() + add_log(user, user, CHANGE, 'Password updated') form = UserLoginForm() context['password_updated'] = True context['form'] = form @@ -285,6 +312,8 @@ def SubmitBook(request): context['user'] = curr_user curr_book = Book.objects.order_by("-id")[0] curr_book_id = curr_book.id + proposal_id = Proposal.objects.get(accepted=curr_book) + add_log(curr_user, curr_book, CHANGE, 'Book submitted', proposal_id) return HttpResponseRedirect('/upload-content/'+str(curr_book_id)) else: context.update(csrf(request)) @@ -305,14 +334,25 @@ def SubmitProposal(request): context = {} context.update(csrf(request)) context['user'] = curr_user - user_proposals = Proposal.objects.filter(user=user_profile) - can_submit_new = True + user_proposals = list(Proposal.objects.filter(user=user_profile)) + proposal_id = None + can_submit_new = False matching_books = [] - for proposal in user_proposals: - if proposal.status is not "book completed": - can_submit_new = False + if user_proposals: + if user_proposals[-1].status == 'rejected': + can_submit_new = True + proposal_id = user_proposals[-1].id + else: + can_submit_new = True if can_submit_new: if request.method == 'POST': + try: + proposal = Proposal.objects.get(id=proposal_id) + except: + proposal = Proposal() + proposal.user = user_profile + proposal.status = 'Pending' + proposal.save() book_titles = request.POST.getlist('title') book_authors = request.POST.getlist('author') book_categories = request.POST.getlist('category') @@ -321,8 +361,12 @@ def SubmitProposal(request): book_editions = request.POST.getlist('edition') book_years = request.POST.getlist('year_of_pub') book_chapters = request.POST.getlist('no_chapters') + textbooks = proposal.textbooks.all() for item in range(3): - tempbook = TempBook() + if textbooks: + tempbook = textbooks[item] + else: + tempbook = TempBook() tempbook.title = book_titles[item] tempbook.author = book_authors[item] tempbook.category = book_categories[item] @@ -332,16 +376,26 @@ def SubmitProposal(request): tempbook.year_of_pub = book_years[item] tempbook.no_chapters = book_chapters[item] tempbook.save() - proposal = Proposal() - proposal.user = user_profile - proposal.save() - for book in list(TempBook.objects.all())[-3:]: - proposal.textbooks.add(book) + if not textbooks: + proposal.textbooks.add(tempbook) + add_log(curr_user, proposal, CHANGE, 'Proposed Books', proposal.id) return HttpResponseRedirect('/?proposal=submitted') else: book_forms = [] for i in range(3): form = BookForm() + if proposal_id: + proposal = Proposal.objects.get(id=proposal_id) + textbooks = proposal.textbooks.all() + form.initial['title'] = textbooks[i].title + form.initial['author'] = textbooks[i].author + form.initial['category'] = textbooks[i].category + form.initial['publisher_place'] = textbooks[i].publisher_place + form.initial['isbn'] = textbooks[i].isbn + form.initial['edition'] = textbooks[i].edition + form.initial['year_of_pub'] = textbooks[i].year_of_pub + form.initial['no_chapters'] = textbooks[i].no_chapters + book_forms.append(form) context['book_forms'] = book_forms return render_to_response('tbc/submit-proposal.html', context) @@ -437,6 +491,7 @@ def ReviewProposals(request, proposal_id=None, textbook_id=None): proposal.status = "samples" proposal.accepted = new_book proposal.save() + add_log(request.user, proposal, CHANGE, 'Proposal accepted', proposal.id) return HttpResponse("Approved") else: new_proposals = Proposal.objects.filter(status="pending") @@ -466,6 +521,7 @@ def DisapproveProposal(request, proposal_id=None): context.update(csrf(request)) proposal = Proposal.objects.get(id=proposal_id) if request.method == 'POST': + add_log(request.user, proposal, CHANGE, 'Sample disapproved', proposal_id) changes_required = request.POST['changes_required'] subject = "Python-TBC: Corrections Required in the sample notebook" message = "Hi, "+proposal.user.user.first_name+",\n"+\ @@ -480,11 +536,12 @@ def DisapproveProposal(request, proposal_id=None): return render_to_response('tbc/disapprove-sample.html', context) -def AllotBook(requrest, proposal_id=None): +def AllotBook(request, proposal_id=None): context = {} proposal = Proposal.objects.get(id=proposal_id) proposal.status = "book alloted" proposal.save() + add_log(request.user, proposal, CHANGE, 'Book alloted', proposal_id) return HttpResponseRedirect("/book-review/?book_alloted=done") @@ -495,6 +552,7 @@ def RejectProposal(request, proposal_id=None): if request.method == 'POST': proposal.status = 'rejected' proposal.save() + add_log(request.user, proposal, CHANGE, 'Proposal rejected', proposal.id) remarks = request.POST['remarks'] subject = "Python-TBC: Rejection of Proposal" message = "Dear "+proposal.user.user.first_name+"\nYour proposal has been\ @@ -512,8 +570,14 @@ def SubmitSample(request, proposal_id=None, old_notebook_id=None): context.update(csrf(request)) if request.method == "POST": curr_proposal = Proposal.objects.get(id=proposal_id) + add_log(request.user, curr_proposal, CHANGE, 'Sample Submitted', curr_proposal.id) if old_notebook_id: - pass + old_notebook = SampleNotebook.objects.get(id=old_notebook_id) + old_notebook.proposal = curr_proposal + old_notebook.name = request.POST.get('ch_name_old') + old_notebook.sample_notebook = request.FILES['old_notebook'] + old_notebook.save() + return HttpResponseRedirect('/?sample_notebook=done') else: sample_notebook = SampleNotebook() sample_notebook.proposal = curr_proposal @@ -523,7 +587,10 @@ def SubmitSample(request, proposal_id=None, old_notebook_id=None): return HttpResponseRedirect('/?sample_notebook=done') else: profile = Profile.objects.get(user=request.user) - proposal = Proposal.objects.get(user=profile, status='samples') + try: + proposal = Proposal.objects.get(user=profile, status='samples') + except Proposal.DoesNotExist: + return HttpResponseRedirect('/?cannot_submit_sample=True') try: old_notebook = SampleNotebook.objects.get(proposal=proposal) context['has_old'] = True @@ -559,6 +626,8 @@ def UpdateBook(request): data.save() context.update(csrf(request)) context['form'] = book_form + proposal = Proposal.objects.get(accepted=book_to_update) + add_log(current_user, book_to_update, CHANGE, 'Book updated', proposal.id) return HttpResponseRedirect('/update-content/'+str(book_to_update.id)) else: book_form = BookForm() @@ -598,6 +667,8 @@ def SubmitCode(request): screenshot.book = curr_book screenshot.save() book = Book.objects.order_by("-id")[0] + proposal = Proposal.objects.get(accepted=book) + add_log(user, curr_book, CHANGE, 'Chapters and Screenshots added', proposal.id) subject = "Python-TBC: Book Submission" message = "Hi "+curr_book.reviewer.name+",\n"+\ "A book has been submitted on the Python TBC interface.\n"+\ @@ -640,6 +711,8 @@ def UpdateContent(request, book_id=None): screenshot.image = request.FILES['image'+str(i)] screenshot.book = current_book screenshot.save() + proposal = Proposal.objects.get(accepted=current_book) + add_log(user, current_book, CHANGE, 'book updated', proposal.id) subject = "Python-TBC: Book Updated" message = "Hi "+current_book.reviewer.name+",\n"+\ "Submission for a book has been updated on the Python TBC interface.\n"+\ @@ -651,7 +724,7 @@ def UpdateContent(request, book_id=None): "ISBN: "+current_book.isbn+"\n"+\ "Follow the link to review the book: \n"+\ "http://dev.fossee.in/book-review/"+str(current_book.id) - email_send(current_book.reviewer.email, subject, message) + email_send(current_book.reviewer.email, subject, message, current_book.id) return HttpResponseRedirect('/?update_book=done') else: context.update(csrf(request)) @@ -715,6 +788,9 @@ def BookReview(request, book_id=None): book = Book.objects.get(id=book_id) chapters = Chapters.objects.filter(book=book) images = ScreenShots.objects.filter(book=book) + proposal = Proposal.objects.get(accepted=book) + logs = ActivityLog.objects.filter(proposal_id=proposal.id) + context['logs'] = logs context['chapters'] = chapters context['images'] = images context['book'] = book @@ -727,6 +803,8 @@ def BookReview(request, book_id=None): if 'mail_notify' in request.GET: context['mail_notify'] = True books = Book.objects.filter(approved=False) + approved_books = Book.objects.filter(approved=True) + context['approved_books'] = approved_books context['books'] = books context['reviewer'] = request.user context.update(csrf(request)) @@ -743,6 +821,8 @@ def ApproveBook(request, book_id=None): book = Book.objects.get(id=book_id) book.approved = True book.save() + proposal = Proposal.objects.get(accepted=book) + add_log(user, book, CHANGE, 'Book approved', proposal.id) file_path = os.path.abspath(os.path.dirname(__file__)) zip_path = "/".join(file_path.split("/")[1:-2]) zip_path = "/"+zip_path+"/Python-Textbook-Companions/" @@ -791,8 +871,10 @@ def NotifyChanges(request, book_id=None): context = {} if is_reviewer(request.user): book = Book.objects.get(id=book_id) + proposal = Proposal.objects.get(accepted=book) if request.method == 'POST': changes_required = request.POST['changes_required'] + add_log(request.user, book, CHANGE, 'Changes notification', proposal.id) subject = "Python-TBC: Corrections Required" message = "Hi, "+book.contributor.user.first_name+",\n"+\ "Book titled, "+book.title+" requires following changes: \n"+\ |