testappproj/testapp/views.py
author amit@thunder
Mon, 12 Jul 2010 15:16:52 +0530
changeset 6 d0f107095b1a
parent 5 548c6261fa00
permissions -rwxr-xr-x
changes to image comparison methods

# Python imports
import doctest
import logging
import os
import traceback
import random
import StringIO
import sys
import json
import time
import sandbox
import re
from matplotlib.pyplot import imread
from numpy import alltrue


from django.contrib.auth.models import User 

from testappproj.testapp.models import *
from django.http import HttpResponse


from django import http
from django import shortcuts
from django.template import Context ,RequestContext
from django.template.loader import get_template

# Local imports
from forms import *
import models
from helpers import bulkuploader as pykataupload
from datetime import date
from django.contrib.auth.decorators import permission_required
from models import Problem
from django.contrib.auth.decorators import login_required 
from models import Score 
from django.utils.datastructures import MultiValueDictKeyError
from subprocess import PIPE,Popen,STDOUT


class RGBvalues(object):
    def __init__(self):
        self.red=None
        self.green=None
        self.blue=None
        self.alpha=None
        self.all=None
        self.rgb_dict=None
    def get_values(self,output):
         print output
         k=re.search(r"red:.*",output,re.DOTALL)
         all_values_string=output[k.start():k.end()]
         self.rgb_list=re.findall('(?<=: )\d+',all_values_string) 
         self.red=self.rgb_list[0]
         self.green=self.rgb_list[1]
         self.blue=self.rgb_list[2]
         self.alpha=self.rgb_list[3]
         self.all=self.rgb_list[4]
         return self.rgb_list




def respond(request, user,template, params=None):
  """Helper to render a response, passing standard stuff to the response.

  Args:
    request: The request object.
    user: The User object representing the current user; or None if nobody
      is logged in.
    template: The template name; '.html' is appended automatically.
    params: A dict giving the template parameters; modified in-place.

  Returns:
    Whatever render_to_response(template, params) returns.

  Raises:
    Whatever render_to_response(template, params) raises.
  """
  if params is None:
     params = {}
  if user:
    params['user'] = user
    params['sign_out'] = 1
  #   params['is_admin'] = (users.is_current_user_admin())
  else:
    params['sign_in'] = 1
  # if not template.endswith('.html'):
  template += '.html'
  return shortcuts.render_to_response(template, params)

def import_check(user_code):

  no_imports=len(re.findall('import',user_code))
  
  if (no_imports >= 1):
    return True
  return False
  


def plot_change_code(user_code):
  user_code=re.sub("show\(\)",'',user_code)

  return user_code




def check_examination_done(f):
        def wrap(request, *args, **kwargs):
                #this check the session if userid key exist, if not it will redirect to login page
              
                if unicode(request.user)==unicode('amit'):
                  print "hello what the hell"
                  return f(request, *args, **kwargs)
                user= Test_User.objects.get(user=request.user)
                if user.exam_done==True:
                        return HttpResponse("You have given the exam before")
                return f(request, *args, **kwargs)
        return wrap

  








def execute_plotting_test_cases(user_code , solution_image,problem_id , username):
   

  solved=False

  if import_check(user_code):
    print "entered"
    return solved,None,True

 
  user_image_name = str(username)+'_'+str(problem_id)+'_'+str(int(time.time()))+'.png'
   
  
  user_code=plot_change_code(user_code)



  code="""from pylab import *
import pylab
%s
figure_conf=pylab.gcf()
figure_conf.set_size_inches(10,7.5)
figure_conf.set_dpi(80)
figure_conf.savefig('%s',dpi=80)"""%(user_code,user_image_name)

  
  print code
  # create file-like string to capture output
  codeOut = StringIO.StringIO()
  codeErr = StringIO.StringIO()

  print str(codeOut)
  
  # capture output and errors
  sys.stdout = codeOut
  sys.stderr = codeErr

 
  sandbox.execute(code)

 
 
# restore stdout and stderr
  sys.stdout = sys.__stdout__
  sys.stderr = sys.__stderr__


  solution_image_name='media-root/'+str((solution_image))
#   solution_image_matrix=imread(new_solution_image)
# #  print str(solution_image_matrix)
# #  print user_image_name
#   user_image_matrix=imread(user_image_name)

  errors=codeErr.getvalue()  

  codeOut.close()
  codeErr.close()
  
  cmd = 'compare -verbose -metric MAE %s %s null: 2>&1'%(solution_image_name,user_image_name)
  print cmd
  p = Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT)
  
  output = p.stdout.read()
  print output
  k=RGBvalues()
  print k.get_values(output)
  print k.all

  if k.all<=250:
    solved=True
  # if solution_image_matrix==user_image_matrix:
  #   solved=True

 


  print solved
  return solved,errors,False

def execute_test_cases(code , solution):

  solved=False
 
 
  if import_check(code):
    print "entered"
    return solved,None,True
  # create file-like string to capture output



  codeOut = StringIO.StringIO()
  codeErr = StringIO.StringIO()

  


  # capture output and errors
  sys.stdout = codeOut
  
  sys.stderr = codeErr
 
  try:
    sandbox.execute(code)
  except :
    print "ok now we are at something"
# restore stdout and stderr
  sys.stdout = sys.__stdout__
  sys.stderr = sys.__stderr__



  
  
  s = codeOut.getvalue()
  
  s=unicode(s)
  

  print s.strip()
  print solution.strip()
  
 
     
  if solution.strip() == s.strip():
    solved =True

  errors=codeErr.getvalue()
  


  
  

  codeOut.close()
  codeErr.close()
  
  return solved,errors,False


