testappproj/testapp/views.py
changeset 3 34d0c21e3352
parent 2 654c583fd78e
child 4 4d5422e5a45d
equal deleted inserted replaced
2:654c583fd78e 3:34d0c21e3352
     4 import os
     4 import os
     5 import traceback
     5 import traceback
     6 import random
     6 import random
     7 import StringIO
     7 import StringIO
     8 import sys
     8 import sys
     9 
     9 import json
    10 # # AppEngine imports
    10 
    11 
    11 
    12 from django.contrib.auth.models import User 
    12 from django.contrib.auth.models import User 
    13 
    13 
    14 from testappproj.testapp.models import *
    14 from testappproj.testapp.models import *
    15 from django.http import HttpResponse
    15 from django.http import HttpResponse
    16 
    16 
    17 
    17 
    18 
       
    19 # Django imports 
       
    20 #from django.conf import settings
       
    21 #settings._target = None
       
    22 #os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
       
    23 #import django
       
    24 from django import http
    18 from django import http
    25 from django import shortcuts
    19 from django import shortcuts
    26 from django.template import Context ,RequestContext
    20 from django.template import Context ,RequestContext
    27 from django.template.loader import get_template
    21 from django.template.loader import get_template
    28 
    22 
    34 from django.contrib.auth.decorators import permission_required
    28 from django.contrib.auth.decorators import permission_required
    35 from models import Problem
    29 from models import Problem
    36 from django.contrib.auth.decorators import login_required 
    30 from django.contrib.auth.decorators import login_required 
    37 from models import Score 
    31 from models import Score 
    38 import time
    32 import time
    39 
    33 import sandbox
    40 
       
    41 # def handle_uploaded_file(f):
       
    42 #   print f  
       
    43 #   destination = open('some/file/name.txt', 'wb+')
       
    44 #   for chunk in f.chunks():
       
    45 #     destination.write(chunk)
       
    46 #   destination.close()
       
    47 
       
    48 
    34 
    49 
    35 
    50 def respond(request, user,template, params=None):
    36 def respond(request, user,template, params=None):
    51   """Helper to render a response, passing standard stuff to the response.
    37   """Helper to render a response, passing standard stuff to the response.
    52 
    38 
    73     params['sign_in'] = 1
    59     params['sign_in'] = 1
    74   # if not template.endswith('.html'):
    60   # if not template.endswith('.html'):
    75   template += '.html'
    61   template += '.html'
    76   return shortcuts.render_to_response(template, params)
    62   return shortcuts.render_to_response(template, params)
    77 
    63 
       
    64 
       
    65 
       
    66 def check_examination_done(f):
       
    67         def wrap(request, *args, **kwargs):
       
    68                 #this check the session if userid key exist, if not it will redirect to login page
       
    69                 user= Test_User.objects.get(user=request.user)
       
    70                 
       
    71                 if user.exam_done==True:
       
    72                         return HttpResponse("You have given the exam before")
       
    73                 return f(request, *args, **kwargs)
       
    74         return wrap
       
    75 
       
    76   
       
    77 
       
    78 
       
    79 
       
    80 
       
    81 
       
    82 
       
    83 
       
    84 
    78 def execute_plotting_test_cases(user_code , solution_image,problem_id , username):
    85 def execute_plotting_test_cases(user_code , solution_image,problem_id , username):
    79   
    86   
    80   print  user_code 
    87   print  user_code 
    81   print "solution"+solution_image
    88   print "solution"+solution_image
    82 
    89 
    90   # create file-like string to capture output
    97   # create file-like string to capture output
    91   codeOut = StringIO.StringIO()
    98   codeOut = StringIO.StringIO()
    92   codeErr = StringIO.StringIO()
    99   codeErr = StringIO.StringIO()
    93 
   100 
    94 
   101 
    95 
   102   
    96   # capture output and errors
   103   # capture output and errors
    97   sys.stdout = codeOut
   104   sys.stdout = codeOut
    98   sys.stderr = codeErr
   105   sys.stderr = codeErr
    99 
   106 
   100   exec code
   107   sandbox.execute(code)
   101 
   108 
   102 # restore stdout and stderr
   109 # restore stdout and stderr
   103   sys.stdout = sys.__stdout__
   110   sys.stdout = sys.__stdout__
   104   sys.stderr = sys.__stderr__
   111   sys.stderr = sys.__stderr__
   105 
   112 
   128   codeErr.close()
   135   codeErr.close()
   129 
   136 
   130   return solved,errors
   137   return solved,errors
   131 
   138 
   132 def execute_test_cases(code , solution):
   139 def execute_test_cases(code , solution):
   133   
   140 
   134   print code 
   141 
   135   print "solution"+solution
   142   
   136 
   143 
   137 
   144 
   138   solved=False
   145   solved=False
   139   # create file-like string to capture output
   146   # create file-like string to capture output
   140   codeOut = StringIO.StringIO()
   147   codeOut = StringIO.StringIO()
   141   codeErr = StringIO.StringIO()
   148   codeErr = StringIO.StringIO()
   142 
   149 
       
   150   
   143 
   151 
   144 
   152 
   145   # capture output and errors
   153   # capture output and errors
   146   sys.stdout = codeOut
   154   sys.stdout = codeOut
       
   155   
   147   sys.stderr = codeErr
   156   sys.stderr = codeErr
   148 
   157   print "aaaklamnsldnlndskn"
   149   exec code
   158   sandbox.execute(code)
   150 
   159 
   151 # restore stdout and stderr
   160 # restore stdout and stderr
   152   sys.stdout = sys.__stdout__
   161   sys.stdout = sys.__stdout__
   153   sys.stderr = sys.__stderr__
   162   sys.stderr = sys.__stderr__
   154 
   163 
   155 
   164 
   156 
   165   print "xs zc sdc"
   157   
   166   
   158   
   167   
   159   s = codeOut.getvalue()
   168   s = codeOut.getvalue()
   160   
   169   
   161   s=unicode(s)
   170   s=unicode(s)
   177   codeErr.close()
   186   codeErr.close()
   178 
   187 
   179   return solved,errors
   188   return solved,errors
   180 
   189 
   181 
   190 
       
   191 def complete(request):
       
   192   print request.user
       
   193   user= Test_User.objects.get(user=request.user)
       
   194   user.exam_done=True
       
   195   user.save()
       
   196 
       
   197   return respond(request, request.user ,'submit')
       
   198 
       
   199 
       
   200 
       
   201 
   182 
   202 
   183 def index(request):
   203 def index(request):
   184   """ need to change user in the django.contrib way"""
   204   """ need to change user in the django.contrib way"""
   185 
   205 
   186   user = request.user
   206   user = request.user
   187   
   207   
   188   return respond(request , user, 'index')
   208   return respond(request , user, 'index')
   189 
   209 
   190 # def contribution(request):
       
   191 # #  user = users.get_current_user()
       
   192 #   return respond(request, user, 'contribution')
       
   193   
       
   194 # def help(request):
       
   195 # #  user = users.get_current_user()
       
   196 #   return respond(request, user, 'help')
       
   197   
       
   198 # def about(request):
       
   199 # #  user = users.get_current_user()
       
   200 #   return respond(request, user, 'about')
       
   201 
       
   202 # def vision(request):
       
   203 # #  user = users.get_current_user()
       
   204 #   return respond(request, user, 'vision')
       
   205 
       
   206 # def statements(request):
       
   207 # #  user = users.get_current_user()
       
   208 #   return respond(request, user, 'statements')
       
   209 
       
   210 
       
   211 def get_pu(problem):
       
   212   '''
       
   213   returns:
       
   214    - "USER_NOT_SIGNED_IN": user not signed in. returning this to prevent saving anonymous user's potentially crappy solution and display it to every anonymous visitor
       
   215    - "PU_NOT_FOUND": for signed in users when no solution has been attempted.
       
   216    - ProblemUser: for signed in users when a solution has been attempted
       
   217   
       
   218   '''
       
   219 #  user = users.get_current_user()
       
   220 #  if not user:
       
   221 #    return "USER_NOT_SIGNED_IN"
       
   222   pu_query = models.ProblemUser.all().filter('problem = ', problem).filter('user =', users.get_current_user())
       
   223   pu_results = pu_query.fetch(1)
       
   224   if pu_results: 
       
   225     return pu_results[0]
       
   226   return "PU_NOT_FOUND"
       
   227    
   210    
   228 # def is_solved(problem):
   211 
   229 #   pu = get_pu(problem)
       
   230 #   if pu == "PU_NOT_FOUND" or pu == "USER_NOT_SIGNED_IN": return False
       
   231 #   return pu.solved
       
   232 @login_required(function=None, redirect_field_name='next')
   212 @login_required(function=None, redirect_field_name='next')
       
   213 @check_examination_done
   233 def problems(request, category=None):
   214 def problems(request, category=None):
   234   user = request.user
   215   user = request.user
   235   
   216 
   236   # if category is None:
       
   237   #   problems = db.GqlQuery('SELECT * FROM Problem ORDER BY created DESC')
       
   238   # else:
       
   239   #   problems = db.GqlQuery('SELECT * FROM Problem WHERE categories = :1 ORDER BY created DESC', category)
       
   240   
       
   241   
       
   242 
       
   243 
       
   244   # entries = []
       
   245   # for problem in problems:
       
   246   #   e = dict(problem=problem,
       
   247   #            username=problem.author.nickname().partition('@')[0],
       
   248   #            solved=is_solved(problem))
       
   249   #   entries.append(e)
       
   250   # problems = entries
       
   251   entries=[]
   217   entries=[]
   252   all_sessions=set([element.session  for element in Problem.objects.all()])
   218   all_sessions=set([element.session  for element in Problem.objects.all()])
   253   print all_sessions
   219   
   254 
   220 
   255   # for problem in problems:
   221   
   256   #    e = dict(problem=problem.description,
   222   
   257   #             username=user.username,
       
   258   #             problem_id=problem.id
       
   259              
       
   260   #             )
       
   261   #    entries.append(e)
       
   262   
       
   263 #  print entries
       
   264 
   223 
   265   
   224   
   266   #get problems to solve from each session.
   225   #get problems to solve from each session.
   267   for session in all_sessions: 
   226   for session in all_sessions: 
   268     get_problem=random.Random().choice(Problem.objects.filter(session=session))
   227     get_problem=random.Random().choice(Problem.objects.filter(session=session))
   286   
   245   
   287   if problem is None:
   246   if problem is None:
   288   
   247   
   289     return http.HttpResponseNotFound('No such problem.')
   248     return http.HttpResponseNotFound('No such problem.')
   290   
   249   
   291 #  pu = get_pu(problem)
       
   292 #  if pu == "PU_NOT_FOUND":  # user is attempting problem for the first time
       
   293 #    pu = models.ProblemUser(problem=problem, user=users.get_current_user(), solution='', solved=False)
       
   294 #    pu.put()
       
   295 #    pu = None
       
   296   print problem.id
   250   print problem.id
   297   return respond(request, request.user ,'code' ,{'problem' : problem } )
   251   return respond(request, request.user ,'code' ,{'problem' : problem } )
   298 
   252 
   299 def run(request):
   253 def run(request):
   300   user = request.user 
   254 
   301   print request.POST
   255    user = request.user 
   302 
   256    print user
   303   problem_id = request.POST.get('problem_id')
   257    problem_id = request.POST.get('problem_id')
   304   
   258   
   305   if problem_id:
   259    if problem_id:
   306     problem = Problem.objects.get(id=int(problem_id))
   260      problem = Problem.objects.get(id=int(problem_id))
   307 
   261 
   308     if problem is None:
   262      if problem is None:
   309       return http.HttpResponseNotFound('No such problem.')
   263        return http.HttpResponse('There is no problem like this are you sure you solved it')
   310   
   264 
   311   user_code = request.POST.get('user_code')
   265    user_code = request.POST.get('user_code')
   312 
   266 
   313   if not user_code:
   267 
   314     return http.HttpResponse('bad request')
   268    if  user_code == '':
   315   
   269      return http.HttpResponse('No solution')
   316   # pu = get_pu(problem)
   270   
   317   # # update ProblemUser object for this user
   271     
   318   # if (pu.__class__ == models.ProblemUser):
   272    user_code = user_code.replace('\r\n', '\n')
   319   #   pu.solution = user_code
   273    user_code += '\n\n'
   320   #   pu.put()
   274 
   321 
   275    errors = ''
   322   user_code = user_code.replace('\r\n', '\n')
   276   
   323   user_code += '\n\n'
   277   
   324 
   278    print "ksmdlnjdns"
   325   errors = ''
   279 
   326   
   280    solved,errors = execute_test_cases(user_code,problem.solution)
   327   
   281    
   328   # try:
   282    
   329   #   print user_code
   283    if solved==True:
   330   #   compiled = compile(user_code, 'error_file', 'exec')
   284     
   331   #   g = {}
   285      #user is answering his first question
   332   #   exec compiled in g
   286      try:
   333 
   287        print user.id
   334 #    s = problem.tests.replace('\r\n', '\n')
   288        score_for_user= Score.objects.get(user=user)
   335 #    s += '\n\n'
   289        score_for_user.total_credits+=problem.credit
   336     # test_cases = doctest.DocTestParser().get_examples(s) 
   290        score_for_user.save()
   337   solved,errors = execute_test_cases(user_code,problem.solution)
   291     
   338     # if solved:
   292     # user has answered questions previously
   339     #   pu = get_pu(problem)
   293      except Score.DoesNotExist:
   340     #   if pu.__class__ == models.ProblemUser:
   294 
   341     #     pu.solved = True
   295        score_new_user=user.id
   342     #     pu.put()
   296        score_total_credits=problem.credit
   343     # else:
   297        score=Score(user_id=user.id,total_credits=score_total_credits)
   344     #   pu = get_pu(problem)
   298        score.save()
   345     #   if pu.__class__ == models.ProblemUser:
   299   
   346     #     pu.solved = False
   300 
   347     #     pu.put()
   301 
   348   
   302    else:
   349   
   303      http.HttpResponse('Wrong Answer')
   350   
   304      
   351 
   305  
   352   if solved==True:
   306    return http.HttpResponse("Right Answer")
   353     
   307 
   354     #user is answering his first question
       
   355     try:
       
   356    # print user.id
       
   357       score_for_user= Score.objects.get(user=user)
       
   358       score_for_user.total_credits+=problem.credit
       
   359       score_for_user.save()
       
   360     
       
   361    # user has answered questions previously
       
   362     except Score.DoesNotExist:
       
   363 #      print user.id 
       
   364       score_new_user=user.id
       
   365       score_total_credits=problem.credit
       
   366       score=Score(user_id=user.id,total_credits=score_total_credits)
       
   367       score.save()
       
   368   
       
   369 
       
   370 
       
   371   else:
       
   372     print "oops"
       
   373   results=solved
       
   374       
       
   375   return respond(request, request.user, 'run', {'results': results})
       
   376   
   308   
   377 
   309 
   378 @permission_required('testapp.add_problem' , login_url="/code/1234")
   310 @permission_required('testapp.add_problem' , login_url="/code/1234")
   379 def new_edit(request, problem_id=None, internal=False):
   311 def new_edit(request, problem_id=None, internal=False):
   380   
   312   
   465     return ('success','success')
   397     return ('success','success')
   466   
   398   
   467 
   399 
   468   return http.HttpResponseRedirect('/problems')
   400   return http.HttpResponseRedirect('/problems')
   469 
   401 
   470 def upload(request): 
   402 
   471   """ upload handler, validates the form and calls handle_uploaded_file
   403   
   472       for processing further
       
   473   """
       
   474   user = request.user
       
   475   if user is None:
       
   476     return http.HttpResponseForbidden('You must be an signed in to create/edit a problem.')
       
   477 
       
   478   if request.method == 'POST':
       
   479     form = UploadForm(request.POST, request.FILES)
       
   480     if form.is_valid():
       
   481       submission_report = handle_uploaded_file(request)
       
   482       print "testing"
       
   483       print submission_report
       
   484 
       
   485       return respond(request, user, 'upload', {'report':submission_report})
       
   486     else:
       
   487       return http.HttpResponseForbidden('Oops something went wrong with the upload')
       
   488 
       
   489 def handle_uploaded_file(request):
       
   490   """ Handles uploaded data, pushes it to existing problem creating code
       
   491       TODO: 1. make efficient by putting actual database code Here
       
   492             2. Add more security and validation
       
   493   """
       
   494   submission_data = request.FILES['file'].read()
       
   495   if '#---' in submission_data:
       
   496     all_submissions = submission_data.split('#---')[1:-1]
       
   497     # ^^ ignoring the first null and last __main__ code
       
   498     all_submissions = [ pykataupload.Submission(x) for x in all_submissions ]
       
   499     report = []
       
   500 
       
   501     for key,each_submission in enumerate(all_submissions):
       
   502       # TODO: handle these later by TaskQueues to avoid timeouts on big uploads
       
   503       # a good way would be to have ajax based status coming back to this page
       
   504       # about each problem in the uploaded file, their status, progress etc.
       
   505       each_submission.parse()
       
   506       request.POST.clear()
       
   507       request.POST.update (each_submission.data_dict)
       
   508       upload_status, upload_response = new_edit(request, internal=True)
       
   509 
       
   510       report.append ({'status':upload_status, 'name':each_submission['name'], 
       
   511                           'upload_response':upload_response})
       
   512 
       
   513       # Yay this hack works :D
       
   514     return report
       
   515   else:
       
   516     return http.HttpResponseForbidden('The file you uploaded is not in appropriate format.')
       
   517 
       
   518 def shell(request):
       
   519   """ need to change user in the django.contrib way"""
       
   520 
       
   521   user = request.user
       
   522   statement=request.GET.get('statement','')
       
   523   if  statement is not '':
       
   524     
       
   525     # the python compiler doesn't like network line endings
       
   526     statement = statement.replace('\r\n', '\n')
       
   527 
       
   528     # add a couple newlines at the end of the statement. this makes
       
   529     # single-line expressions such as 'class Foo: pass' evaluate happily.
       
   530     statement += '\n\n'
       
   531     print "statement"+statement 
       
   532     # log and compile the statement up front
       
   533     try:
       
   534       logging.info('Compiling and evaluating:\n%s' % statement)
       
   535       compiled = compile(statement, '<string>', 'single')
       
   536     except:
       
   537        return HttpResponse(traceback.format_exc(),mimetype="text/plain")  
       
   538 #      pass
       
   539     return HttpResponse("",mimetype="text/plain")
       
   540   else:
       
   541     return respond(request, user, 'shell')
       
   542 
       
   543