from django.utils.encoding import force_text
from django.contrib.contenttypes.models import ContentType
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import render_to_response, redirect
from django.views.decorators.csrf import csrf_exempt
from django.template.context_processors import csrf
from django.contrib.auth import authenticate, login, logout
from django.contrib.admin.models import CHANGE
from django.contrib.auth.decorators import login_required
from django.template import RequestContext
from .models import *
from tbc.forms import *
from . import local
import os
import zipfile
import io
import smtplib
import shutil
import string
import random
import json
import subprocess
from email.mime.text import MIMEText
import StringIO

def add_log(user, object, flag, message, proposal_id=None, chat='No message'):
    '''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,
        conversation = chat,
    ).save()


def email_send(to,subject,msg):
    try:
        smtpObj = smtplib.SMTP('localhost')
        mail_from = "textbook@fossee.in"
        message = MIMEText(msg)
        message['Subject'] = subject
        message['From'] = mail_from
        message['to'] = to
        smtpObj.sendmail(mail_from, to, message.as_string())
    except SMTPException:
        return HttpResponse("Error:unable to send email")


def is_reviewer(user):
    if user.groups.filter(name='reviewer').exists():
        return True


def internship_forms(request):
    context = {}
    images = []
    if request.user.is_anonymous():
        context['anonymous'] = True
    else:
        if is_reviewer(request.user):
            context['reviewer'] = request.user
        else:
            context['user'] = request.user
    return render_to_response('tbc/internship-forms.html', context)


def sample_ipynb(request):
    return render_to_response('tbc/sample.html')


def about_pytbc(request):
    context = {}
    images = []
    if request.user.is_anonymous():
        context['anonymous'] = True
    else:
        if is_reviewer(request.user):
            context['reviewer'] = request.user
        else:
            context['user'] = request.user
    return render_to_response('tbc/about-pytbc.html', context)


def home(request):
    context = {}
    images = []
    if request.user.is_anonymous():
        context['anonymous'] = True
    else:
        if is_reviewer(request.user):
            context['reviewer'] = request.user
        else:
            context['user'] = request.user
    if 'up' in request.GET:
        context['up'] = True
    if 'profile' in request.GET:
        context['profile'] = True
    if 'login' in request.GET:
        context['login'] = True
    if 'logout' in request.GET:
        context['logout'] = True
    if 'update_book' in request.GET:
        context['update_book'] = True
    if 'not_found' in request.GET:
        context['not_found'] = True
    if 'proposal' in request.GET:
        context['proposal_submitted'] = True
    if 'proposal_pending' in request.GET:
        context['proposal_pending'] = True
    if 'book_pending' in request.GET:
        context['book_pending'] = True
    if 'no_book_alloted' in request.GET:
        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
    if 'bookupdate' in request.GET:
        context['bookupdate'] =True

    books = Book.objects.filter(approved=True).order_by("-id")
    for book in books:
        try:
            images.append(ScreenShots.objects.filter(book=book)[0])
        except:
            return HttpResponse(book)
    context['images'] = images
    book_images = []
    for i in range(len(books)):
        obj = {'book':books[i], 'image':images[i]}
        book_images.append(obj)
    context['items'] = book_images

    #Check if user is logged in and fetch user's pending proposal ID
    if context.get('user'):
        curr_user = request.user
        user_profile = Profile.objects.filter(user=curr_user)

        pending_proposal_list = list(Proposal.objects.filter(status="pending").order_by('id'))
        try:
            pending_user_proposal = Proposal.objects.get(user=user_profile, status="pending")
        except:
            pending_user_proposal = None

        if pending_user_proposal:
            context['proposal_position'] = pending_proposal_list.index(pending_user_proposal) + 1

    return render_to_response('base.html', context)


def _checkprofile(user):
    return Profile.objects.filter(user=user).exists()


def user_login(request):
    context = {}
    context.update(csrf(request))
    if 'require_login' in request.GET:
        context['require_login'] = True
    if request.method == 'POST':
        form = UserLoginForm(request.POST)
        username = request.POST['username']
        password = request.POST['password']
        if username == "" or password == "":
            form = UserLoginForm()
            context['form'] = form
            context['empty'] = True
            return render_to_response('tbc/login.html', context)
        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
            context['invalid'] = True
            return render_to_response('tbc/login.html', context)
        if is_reviewer(curr_user):
            context['reviewer'] = curr_user
            return HttpResponseRedirect("/book-review")
        else:
            context['user'] = curr_user
            try:
                Profile.objects.get(user=curr_user)
                return HttpResponseRedirect("/?login=success")
            except:
                return HttpResponseRedirect("/profile/?update=profile")
    else:
        form = UserLoginForm()
        if 'signup' in request.GET:
            context['signup'] = True
    context['form'] = form
    return render_to_response('tbc/login.html', context)


def user_register(request):
    context = {}
    context.update(csrf(request))
    if request.method == 'POST':
        form = UserRegisterForm(request.POST)
        if form.is_valid():
            email = request.POST['email']
            check_email = User.objects.filter(email=email)
            if check_email:
                context['form'] = form
                context['DuplicateEmail'] = True
                return render_to_response('tbc/register.html', context)
            else:
                user = form.save()
                add_log(user, user, CHANGE, 'Registered')
                return HttpResponseRedirect('/login/?signup=done')
        else:
            context = {}
            context.update(csrf(request))
            context['form'] = form
            return render_to_response('tbc/register.html', context)
    else:
        form = UserRegisterForm()
    context['form'] = form
    return render_to_response('tbc/register.html', context)


def user_profile(request):
    context = {}
    user = request.user
    if user.is_authenticated():
        user_profile = Profile.objects.filter(user=user)
        profile = user_profile[0] if user_profile.exists() else None
        if request.method == 'POST':
            form = UserProfileForm(request.POST, instance=profile)
            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.update(csrf(request))
                context['form'] = form
                return render_to_response('tbc/profile.html', context)
        form = UserProfileForm(instance=profile)
        context.update(csrf(request))
        context['form'] = form
        context['user'] = user
        if 'update' in request.GET:
            context['profile'] = True
        return render_to_response('tbc/profile.html', context)
    else:
        return HttpResponseRedirect('/login/?require_login=True')


def update_profile(request):
    user = request.user
    context = {}
    context.update(csrf(request))
    if user.is_anonymous():
        return HttpResponseRedirect('/login/?require_login=True')
    if not _checkprofile(user):
        return HttpResponseRedirect("/profile/?update=profile")
    context['user'] = user   
    user_profile = Profile.objects.get(user=user)
    if request.method == "POST":
        form = UserProfileForm(request.POST, instance=user_profile)
        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['form'] = form
            return render_to_response('tbc/update-profile.html', context)
    else:
        form = UserProfileForm(instance=user_profile)
    context['form'] = form
    return render_to_response('tbc/update-profile.html', context)

def user_logout(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')


def forgot_password(request):
    context = {}
    user_emails = []
    context.update(csrf(request))
    if request.user.is_anonymous():
        context['anonymous'] = True
    if request.method == 'POST':
        email = request.POST['email']
        profiles = Profile.objects.all()
        for profile in profiles:
            user_emails.append(profile.user.email)
        if email in user_emails:
            user = User.objects.get(email=email)
            password = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(8))
            user.set_password(password)
            user.save()
            subject = "PythonTBC: Password Reset"
            message = """Dear """+user.first_name+""",\nYour password for Python TBC interface has been reset. Your credentials are:\nUsername: """+user.username+"""\nPassword: """+password+"""\n\nKindly login with the given password and update your password through the link given below.\nLink: http://tbc-python.fossee.in/update-password.\n\nThank You !\n\nRegards,\n Python TBC Team,\nFOSSEE - IIT Bombay."""
            email_send(email, subject, message)
            form = UserLoginForm()
            context['form'] = form
            context['forgot_pass_redirection'] = True
            return render_to_response("tbc/login.html", context)
        else:
            context['invalid_email'] = True
            return render_to_response("tbc/forgot-password.html", context)
    else:
        return render_to_response("tbc/forgot-password.html", context)


def update_password(request):
    context = {}
    user = request.user
    context.update(csrf(request))
    if user.is_authenticated():
        if request.method == 'POST':
            new_password = request.POST['new_password']
            confirm = request.POST['confirm_new_password']
            if new_password == "" or confirm == "":
                form = PasswordResetForm()
                context['empty'] = True
                context['form'] = form
                return render_to_response("tbc/update-password.html", context)
            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
                logout(request)
                return render_to_response("tbc/login.html", context)
            else:
                form = PasswordResetForm()
                context['no_match'] = True
                context['form'] = form
                return render_to_response("tbc/update-password.html", context)
        else:
            form = PasswordResetForm()
            context['form'] = form
            return render_to_response("tbc/update-password.html", context)
    else:
        form = UserLoginForm()
        context['form'] = form
        context['require_login'] = True
        return render_to_response("tbc/login.html", context)


def books(request):
    user = request.user
    if user.is_superuser:
        books = Book.objects.all()
        books_incomplete = []
        books_complete = []
        auto = []
        manual = []
        for book in books:
            if book.start_time is None or book.end_time is None:
                books_incomplete.append(book)
            else:
                books_complete.append(book)
        for book in books_incomplete:
            if book.approved_textbook.all():
                auto.append(book)
            else:
                manual.append(book)
        context = {'auto': auto, 'manual': manual, 'books_complete': books_complete}
        return render_to_response('tbc/books.html', context)
    else:
        return HttpResponseRedirect("/login/?require_login=true")


def edit_book(request, book_id):
    user = request.user
    if user.is_superuser:
        book = Book.objects.get(id=book_id)
        context = {}
        context.update(csrf(request))
        if request.method == 'POST':
            form = BookForm(request.POST, instance=book)
            if form.is_valid():
                form.save()
                return books(request)
            else:
                context['form'] = form
                context['book'] = book
                return render_to_response('tbc/edit-book.html', context)
        form = BookForm(instance=book)
        context['form'] = form
        context['book'] = book
        return render_to_response('tbc/edit-book.html', context)
    else:
        return HttpResponseRedirect("/login/?require_login=true")

def books_fill_details(request):
    user = request.user
    if user.is_superuser:
        books = Book.objects.all()
        books_incomplete = []
        books_complete = []
        auto = []
        manual = []
        for book in books:
            if book.courses is None or book.year is None or book.university is None:
                books_incomplete.append(book)
                auto.append(book)
            else:
                books_complete.append(book)
                manual.append(book)
        context = {'auto': auto, 'manual': manual, 'books_complete': books_complete}
        return render_to_response('tbc/books-fill-details.html', context)
    else:
        return HttpResponseRedirect("/login/?require_login=true")

def edit_books_fill_details(request, book_id):
    user = request.user
    if user.is_superuser:
        book = Book.objects.get(id=book_id)
        context = {}
        context.update(csrf(request))
        if request.method == 'POST':
            form = BookForm(request.POST, instance=book)
            if form.is_valid():
                form.save()
                return books_fill_details(request)
            else:
                form.fields['title'].widget.attrs['readonly'] = True
                form.fields['author'].widget.attrs['readonly'] = True
                form.fields['publisher_place'].widget.attrs['readonly'] = True
                form.fields['isbn'].widget.attrs['readonly'] = True
                form.fields['edition'].widget.attrs['readonly'] = True
                form.fields['year_of_pub'].widget.attrs['readonly'] = True
                form.fields['no_chapters'].widget.attrs['readonly'] = True

                context['form'] = form
                context['book'] = book
                return render_to_response('tbc/edit-books-fill-details.html', context)
        form = BookForm(instance=book)
        form.fields['title'].widget.attrs['readonly'] = True
        form.fields['author'].widget.attrs['readonly'] = True
        form.fields['publisher_place'].widget.attrs['readonly'] = True
        form.fields['isbn'].widget.attrs['readonly'] = True
        form.fields['edition'].widget.attrs['readonly'] = True
        form.fields['year_of_pub'].widget.attrs['readonly'] = True
        form.fields['no_chapters'].widget.attrs['readonly'] = True
        context['form'] = form
        context['book'] = book
        return render_to_response('tbc/edit-books-fill-details.html', context)
    else:
        return HttpResponseRedirect("/login/?require_login=true")
    
def submit_book(request):
    context = {}
    if request.user.is_anonymous():
        return HttpResponseRedirect("/login/?require_login=true")
    else:
        curr_user = request.user
        if curr_user.is_authenticated():
            if not _checkprofile(curr_user):
                return HttpResponseRedirect("/profile/?update=profile")
    user_profile = Profile.objects.get(user=curr_user)
    curr_proposals = Proposal.objects.filter(user=user_profile)
    user_books = Book.objects.filter(contributor=user_profile)
    can_submit_book = True
    for proposal in curr_proposals:
        if proposal.status not in ['book completed', 'rejected']:
            can_submit_book = False
    for book in user_books:
        if not book.approved:
            can_submit_book = False
    if can_submit_book:
        if request.method == 'POST':
            form = BookForm(request.POST)
            if form.is_valid():
                data = form.save(commit=False)
                profile = Profile.objects.get(user=request.user.id)
                data.contributor = profile
                data.reviewer = Reviewer.objects.get(pk=2)
                data.save()
                context['user'] = curr_user
                curr_book = Book.objects.order_by("-id")[0]
                curr_book_id = curr_book.id
                return HttpResponseRedirect('/submit-code-old/'+str(curr_book_id))
            else:
                context.update(csrf(request))
                context['form'] = form
                context['user'] = curr_user
                return render_to_response('tbc/submit-book.html', context)
        else:
            form = BookForm()
        context.update(csrf(request))
        context['form'] = form
        context['user'] = curr_user
        return render_to_response('tbc/submit-book.html', context)
    else:
        return HttpResponseRedirect('/?book_pending=True')
        


def submit_code_old(request, book_id=None):
    user = request.user
    if not _checkprofile(user):
        return HttpResponseRedirect("/profile/?update=profile")
    curr_profile = Profile.objects.get(user=user)
    context = {}
    dict = {}
    curr_book = Book.objects.get(id=book_id)
    if request.method == 'POST':
        for i in range(1, curr_book.no_chapters+1):
            chapter = Chapters()
            chapter.name = request.POST['chapter'+str(i)]
            dict['chapter'+str(i)] = chapter.name
            chapter.notebook = request.FILES['notebook'+str(i)]
            chapter.book = curr_book
            chapter.save()
        for i in range(1, 4):
            screenshot = ScreenShots()
            screenshot.caption = request.POST['caption'+str(i)]
            screenshot.image = request.FILES['image'+str(i)]
            screenshot.book = curr_book
            screenshot.save()
            chapter_image = request.POST['chapter_image'+str(i)]
            chapter = list(Chapters.objects.filter(name=dict[chapter_image]))[-1]
            chapter.screen_shots.add(screenshot)
            chapter.save()
        subject = "Python-TBC: Codes Submitted Acknowledgement"
        message = """Hi """+curr_book.contributor.user.first_name+""",\nThank you for your contribution to Python TBC.\nWe have received the book & codes submitted by you.\nDetails of the book are given below: \nBook Title: """+curr_book.title+"""\nAuthor: """+curr_book.author+"""\n Publisher: """+curr_book.publisher_place+"""\nISBN: """+curr_book.isbn+"""\n\nPlease be patient while we review your book & get back to you. Review of the book will take a minimum of 45 days. Hoping for kind cooperation."""
        email_send(curr_book.contributor.user.email, subject, message)
        subject = "Python-TBC: Book Submission"
        message = """Hi """+curr_book.reviewer.name+""",\nA book has been submitted on the Python TBC interface.\n Details of the book & contributor:\n Contributor: """+curr_book.contributor.user.first_name+""" """+curr_book.contributor.user.last_name+"""\nBook Title"""+curr_book.title+"""\nAuthor: """+curr_book.title+"""\nAuthor: """+curr_book.author+"""\n Publisher: """+curr_book.publisher_place+"""\nISBN: """+curr_book.isbn+"""\nFollow the link to riview the book:\nhttp://tbc-python.fosse.in/book-review/"""+str(curr_book.id)
        email_send(curr_book.reviewer.email, subject, message)
        return HttpResponseRedirect('/?up=done')
    else:
        context.update(csrf(request))
        context['user'] = user
        context['curr_book'] = curr_book
        context['no_notebooks'] = [i for i in range(1, curr_book.no_chapters+1)]
        context['no_images'] = [i for i in range(1, 4)]
        return render_to_response('tbc/upload-content-old.html', context)


def submit_proposal(request):
    curr_user = request.user
    if not _checkprofile(curr_user):
        return HttpResponseRedirect("/profile/?update=profile")
    user_profile = Profile.objects.get(user=curr_user.id)
    context = {}
    context.update(csrf(request))
    context['user'] = curr_user
    user_proposals = list(Proposal.objects.filter(user=user_profile))
    proposal_id = None
    can_submit_new = True
    matching_books = []
    for proposal in user_proposals:
        if proposal.status != 'book completed':
            can_submit_new = False
        if proposal.status == 'rejected':
            can_submit_new = True
            proposal_id = proposal.id

    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')
            book_pubs = request.POST.getlist('publisher_place')
            book_isbns = request.POST.getlist('isbn')
            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()
            textbooks.delete()
            proposed_books = []
            for item in range(3):
                tempbook = TempBook(no_chapters=0)
                tempbook.title = book_titles[item]
                tempbook.author = book_authors[item]
                tempbook.category = book_categories[item]
                tempbook.publisher_place = book_pubs[item]
                tempbook.isbn = book_isbns[item]
                tempbook.edition = book_editions[item]
                tempbook.year_of_pub = book_years[item]
                tempbook.save()
                proposal.textbooks.add(tempbook)
                proposed_books.append(tempbook)
            subject = "Python TBC: Proposal Acknowledgement"
            message = """Dear """+proposal.user.user.first_name+""",\n
Thank you for showing interest in contributing to Python Textbook Companion Activity.\n\nWe have received your proposal. Details of the books proposed by you are given below:\n\nBook Preference 1\nTitle: """+proposed_books[0].title+"""\nAuthor: """+proposed_books[0].author+"""\nEdition: """+proposed_books[0].edition+"""\nISBN: """+proposed_books[0].isbn+"""\nPublisher: """+proposed_books[0].publisher_place+"""\nYear of Publication: """+proposed_books[0].year_of_pub+"""\n\nBook Preference 2\nTitle: """+proposed_books[1].title+"""\nAuthor: """+proposed_books[1].author+"""\nEdition: """+proposed_books[1].edition+"""\nISBN: """+proposed_books[1].isbn+"""\nPublisher: """+proposed_books[1].publisher_place+"""\nYear of Publication: """+proposed_books[1].year_of_pub+"""\n\nBook Preference 3\nTitle: """+proposed_books[2].title+"""\nAuthor: """+proposed_books[2].author+"""\nEdition: """+proposed_books[2].edition+"""\nISBN: """+proposed_books[2].isbn+"""\nPublisher: """+proposed_books[2].publisher_place+"""\nYear of Publication: """+proposed_books[2].year_of_pub+"""\n\nPlese be patient while we review your proposal. You will be notified to submit sample notebook once the proposal has been reviewed. Review of the proposal will take a minimum of 45 days.\n\nRegards,\nPython TBC Team\nFOSSEE - IIT Bombay"""
            add_log(curr_user, proposal, CHANGE, 'Proposed Books', proposal.id)
            email_send(proposal.user.user.email, subject, message)
            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()
                    if len(textbooks) == 3:
                        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)
    else:
        return HttpResponseRedirect('/?proposal_pending=True')


def list_aicte(request):
    if request.user.is_anonymous():
        return HttpResponseRedirect('/login/?require_login=True')
    else:
        curr_user = request.user
    if not _checkprofile(curr_user):
        return HttpResponseRedirect("/profile/?update=profile")
    user_profile = Profile.objects.get(user=curr_user.id)
    user_proposals = Proposal.objects.filter(user=user_profile)
    context = {}
    context.update(csrf(request))
    context['user'] = curr_user
    if request.method == "POST":
        category = request.POST['category']
        return HttpResponse(category)
        context['category'] = category
        if category == "all":
            aicte_books = AicteBook.objects.filter(proposed=0)
        else:
            aicte_books = AicteBook.objects.filter(category=category, proposed=0)
        if len(aicte_books) == 0:
            context['no_books'] = True
    else:
        aicte_books = AicteBook.objects.filter(proposed=0)
        context['aicte_books'] = aicte_books
    return render_to_response('tbc/aicte-books.html', context)


def submit_aicte_proposal(request, aicte_book_id=None):
    if request.user.is_anonymous():
        return HttpResponseRedirect('/login/?require_login=True')
    else:
        curr_user = request.user
    if not _checkprofile(curr_user):
        return HttpResponseRedirect("/profile/?update=profile")
    user_profile = Profile.objects.get(user=curr_user.id)
    context = {}
    context.update(csrf(request))
    context['user'] = curr_user
    user_proposals = Proposal.objects.filter(user=user_profile)
    book_proposed = AicteBook.objects.get(id=aicte_book_id)
    context['aicte_book'] = book_proposed
    can_submit_new = True
    proposal_id = None
    for proposal in user_proposals:
        if proposal.status != "book completed":
            can_submit_new = False
        if proposal.status == 'rejected':
            can_submit_new = True
            proposal_id = proposal.id
    if can_submit_new:
        if request.method == 'POST':
            book_form = BookForm(request.POST, instance=book_proposed)
            if book_form.is_valid():
                data = book_form.save(commit=False)
                data.save()
                try:
                    proposal = Proposal.objects.get(id=proposal_id)
                except:
                    proposal = Proposal()
                proposal.user = user_profile
                proposal.status = 'Pending'
                proposal.save()
                textbooks = proposal.textbooks.all()
                if textbooks:
                    textbooks.delete()
                tempbook = TempBook(no_chapters=0)
                tempbook.title = book_proposed.title
                tempbook.author = book_proposed.author
                tempbook.category = book_proposed.category
                tempbook.publisher_place = book_proposed.publisher_place
                tempbook.isbn = book_proposed.isbn
                tempbook.edition = book_proposed.edition
                tempbook.year_of_pub = book_proposed.year_of_pub
                tempbook.save()
                proposal.textbooks.add(tempbook)
                add_log(curr_user, proposal, CHANGE, 'AICTE proposal' ,proposal.id)
                subject = "Python TBC: Proposal Acknowledgement"
                message = """Dear """+proposal.user.user.first_name+""",\n
    Thank you for showing interest in contributing to Python Textbook Companion Activity.\n\nWe have received your proposal & you have chosen to contribute an AICTE recommended book. Review of the proposal will take a minimum of 45 days. Detail of the book you proposed is given below:\nTitle: """+tempbook.title+"""\nAuthor: """+tempbook.author+"""\nEdition: """+tempbook.edition+"""\nISBN: """+tempbook.isbn+"""\nPublisher: """+tempbook.publisher_place+"""\nYear of Publication: """+tempbook.year_of_pub+"""\n\nRegards,\nPython TBC Team\nFOSSEE - IIT Bombay"""
                email_send(proposal.user.user.email, subject, message)
                return HttpResponseRedirect('/?proposal=submitted')
            else:
                context['form'] = book_form
                return render_to_response('tbc/confirm-aicte-details.html', context)
        else:
            book_form = BookForm()
            book_form.initial['title'] = book_proposed.title
            book_form.initial['author'] = book_proposed.author
            book_form.initial['publisher_place'] = book_proposed.publisher_place
            book_form.initial['category'] = book_proposed.category
            book_form.initial['isbn'] = book_proposed.isbn
            book_form.initial['edition'] = book_proposed.edition
            book_form.initial['year_of_pub'] = book_proposed.year_of_pub
            context['form'] = book_form
            return render_to_response('tbc/confirm-aicte-details.html', context)
    else:
        return HttpResponseRedirect('/?proposal_pending=True')


def review_proposals(request, proposal_id=None, textbook_id=None):
    context = {}
    user = request.user
    if is_reviewer(user):
        context['reviewer'] = user
        if proposal_id:
            proposal = Proposal.objects.get(id=proposal_id)
            accepted_book = TempBook.objects.get(id=textbook_id)
            new_book = Book()
            new_book.title = accepted_book.title
            new_book.author = accepted_book.author
            new_book.category = accepted_book.category
            new_book.publisher_place = accepted_book.publisher_place
            new_book.isbn = accepted_book.isbn
            new_book.edition = accepted_book.edition
            new_book.year_of_pub = accepted_book.year_of_pub
            new_book.no_chapters = accepted_book.no_chapters
            new_book.contributor = proposal.user
            new_book.reviewer = Reviewer.objects.get(pk=2)
            new_book.save()
            proposal.status = "samples"
            proposal.accepted = new_book
            proposal.save()
            add_log(user, proposal, CHANGE, 'Proposal accepted', proposal.id)
            subject = "Python-TBC: Proposal Reviewed"
            message = """Dear """+proposal.user.user.first_name+""", \n\nYour recent proposal for Python TBC has been reviewed and the book titled """+proposal.accepted.title+""" by """+proposal.accepted.author+""" has been approved. You may now submit the sample notebook on the interface. Once the sample notebook is approved, the book will be alloted to you.\n\nRegards,\nPython TBC Team\nFOSSEE - IIT Bombay"""
            email_send(proposal.user.user.email, subject, message)
            return HttpResponseRedirect("/proposal-review")
        else:
            new_proposals = Proposal.objects.filter(status="pending").order_by('id')
            old_proposals = []
            old_proposal_status = ['samples', 'sample disapproved', 'sample resubmitted', 'sample submitted']
            proposals = Proposal.objects.filter(status__in=old_proposal_status)
            for proposal in proposals:
                try:
                    sample_notebook = SampleNotebook.objects.get(proposal=proposal)
                except:
                    sample_notebook = None
                obj = {'proposal':proposal, 'sample':sample_notebook}
                old_proposals.append(obj)
            if new_proposals.count() > 0:
                no_new_proposal = False
            else:
                no_new_proposal = True
            context['no_new_proposal'] = no_new_proposal
            context['proposals'] = new_proposals
            context['old_proposals'] = old_proposals
            return render_to_response('tbc/review-proposal.html', context)
    else:
        return HttpResponse("not allowed")


def disapprove_proposal(request, proposal_id=None):
    context = {}
    context.update(csrf(request))
    proposal = Proposal.objects.get(id=proposal_id)
    if request.method == 'POST':
        changes_required = request.POST['changes_required']
        subject = "Python-TBC: Corrections Required in the sample notebook"
        message = """Hi, """+proposal.user.user.first_name+""",\nSample notebook submitted by you for the book titled, """+proposal.accepted.title+""",\nrequires following changes: \n"""+changes_required+"""\n\nKindly make the necessary changes and upload the sample notebook again.\n\nThank You !\n\n Regards,\nPython TBC Team\nFOSSEE - IIT Bombay"""
        add_log(request.user, proposal, CHANGE, 'Sample disapproved',
                proposal_id, chat=subject + '\n' + changes_required)
        context.update(csrf(request))
        proposal.status = "sample disapproved"
        proposal.save()
        email_send(proposal.user.user.email, subject, message)
        return HttpResponseRedirect("/book-review/?mail_notify=done")
    else:
        context['proposal'] = proposal
        return render_to_response('tbc/disapprove-sample.html', context)


def allot_book(request, proposal_id=None):
    context = {}
    proposal = Proposal.objects.get(id=proposal_id)
    proposal.status = "book alloted"
    proposal.save()
    subject = "Python-TBC: Book Alloted"
    message = """Hi """+proposal.user.user.first_name+""",\n The sample examples for the book '"""+proposal.accepted.title+"""' are correct. Hence, the book is now allotted to you. A time period of 2 months from today is allotted to you for completion of the book. Convert all the solved/worked examples of all the chapters. You can get back to us for any queries.\n\nGood Luck!\n\nRegards,\nPython TBC Team\nFOSSEE - IIT Bombay"""
    add_log(request.user, proposal, CHANGE, 'Book alloted', proposal_id)
    email_send(proposal.user.user.email, subject, message)
    return HttpResponseRedirect("/book-review/?book_alloted=done")


def reject_proposal(request, proposal_id=None):
    context = {}
    context.update(csrf(request))
    proposal = Proposal.objects.get(id=proposal_id)
    if request.method == 'POST':
        books = proposal.textbooks.all() 
        if len(books) == 1:
            aicte_book = AicteBook.objects.get(isbn=books[0].isbn)
            aicte_book.proposed = False
            aicte_book.save()
        proposal.status = 'rejected'
        proposal.save()
        remarks = request.POST['remarks']
        subject = "Python-TBC: Rejection of Proposal"
        message = """Dear """+proposal.user.user.first_name+"""\nYour recent proposal for contributing in Python TBC has been rejected for the following reasons\n"""+request.POST.get('remarks')+"""\n\nHowever, your last proposal will be saved and you can edit the same proposal or propose a fresh one again.\n\nRegards\nPython TBC Team\nFOSSEE - IIT Bombay"""
        add_log(request.user, proposal, CHANGE, 'Proposal rejected',
                proposal.id, chat=subject + '\n' + remarks)
        email_send(proposal.user.user.email, subject, message)
        context.update(csrf(request))
        return HttpResponseRedirect("/book-review/?reject-proposal=done")
    else:
        context['proposal'] = proposal
        return render_to_response('tbc/reject-proposal.html', context)


def submit_sample(request, proposal_id=None, old_notebook_id=None):
    context = {}
    if request.user.is_anonymous():
        return HttpResponseRedirect('/login/?require_login=True')
    else:
        user = request.user
    if not _checkprofile(user):
        return HttpResponseRedirect("/profile/?update=profile")
    context.update(csrf(request))
    if request.method == "POST":
        curr_proposal = Proposal.objects.get(id=proposal_id)
        add_log(user, curr_proposal, CHANGE, 'Sample Submitted', curr_proposal.id)
        if old_notebook_id:
            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()
            curr_proposal.status = "sample resubmitted"
            curr_proposal.save()
            return HttpResponseRedirect('/?sample_notebook=done')
        else:
            sample_notebook = SampleNotebook()
            sample_notebook.proposal = curr_proposal
            sample_notebook.name = request.POST.get('ch_name')
            sample_notebook.sample_notebook = request.FILES['sample_notebook']
            sample_notebook.save()
            curr_proposal.status = "sample submitted"
            curr_proposal.save()
            return HttpResponseRedirect('/?sample_notebook=done')
    else:
        profile = Profile.objects.get(user=user)
        try:
            proposal = Proposal.objects.get(user=profile, status__in=['samples','sample disapproved'])
        except Proposal.DoesNotExist:
            return HttpResponseRedirect('/?cannot_submit_sample=True')
        try:
            old_notebook = SampleNotebook.objects.get(proposal=proposal)
            context['has_old'] = True
            context['old_notebook'] = old_notebook
            context['proposal'] = proposal
            return render_to_response('tbc/submit-sample.html', context)
        except:
            context['proposal'] = proposal
            return render_to_response('tbc/submit-sample.html', context)


def confirm_book_details(request):
    context = {}
    if request.user.is_anonymous():
        return HttpResponseRedirect('/login/?require_login=True')
    else:
        current_user = request.user
    if not _checkprofile(current_user):
        return HttpResponseRedirect("/profile/?update=profile")
    user_profile = Profile.objects.get(user=current_user)
    try:
        proposal = Proposal.objects.get(user=user_profile, status__in=["book alloted", "codes disapproved"])
    except:
        return HttpResponseRedirect('/?no_book_alloted=true')
    book_to_update = Book.objects.get(id=proposal.accepted.id)
    if request.method == 'POST':
        book_form = BookForm(request.POST, instance=book_to_update)
        if book_form.is_valid():
            data = book_form.save(commit=False)
            data.contributor = user_profile
            data.save()
            context.update(csrf(request))
            context['form'] = book_form
            add_log(current_user, book_to_update, CHANGE, 'Book updated', proposal.id)
            if proposal.status == "codes disapproved":
                chapters = Chapters.objects.filter(book=book_to_update)
                screen_shots = ScreenShots.objects.filter(book=book_to_update)
                context.update(csrf(request))
                context['book'] = book_to_update
                context['chapters'] = chapters
                context['screenshots'] = screen_shots
                context['no_notebooks'] = [i for i in range(1, book_to_update.no_chapters+1)]
                return render_to_response('tbc/update-code.html', context)
            return HttpResponseRedirect('/submit-code/')
        else:
            context.update(csrf(request))
            context['form'] = book_form
            context['book'] = book_to_update
            return render_to_response('tbc/confirm-details.html', context)
    else:
        book_form = BookForm()
        book_form.initial['title'] = book_to_update.title
        book_form.initial['author'] = book_to_update.author
        book_form.initial['publisher_place'] = book_to_update.publisher_place
        book_form.initial['category'] = book_to_update.category
        book_form.initial['isbn'] = book_to_update.isbn
        book_form.initial['edition'] = book_to_update.edition
        book_form.initial['year_of_pub'] = book_to_update.year_of_pub
        book_form.initial['no_chapters'] = book_to_update.no_chapters
        book_form.initial['reviewer'] = book_to_update.reviewer
        context.update(csrf(request))
        context['form'] = book_form
        context['book'] = book_to_update
        return render_to_response('tbc/confirm-details.html', context)




def submit_code(request):
    if request.user.is_anonymous():
        return HttpResponseRedirect('/login/?require_login=True')
    else:
        user = request.user
    if not _checkprofile(user):
        return HttpResponseRedirect("/profile/?update=profile")
    curr_profile = Profile.objects.get(user=user)
    context = {}
    try:
        curr_proposal = Proposal.objects.get(user=curr_profile, status__in=['book alloted', 'codes disapproved'])
        curr_book = curr_proposal.accepted
    except:
        return HttpResponseRedirect('/?no_book_alloted=true')
    dict = {}
    if curr_proposal.status == "codes disapproved":
        if request.method == 'POST':
            chapters = Chapters.objects.filter(book=curr_book)
            old_chapter_count = len(chapters)
            screen_shots = ScreenShots.objects.filter(book=curr_book)
            counter = 1
            for chapter in chapters:
                chapter.name = request.POST['chapter'+str(counter)]
                chapter.notebook = request.FILES['notebook'+str(counter)]
                dict['chapter'+str(counter)] = chapter.name
                chapter.screen_shots.clear()
                chapter.save()
                counter += 1
            num_new_chapters = curr_book.no_chapters - old_chapter_count
            if num_new_chapters > 0:
                for i in range(num_new_chapters):
                    new_chapter = Chapters()
                    new_chapter.book = curr_book
                    new_chapter.name = request.POST['chapter'+str(counter)]
                    new_chapter.notebook = request.FILES['notebook'+str(counter)]
                    new_chapter.save()
                    counter += 1
            counter = 1
            for screenshot in screen_shots:
                screenshot.caption = request.POST['caption'+str(counter)]
                screenshot.image = request.FILES['image'+str(counter)]
                screenshot.save()
                chapter_image = request.POST['chapter_image'+str(counter)]
                # if chapter name is unique then no need to convert the query
                # set to list. Instead of filter get can be used then.
                chapter = list(Chapters.objects.filter(name=dict[chapter_image]))[-1]
                chapter.screen_shots.add(screenshot)
                chapter.save()
                counter += 1
            curr_proposal.status = "codes submitted"
            curr_proposal.save()
            subject = "Python-TBC: Book & Code Updated"
            message = """Hi """+curr_book.reviewer.name+""",\nA book & code has been updated on the Python TBC interface.\n Details of the book & contributor:\n Contributor: """+curr_book.contributor.user.first_name+""" """+curr_book.contributor.user.last_name+"""\nBook Title"""+curr_book.title+"""\nAuthor: """+curr_book.title+"""\nAuthor: """+curr_book.author+"""\n Publisher: """+curr_book.publisher_place+"""\nISBN: """+curr_book.isbn+"""\nFollow the link to riview the book:\nhttp://tbc-python.fosse.in/book-review/"""+str(curr_book.id)
            add_log(user, curr_book, CHANGE, 'Codes & Screenshots Resubmitted',
                curr_proposal.id)
            email_send(curr_book.reviewer.email, subject, message)
            subject = "Python-TBC: Codes Updated Acknowledgement"
            message = """Hi """+curr_book.contributor.user.first_name+""",\nCodes for the book given below have been successfully updated.\nBook Title: """+curr_book.title+"""\nAuthor: """+curr_book.author+"""\n Publisher: """+curr_book.publisher_place+"""\nISBN: """+curr_book.isbn+"""\n\nPlease be patient while we review your updated codes & get back to you. Review of the codes will take a minimum of 45 days. Hoping for kind cooperation."""
        email_send(curr_book.contributor.user.email, subject, message)
        return HttpResponseRedirect('/?bookupdate=done')
    if request.method == 'POST':
        for i in range(1, curr_book.no_chapters+1):
            chapter = Chapters()
            chapter.name = request.POST['chapter'+str(i)]
            dict['chapter'+str(i)] = chapter.name
            chapter.notebook = request.FILES['notebook'+str(i)]
            chapter.book = curr_book
            chapter.save()
        for i in range(1, 4):
            screenshot = ScreenShots()
            screenshot.caption = request.POST['caption'+str(i)]
            screenshot.image = request.FILES['image'+str(i)]
            screenshot.book = curr_book
            screenshot.save()
            chapter_image = request.POST['chapter_image'+str(i)]
            chapter = list(Chapters.objects.filter(name=dict[chapter_image]))[-1]
            chapter.screen_shots.add(screenshot)
            chapter.save()
        curr_proposal.status = "codes submitted"
        curr_proposal.save()
        subject = "Python-TBC: Book Submission"
        message = """Hi """+curr_book.reviewer.name+""",\nA book has been submitted on the Python TBC interface.\n Details of the book & contributor:\n Contributor: """+curr_book.contributor.user.first_name+""" """+curr_book.contributor.user.last_name+"""\nBook Title"""+curr_book.title+"""\nAuthor: """+curr_book.title+"""\nAuthor: """+curr_book.author+"""\n Publisher: """+curr_book.publisher_place+"""\nISBN: """+curr_book.isbn+"""\nFollow the link to riview the book:\nhttp://tbc-python.fosse.in/book-review/"""+str(curr_book.id)
        log_chat = subject + '\n' + 'Book ' + curr_book.title + \
                ' has been submitted on the Python TBC interface.'
        add_log(user, curr_book, CHANGE, 'Chapters and Screenshots added',
                curr_proposal.id, chat=log_chat)
        email_send(curr_book.reviewer.email, subject, message)
        subject = "Python-TBC: Codes Submitted Acknowledgement"
        message = """Hi """+curr_book.contributor.user.first_name+""",\nThank you for your contribution to Python TBC.\nWe have received the book & codes submitted by you.\nDetails of the book are given below: \nBook Title: """+curr_book.title+"""\nAuthor: """+curr_book.author+"""\n Publisher: """+curr_book.publisher_place+"""\nISBN: """+curr_book.isbn+"""\n\nPlease be patient while we review your book & get back to you. Review of the book will take a minimum of 45 days. Hoping for kind cooperation."""
        email_send(curr_book.contributor.user.email, subject, message)
        return HttpResponseRedirect('/?up=done')
    else:
        context.update(csrf(request))
        context['user'] = user
        context['curr_book'] = curr_book
        context['no_notebooks'] = [i for i in range(1, curr_book.no_chapters+1)]
        context['no_images'] = [i for i in range(1, 4)]
        return render_to_response('tbc/upload-content.html', context)


def update_content(request, book_id=None):
    context = {}
    if request.user.is_anonymous():
        return HttpResponseRedirect('/login/?require_login=True')
    else:
        user = request.user
    current_book = Book.objects.get(id=book_id)
    chapters_to_update = Chapters.objects.filter(book=current_book)
    screenshots_to_update = ScreenShots.objects.filter(book=current_book)
    if request.method == 'POST':
        for i in range(1, current_book.no_chapters+1):
            chapter = Chapters.objects.get(id=chapters_to_update[i-1].id)
            chapter.name = request.POST['chapter'+str(i)]
            chapter.notebook = request.FILES['notebook'+str(i)]
            chapter.book = current_book
            chapter.save()
        for i in range(1, 4):
            screenshot = ScreenShots.objects.get(id=screenshots_to_update[i-1].id)
            screenshot.caption = request.POST['caption'+str(i)]
            screenshot.image = request.FILES['image'+str(i)]
            screenshot.book = current_book
            screenshot.save()
        proposal = Proposal.objects.get(accepted=current_book)
        subject = "Python-TBC: Book Updated"
        message = """Hi """+curr_book.reviewer.name+""",\nSubmission for a book has been updated on the Python TBC interface.\n Detailf othe book & contributor: \nContributor: """+curr_book.contributor.user.first_name+""" """+curr_book.contributor.user.last_name+"""\nBook Title"""+curr_book.title+"""\nAuthor: """+curr_book.title+"""\nAuthor: """+curr_book.author+"""\n Publisher: """+curr_book.publisher_place+"""\nISBN: """+curr_book.isbn+"""\nFollow the link to riview the book:\nhttp://tbc-python.fosse.in/book-review/"""+str(curr_book.id)
        log_chat = subject + '\n' + current_book.title +\
                ' book has been updated on the Python TBC interface.'
        add_log(user, current_book, CHANGE, 'book updated', proposal.id,
                chat=log_chat)
        email_send(current_book.reviewer.email, subject, message)
        return HttpResponseRedirect('/?update_book=done')
    else:
        context.update(csrf(request))
        context['user'] = user
        context['current_book'] = current_book
        context['chapters'] = chapters_to_update
        context['screenshots'] = screenshots_to_update
        return render_to_response('tbc/update-content.html', context)


def generate_zip(book_id):
    book = Book.objects.get(id=book_id)
    files_to_zip = []
    file_path = os.path.abspath(os.path.dirname(__file__))
    file_path = file_path+"/static/Python-Textbook-Companions/"
    notebooks = Chapters.objects.filter(book=book)
    for notebook in notebooks:
        files_to_zip.append(file_path+str(notebook.notebook))
    zip_subdir = "PythonTBC"
    zipfile_name = "%s.zip" %zip_subdir
    s = StringIO.StringIO()
    zip_file = zipfile.ZipFile(s, 'w')
    for fpath in files_to_zip:
        fdir, fname = os.path.split(fpath)
        zip_path = os.path.join(book.title, fname)
        zip_file.write(fpath, zip_path)
    zip_file.close()
    return s, zipfile_name


def get_zip(request, book_id=None):
    user = request.user
    s, zipfile_name = generate_zip(book_id)
    resp = HttpResponse(s.getvalue(), content_type = "application/x-zip-compressed")
    resp['Content-Disposition'] = 'attachment; filename=%s' % zipfile_name
    return resp


def book_details(request, book_id=None):
    context = {}
    if request.user.is_anonymous():
        context['anonymous'] = True
    else:
        if is_reviewer(request.user):
            context['reviewer'] = request.user
        else:
            context['user'] = request.user
    book = Book.objects.get(id=book_id)
    chapters = Chapters.objects.filter(book=book).order_by('pk')
    images = ScreenShots.objects.filter(book=book)
    context['chapters'] = chapters
    context['images'] = images
    context['book'] = book
    return render_to_response('tbc/book-details.html', context)


def book_review(request, book_id=None):
    context = {}
    if is_reviewer(request.user):
        if book_id:
            book = Book.objects.get(id=book_id)
            chapters = Chapters.objects.filter(book=book).order_by('name')
            images = ScreenShots.objects.filter(book=book)
            #for old books (before automated proposal)
            try:
                proposal = Proposal.objects.get(accepted=book)
                logs = ActivityLog.objects.filter(proposal_id=proposal.id)
                context['logs'] = logs
                context['proposal'] = proposal
            except:
                pass
            context['chapters'] = chapters
            context['images'] = images
            context['book'] = book
            context['reviewer'] = request.user
            context.update(csrf(request))
            return render_to_response('tbc/book-review-details.html', context)
        else:
            if 'book_review' in request.GET:
                context['book_review'] = True
            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))
            return render_to_response('tbc/book-review.html', context)
    else:
        return render_to_response('tbc/forbidden.html')


def approve_book(request, book_id=None):
    context = {}
    user = request.user
    if is_reviewer(request.user):
        if request.method == 'POST' and request.POST['approve_notify'] == "approve":
            book = Book.objects.get(id=book_id)
            file_path = local.path
            book_title = book.title.replace(" ", "_")
            book_title = book_title +'_by_'+book.author.replace(" ", "_")
            directory = file_path+book_title
            os.chdir(directory)
            fp = open(directory+"/README.txt", 'w')
            fp.write("Contributed By: "+book.contributor.user.first_name+" "+book.contributor.user.last_name+"\n")
            fp.write("Course: "+book.contributor.course+"\n")
            fp.write("College/Institute/Organization: "+book.contributor.insti_org+"\n")
            fp.write("Department/Designation: "+book.contributor.dept_desg+"\n")
            fp.write("Book Title: "+book.title+"\n")
            fp.write("Author: "+book.author+"\n")
            fp.write("Publisher: "+book.publisher_place+"\n")
            fp.write("Year of publication: "+book.year_of_pub+"\n")
            fp.write("Isbn: "+book.isbn+"\n")
            fp.write("Edition: "+book.edition)
            fp.close()
            try:
                proposal = Proposal.objects.get(accepted=book)
                proposal.status = "book completed"
                proposal.save()
                msg = "Book Approved"
            except Proposal.DoesNotExist:
                proposal = Proposal()
                proposal.user = book.contributor
                proposal.accepted = book
                proposal.status = "book completed"
                proposal.save()
                msg = "Old Book Approved"
            book.approved = True
            book.save()
            subject = "Python-TBC: Book Completion"
            message = """Hi """+book.contributor.user.first_name+""",\n
Congratulations !\nThe book - """+book.title+""" is now complete & published.\nPlease visit the link given below to download the forms to be filled to complete the formalities.\nhttp://tbc-python.fossee.in/internship-forms\nThe forms should be duly filled (fill only the sections which are applicable) & submitted at the following address:\nDr. Prabhu Ramachandran,\nDepartment of Aerospace Engineering,\nIIT Bombay, Powai, Mumbai - 400076\nKindly write Python Textbook Companion on top of the envelope.\nIf you have already sent the forms then you may kindly ignore this mail.\n\nPlease note that honorarium will be processed within 2 months from the day we receive your forms. We kindly request you to be patient.\n\nCertificate for completed books can be downloaded from the TBC interface itself under the 'Get Certificate' tab which will be available once you login.\n\nThank You for your contribution !\nRegards,\n Python TBC Team,\nFOSSEE - IIT Bombay"""
            add_log(user, book, CHANGE, msg, proposal.id,
                    chat=subject + '\n' + message)
            email_send(book.contributor.user.email, subject, message)
            context['user'] = user
            return HttpResponseRedirect("/book-review/?book_review=done")
        elif request.method == 'POST' and request.POST['approve_notify'] == "notify":
            return HttpResponseRedirect("/notify-changes/"+book_id)
        else:
            context['user'] = user
            return HttpResponseRedirect("/book-review/"+book_id)
    else:
        return render_to_response('tbc/forbidden.html')


def notify_changes(request, book_id=None):
    context = {}
    if is_reviewer(request.user):
        book = Book.objects.get(id=book_id)
        if request.method == 'POST':
            try:
                proposal = Proposal.objects.get(accepted=book)
                proposal.status = 'codes disapproved'
                proposal.save()
                msg = "Notified Changes"
            except Proposal.DoesNotExist:
                proposal = Proposal()
                proposal.user = book.contributor
                proposal.accepted = book
                proposal.status = 'codes disapproved'
                proposal.save()
                msg = "Notified changes for old book"
            changes_required = request.POST['changes_required']
            subject = "Python-TBC: Corrections Required"
            message = """Hi, """+book.contributor.user.first_name+""",\n\nBook titled, '"""+book.title+"""' requires following changes\n"""+changes_required+"""\n\nKindly make the required corrections and submit the codes again.\n\nRegards,\nPython TBC Team\nFOSSEE - IIT Bombay"""
            context.update(csrf(request))
            add_log(request.user, book, CHANGE, msg,
                    proposal.id, chat=subject+'\n'+changes_required)
            email_send(book.contributor.user.email, subject, message)
            return HttpResponseRedirect("/book-review/?mail_notify=done")
        else:
            context['book'] = book
            context['book_id'] = book_id
            context['mailto'] = book.contributor.user.email
            context['reviewer'] = request.user
            context.update(csrf(request))
            return render_to_response('tbc/notify-changes.html', context)
    else:
        return render_to_response('tbc/forbidden.html')


def browse_books(request):
    context = {}
    category = None
    courses = None
    year = None
    university = None
    images = []
    book_images = []
    books = None
    #course_books = None
    #year_of_course_list = None
    #university_list = None
    if request.user.is_anonymous():
        context['anonymous'] = True
    else:
        if is_reviewer(request.user):
            context['reviewer'] = request.user
        else:
            context['user'] = request.user
    context.update(csrf(request))
    books = Book.objects.filter(approved=True)
   # course_books = Book.objects.filter(approved=True)
   # year_of_course = Book.objects.filter(approved=True)
   # university_list = Book.objects.filter(approved=True)
    if request.method == "GET":
        category = request.GET.get('category')
        courses = request.GET.get('courses')
        year = request.GET.get('year')
        university = request.GET.get('university')
        if category == "all" and courses == "all" and year == "all" and university == "all":
            books = Book.objects.filter(approved=True)
        elif category !="all" and courses == "all" and year == "all" and university == "all":
            books = Book.objects.filter(category=category)
        elif category =="all" and courses != "all" and year == "all" and university == "all":
            books = Book.objects.filter(courses=courses)
        elif category !="all" and courses == "all" and year != "all" and university == "all":
            books = Book.objects.filter(year=year)
        elif category !="all" and courses == "all" and year == "all" and university != "all":
            books = Book.objects.filter(university=university)
        else:
            books = Book.objects.filter(category=category,courses=courses,year=year,university=university)
    for book in books:
        images.append(ScreenShots.objects.filter(book=book)[0])
    for i in range(len(books)):
       obj = {'book':books[i], 'image':images[i]}
       book_images.append(obj)
    context['   items'] = book_images
    context['category'] = category
    context['courses'] = courses
    context['year'] = year
    context['university'] = university
    return render_to_response('tbc/browse-books.html', context, context_instance=RequestContext(request))



def convert_notebook(request, notebook_path=None):
    """ Checks for the modified time of ipython notebooks and corresponding html page and replaces html page with 
    new one if corresponding ipython notebook has been modified. """ 
    context = {}
    path = os.path.join(local.path, notebook_path.rsplit(".", 1)[0])
    template_html = path+".html"
    template_ipynb =path+".ipynb"
    template_dir = os.path.dirname(path)

    def nbconvert(template_ipynb):
        notebook_convert = "ipython nbconvert --to html {0} --FilesWriter.build_directory={1}".format(template_ipynb, template_dir)
        subprocess.call (notebook_convert, shell = True)


    if os.path.isfile(template_html):
        modified_time_for_html = os.stat(template_html).st_mtime
        modified_time_for_ipynb = os.stat(template_ipynb).st_mtime
        if not modified_time_for_html > modified_time_for_ipynb:
            nbconvert(template_ipynb)
            
    else:
        nbconvert(template_ipynb)
    
    return render_to_response(template_html, context)


def completed_books(request):
    context = {}
    context.update(csrf(request))
    category = "All"
    if request.user.is_anonymous():
        context['anonymous'] = True
    else:
        if is_reviewer(request.user):
            context['reviewer'] = request.user
        else:
            context['user'] = request.user
    if request.method == "POST":
        category = request.POST['category']
        if category == "all":
            completed_books = Book.objects.filter(approved=True)
        else:
            completed_books = Book.objects.filter(category=category, approved=True)
    else:
        completed_books = Book.objects.filter(approved=True)
    context['category'] = category
    context['completed_books'] = completed_books
    return render_to_response('tbc/completed_books.html', context)
    

def books_under_progress(request):
    context = {}
    context.update(csrf(request))
    if request.user.is_anonymous():
        context['anonymous'] = True
    else:
        if is_reviewer(request.user):
            context['reviewer'] = request.user
        else:
            context['user'] = request.user
    if request.method == "POST":
        category = request.POST['category']
        if category == "all":
            books_under_progress = Book.objects.filter(approved=False)
        else:
            books_under_progress = Book.objects.filter(category=category,
                                                       approved=False)
    else:
        books_under_progress = Book.objects.filter(approved=False)
    context['books_under_progress'] = books_under_progress
    return render_to_response('tbc/books_under_progress.html', context)


def get_certificate(request, book_id=None):
    if request.user.is_anonymous():
        return HttpResponseRedirect('/login/?require_login=True')
    else:
        user = request.user
    user_profile = Profile.objects.get(user=user)
    books = Book.objects.filter(contributor=user_profile, approved=True)
    context = {}
    context['user'] = user
    context['books'] = books
    error = False
    cur_path = os.path.dirname(os.path.realpath(__file__))
    certificate_path = '{0}/certificate/'.format(cur_path)
    if book_id:
        book = Book.objects.get(id=book_id)
        try:
            proposal_id = Proposal.objects.get(accepted=book_id).id
        except Proposal.DoesNotExist:
            proposal_id = None
        title = book.title
        edition = book.edition
        institute = user_profile.insti_org
        gender = user_profile.gender
        if gender == 'female':
            pronoun = 'She'
        else:
            pronoun = 'He'
        full_name = '%s %s' %(user.first_name, user.last_name)
        user_details = 'from %s' % (institute.replace('&', 'and'))
        book_details = '%s, %s edition' % (title.replace('&', 'and'), edition)
        try:
            template_file = open('{0}template_certificate'.format\
                    (certificate_path), 'r')
            content = string.Template(template_file.read())
            template_file.close()
            content_tex = content.safe_substitute(name=full_name,
                    pronoun=pronoun, details=user_details, book=book_details)
            create_tex = open('{0}tbc_certificate.tex'.format\
                    (certificate_path), 'w')
            create_tex.write(content_tex)
            create_tex.close()
            return_value, err = _make_tbc_certificate(certificate_path)
            if return_value == 0:
                file_name = 'tbc_certificate.pdf'
                pdf = open('{0}{1}'.format(certificate_path, file_name) , 'r')
                response = HttpResponse(content_type='application/pdf')
                response['Content-Disposition'] = 'attachment; \
                        filename=%s' % (file_name)
                response.write(pdf.read())
                _clean_tbc_certificate(certificate_path)
                add_log(user, book, CHANGE, 'Certificate Downloaded'
                        ,proposal_id)
                return response
            else:
                error = True
                add_log(user, book, CHANGE, err, proposal_id)
        except Exception as e:
            error = True
            add_log(user, book, CHANGE, e, proposal_id)
    
    if error:
        _clean_tbc_certificate(certificate_path)
        context['error'] = error
        return render_to_response('tbc/get-certificate.html', context)
    return render_to_response('tbc/get-certificate.html', context)

def _clean_tbc_certificate(path):
    clean_process = subprocess.Popen('make -C {0} clean'.format(path),
            shell=True)
    clean_process.wait()

def _make_tbc_certificate(path):
    process = subprocess.Popen('timeout 15 make -C {0} tbc'.format(path),
            stderr = subprocess.PIPE, shell = True)
    err = process.communicate()[1]
    return process.returncode, err

def redirect_to_ipynb(request, notebook_path=None):
    context = {}
    notebook = notebook_path.split("/")
    notebook[0] = "notebooks"
    notebook = "/".join(notebook)
    redirect_url = "https://ipynb.fossee.in/"+notebook
    return redirect(redirect_url)


# ajax views
@csrf_exempt
def ajax_matching_books(request):
    titles = request.POST["titles"]
    titles = json.loads(titles)
    matches = []
    i = 1
    flag = None
    for title in titles:
        if title:
            match = TempBook.objects.filter(title__icontains=title)
            if match:
                flag = True
                matches.append(match)
            else:
                matches.append(None)
    context = {
        'matches': matches,
        'flag': flag
    }
    return render_to_response('tbc/ajax-matching-books.html', context)


def get_broken_books(request):
    context = {}
    ci = RequestContext(request)
    if request.method == 'POST':
        _book_id = request.POST["books"]
        try:
            book = Book.objects.get(id=_book_id)
        except Book.DoesNotExist:
            pass
        else:
            chapters = Chapters.objects.filter(book_id=_book_id)
            screenshots = ScreenShots.objects.filter(book_id=_book_id)
            context['book'] = book
            context['chapters'] = chapters
            context['screenshots'] = screenshots
            return render_to_response('tbc/link_image.html', context,
                context_instance = ci)
    books = Book.objects.all()
    broken_books = []
    for book in  books:
        chapters = Chapters.objects.filter(book=book)
        screenshots = ScreenShots.objects.filter(book=book)
        try:
            if screenshots and chapters:
                for screenshot in screenshots:
                    screenshot.chapters_set.get()
        except Chapters.MultipleObjectsReturned:
            pass
        except Chapters.DoesNotExist:
            broken_books.append(book)
    context = {'books_to_link': broken_books}
    return render_to_response('tbc/brokenbooks.html', context, context_instance=ci)


def link_image(request):
    context = {}
    context['success'] = False
    ci = RequestContext(request)
    if request.method == 'POST':
        _book_id = request.POST["book"]
        screenshots = ScreenShots.objects.filter(book_id=_book_id)
        for screenshot in screenshots:
            chapter_id = request.POST["chapters{0}".format(screenshot.id)]
            chapter = Chapters.objects.get(id=chapter_id)
            chapter.screen_shots.add(screenshot)
            chapter.save()
        context['success'] = True
    return render_to_response('tbc/link_image.html', context, context_instance=ci)

@login_required(login_url="/login/")
def admin_tools(request):
    context = {}
    context.update(csrf(request))
    curr_user = request.user
    
    if not is_reviewer(curr_user):
        raise Http404("You are not allowed to view this page")
    else:
        context["reviewer"] = curr_user
        return render_to_response('tbc/admin-tools.html', context)