def complete(request):
  print request.user
  user= Test_User.objects.get(user=request.user)
  user.exam_done=True
  user.save()

  return respond(request, request.user ,'submit')





def index(request):
  """ need to change user in the django.contrib way"""

  user = request.user
  
  return respond(request , user, 'index')

   

@login_required(function=None, redirect_field_name='next')
@check_examination_done
def problems(request, category=None):
  user = request.user

  entries=[]
  all_sessions=set([element.session  for element in Problem.objects.all()])
  

  
  

  
  #get problems to solve from each session.
  for session in all_sessions: 
    get_problem=random.Random().choice(Problem.objects.filter(session=session))
    e = dict(problem=get_problem.description,
             username=user.username,
             problem_id=get_problem.id,
             session =get_problem.session
               )
    entries.append(e)
    

  return respond(request, user, 'problems',{'entries' : entries }  )



@login_required(function=None, redirect_field_name='next')
def code(request, problem_id):
  
#  print problem_id
  problem = Problem.objects.get(id=int(problem_id))
  
  if problem is None:
  
    return http.HttpResponseNotFound('No such problem.')
  
  print problem.id
  return respond(request, request.user ,'code' ,{'problem' : problem } )

def run(request):

   user = request.user 

   problem_id = request.POST.get('problem_id')
  
   if problem_id:
     problem = Problem.objects.get(id=int(problem_id))

     if problem is None:
       return http.HttpResponse('There is no problem like this are you sure you solved it')

   user_code = request.POST.get('user_code')


   if  user_code == '':
     return http.HttpResponse('No solution')
  
    
   user_code = user_code.replace('\r\n', '\n')
   user_code += '\n\n'

   errors = ''
  
   print problem.problem_type


   if unicode(problem.problem_type)==unicode('S'):
     solved,errors,import_test= execute_test_cases(user_code,problem.solution)
   else :
     solved,errors,import_test= execute_plotting_test_cases(user_code,problem.solution_image,problem_id,user)
   


   print solved

   if import_test==True:
     
     return http.HttpResponse("DO NOT try to import or your exam and account will invalidated")


   if solved==True:
    
     #user is answering his first question
     try:
       print user.id
       score_for_user= Score.objects.get(user=user)
       score_for_user.total_credits+=problem.credit
       score_for_user.save()
    
    # user has answered questions previously
     except Score.DoesNotExist:

       score_new_user=user.id
       score_total_credits=problem.credit
       score=Score(user_id=user.id,total_credits=score_total_credits)
       score.save()
  


   else:
     return http.HttpResponse('Wrong Answer')
     
 
   return http.HttpResponse("Right Answer")

  

@permission_required('testapp.add_problem' , login_url="/code/1234")
def new_edit(request, problem_id=None, internal=False):
  


  # internal indicates that it is being called internally by uploader
  
  user = request.user
  if user.is_anonymous() :
    return http.HttpResponseForbidden('You must be an signed in to create edit a problem.')

  if problem_id is None:
    creating_new = True
  else:
    creating_new = False
    
  if request.method == 'POST':
    form = ProblemForm(request.POST, request.FILES)
  else:
    form = ProblemForm()

  

  if not request.POST:
    return respond(request, user, 'new_edit_problem', {'form':form, 'problem':None, 'creating':creating_new })
  

  
  
  if form.is_valid():
    try:
      description = form.cleaned_data['Description']
      problem_type=form.cleaned_data['Problem_type']
      solution=form.cleaned_data['Solution']
      session=form.cleaned_data['Session']
      credit=form.cleaned_data['Credit']
   # solution_image=form.cleaned_data['Solution_Image']
      solution_image=request.FILES['Solution_Image']

      author = user.username
      created = date.today()
      modified=date.today()
    
    # print request.FILES 
    # print "this is solution"+solution
    # print "this is solution_image"+solution_image
  

      problem=Problem(description=description,problem_type=problem_type,solution_image=solution_image,session=session,author=author,created=created,modified=modified,credit=credit)
    
    except MultiValueDictKeyError:
      description = form.cleaned_data['Description']
      problem_type=form.cleaned_data['Problem_type']
      solution=form.cleaned_data['Solution']
      session=form.cleaned_data['Session']
      credit=form.cleaned_data['Credit']
   # solution_image=form.cleaned_data['Solution_Image']
    

      author = user.username
      created = date.today()
      modified=date.today()
    
      problem=Problem(description=description,problem_type=problem_type,solution=solution,session=session,author=author,created=created,modified=modified,credit=credit)  


    problem.save() 
    print "saved"
  else:
    print "form is valid"
    print form.errors

#  print form.errors
  #  except ValueError, err:
  #    errors['__all__'] = unicode(err)
      

  if form.errors:
    print "new world"
    return respond(request, user, 'new_edit_problem', 
                         {'form': form, 'problem':problem, 'creating':creating_new,'error':errors})

  # if creating_new:
  #   # if internal:
  #   #   if len(request.POST['user_id'])>0:
  #   #     logging.info(request.POST)
  #   #     problem.author = users.User(request.POST['user_id'])
  #   #   else:
  #   #     problem.author = user
  #   # else:
    


    
  
   
#  l = []
  # for x in problem.categories:
  #   l.extend(x.split())
  # problem.categories = l
  # problem.put()

  if internal:
    return ('success','success')
  

  return http.HttpResponseRedirect('/problems')