testappproj/testapp/views.py
changeset 0 0b061d58aea3
child 1 0eda880b3d25
equal deleted inserted replaced
-1:000000000000 0:0b061d58aea3
       
     1 # Python imports
       
     2 import doctest
       
     3 import logging
       
     4 import os
       
     5 import traceback
       
     6 import random
       
     7 
       
     8 
       
     9 # # AppEngine imports
       
    10 
       
    11 from django.contrib.auth.models import User 
       
    12 
       
    13 from testappproj.testapp.models import *
       
    14 from django.http import HttpResponse
       
    15 
       
    16 # from google.appengine.api import users
       
    17 # from google.appengine.ext.webapp import template 
       
    18 
       
    19 # from google.appengine.ext import db
       
    20 # from google.appengine.ext.db import djangoforms
       
    21 
       
    22 
       
    23 # Django imports 
       
    24 #from django.conf import settings
       
    25 #settings._target = None
       
    26 #os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
       
    27 #import django
       
    28 from django import http
       
    29 from django import shortcuts
       
    30 from django.template import Context ,RequestContext
       
    31 from django.template.loader import get_template
       
    32 
       
    33 # Local imports
       
    34 from forms import *
       
    35 import models
       
    36 from helpers import bulkuploader as pykataupload
       
    37 from datetime import date
       
    38 from django.contrib.auth.decorators import permission_required
       
    39 from models import Problem
       
    40 
       
    41 
       
    42 def respond(request, user,template, params=None):
       
    43   """Helper to render a response, passing standard stuff to the response.
       
    44 
       
    45   Args:
       
    46     request: The request object.
       
    47     user: The User object representing the current user; or None if nobody
       
    48       is logged in.
       
    49     template: The template name; '.html' is appended automatically.
       
    50     params: A dict giving the template parameters; modified in-place.
       
    51 
       
    52   Returns:
       
    53     Whatever render_to_response(template, params) returns.
       
    54 
       
    55   Raises:
       
    56     Whatever render_to_response(template, params) raises.
       
    57   """
       
    58   if params is None:
       
    59      params = {}
       
    60   if user:
       
    61     params['user'] = user
       
    62     params['sign_out'] = 1
       
    63   #   params['is_admin'] = (users.is_current_user_admin())
       
    64   else:
       
    65     params['sign_in'] = 1
       
    66   # if not template.endswith('.html'):
       
    67   template += '.html'
       
    68   return shortcuts.render_to_response(template, params)
       
    69 
       
    70 def execute_test_cases(request, test_cases, g):
       
    71   li = []
       
    72   
       
    73   solved = True
       
    74   for e in test_cases:
       
    75     if not e.want:
       
    76       exec e.source in g
       
    77       continue
       
    78     call = e.source.strip()
       
    79     got = eval(e.source.strip(), g)
       
    80     expected = eval(e.want, g)
       
    81     
       
    82     if got == expected:
       
    83       status = 'pass'
       
    84     else:
       
    85       status = 'fail'
       
    86       solved = False
       
    87     li.append([call, expected, "%r" % got, status])
       
    88 
       
    89   return li, solved
       
    90 
       
    91 
       
    92 
       
    93 
       
    94 def index(request):
       
    95   """ need to change user in the django.contrib way"""
       
    96 
       
    97   user = request.user
       
    98   
       
    99   return respond(request , user, 'index')
       
   100 
       
   101 # def contribution(request):
       
   102 # #  user = users.get_current_user()
       
   103 #   return respond(request, user, 'contribution')
       
   104   
       
   105 # def help(request):
       
   106 # #  user = users.get_current_user()
       
   107 #   return respond(request, user, 'help')
       
   108   
       
   109 # def about(request):
       
   110 # #  user = users.get_current_user()
       
   111 #   return respond(request, user, 'about')
       
   112 
       
   113 # def vision(request):
       
   114 # #  user = users.get_current_user()
       
   115 #   return respond(request, user, 'vision')
       
   116 
       
   117 # def statements(request):
       
   118 # #  user = users.get_current_user()
       
   119 #   return respond(request, user, 'statements')
       
   120 
       
   121 
       
   122 def get_pu(problem):
       
   123   '''
       
   124   returns:
       
   125    - "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
       
   126    - "PU_NOT_FOUND": for signed in users when no solution has been attempted.
       
   127    - ProblemUser: for signed in users when a solution has been attempted
       
   128   
       
   129   '''
       
   130 #  user = users.get_current_user()
       
   131 #  if not user:
       
   132 #    return "USER_NOT_SIGNED_IN"
       
   133   pu_query = models.ProblemUser.all().filter('problem = ', problem).filter('user =', users.get_current_user())
       
   134   pu_results = pu_query.fetch(1)
       
   135   if pu_results: 
       
   136     return pu_results[0]
       
   137   return "PU_NOT_FOUND"
       
   138    
       
   139 # def is_solved(problem):
       
   140 #   pu = get_pu(problem)
       
   141 #   if pu == "PU_NOT_FOUND" or pu == "USER_NOT_SIGNED_IN": return False
       
   142 #   return pu.solved
       
   143 
       
   144 def problems(request, category=None):
       
   145   user = request.user
       
   146   
       
   147   # if category is None:
       
   148   #   problems = db.GqlQuery('SELECT * FROM Problem ORDER BY created DESC')
       
   149   # else:
       
   150   #   problems = db.GqlQuery('SELECT * FROM Problem WHERE categories = :1 ORDER BY created DESC', category)
       
   151   
       
   152   
       
   153 
       
   154 
       
   155   # entries = []
       
   156   # for problem in problems:
       
   157   #   e = dict(problem=problem,
       
   158   #            username=problem.author.nickname().partition('@')[0],
       
   159   #            solved=is_solved(problem))
       
   160   #   entries.append(e)
       
   161   # problems = entries
       
   162   entries=[]
       
   163   all_sessions=set([element.session  for element in Problem.objects.all()])
       
   164   print all_sessions
       
   165 
       
   166   # for problem in problems:
       
   167   #    e = dict(problem=problem.description,
       
   168   #             username=user.username,
       
   169   #             problem_id=problem.id
       
   170              
       
   171   #             )
       
   172   #    entries.append(e)
       
   173   
       
   174 #  print entries
       
   175 
       
   176   
       
   177   #get problems to solve from each session.
       
   178   for session in all_sessions: 
       
   179     get_problem=random.Random().choice(Problem.objects.filter(session=session))
       
   180     e = dict(problem=get_problem.description,
       
   181              username=user.username,
       
   182              problem_id=get_problem.id,
       
   183              session =get_problem.session
       
   184                )
       
   185     entries.append(e)
       
   186 
       
   187 
       
   188   return respond(request, user, 'problems',{'entries' : entries }  )
       
   189 
       
   190 def code(request, problem_id):
       
   191   
       
   192   print problem_id
       
   193   problem = Problem.objects.get(id=int(problem_id))
       
   194 
       
   195   if problem is None:
       
   196     return http.HttpResponseNotFound('No such problem.')
       
   197   
       
   198 #  pu = get_pu(problem)
       
   199 #  if pu == "PU_NOT_FOUND":  # user is attempting problem for the first time
       
   200 #    pu = models.ProblemUser(problem=problem, user=users.get_current_user(), solution='', solved=False)
       
   201 #    pu.put()
       
   202 #    pu = None
       
   203 
       
   204   return respond(request, request.user ,'code' , )
       
   205 
       
   206 def run(request):
       
   207   user = request.user 
       
   208   problem_id = request.POST.get('problem_id')
       
   209   if problem_id:
       
   210     problem = Problem.objects.get(id=int(problem_id))
       
   211 
       
   212     if problem is None:
       
   213       return http.HttpResponseNotFound('No such problem.')
       
   214   
       
   215   user_code = request.POST.get('user_code')
       
   216 
       
   217   if not user_code:
       
   218     return http.HttpResponse('bad request')
       
   219   
       
   220   # pu = get_pu(problem)
       
   221   # # update ProblemUser object for this user
       
   222   # if (pu.__class__ == models.ProblemUser):
       
   223   #   pu.solution = user_code
       
   224   #   pu.put()
       
   225 
       
   226   user_code = user_code.replace('\r\n', '\n')
       
   227   user_code += '\n\n'
       
   228 
       
   229   errors = ''
       
   230   
       
   231   
       
   232   try:
       
   233     print user_code
       
   234     compiled = compile(user_code, 'error_file', 'exec')
       
   235     g = {}
       
   236     exec compiled in g
       
   237 
       
   238 #    s = problem.tests.replace('\r\n', '\n')
       
   239 #    s += '\n\n'
       
   240     # test_cases = doctest.DocTestParser().get_examples(s) 
       
   241     # results, solved = execute_test_cases(request, test_cases, g)
       
   242     # if solved:
       
   243     #   pu = get_pu(problem)
       
   244     #   if pu.__class__ == models.ProblemUser:
       
   245     #     pu.solved = True
       
   246     #     pu.put()
       
   247     # else:
       
   248     #   pu = get_pu(problem)
       
   249     #   if pu.__class__ == models.ProblemUser:
       
   250     #     pu.solved = False
       
   251     #     pu.put()
       
   252   except:
       
   253     errors = traceback.format_exc()
       
   254     return respond(request, user, 'traceback', {'errors': errors})
       
   255   results="solved"
       
   256   return respond(request, request.user, 'run', {'results': results})
       
   257   
       
   258 
       
   259 @permission_required('testapp.add_problem' , login_url="/code/1234")
       
   260 def new_edit(request, problem_id=None, internal=False):
       
   261   
       
   262 
       
   263 
       
   264   # internal indicates that it is being called internally by uploader
       
   265   #
       
   266   user = request.user
       
   267 #  print user.get_all_permissions()
       
   268   print user.username
       
   269   if user.is_anonymous() :
       
   270     return http.HttpResponseForbidden('You must be an signed in to create edit a problem.')
       
   271 
       
   272   if problem_id is None:
       
   273     creating_new = True
       
   274   else:
       
   275     creating_new = False
       
   276     
       
   277 #  problem = None
       
   278   # if problem_id:
       
   279   #   problem = models.Problem.get(db.Key.from_path(models.Problem.kind(), int(problem_id)))
       
   280   #   if problem.author != user and not users.is_current_user_admin():
       
   281   #     return http.HttpResponseForbidden('You can only edit your own problems.')
       
   282   #   if problem is None:
       
   283   #     return http.HttpResponseNotFound('No such problem.')  
       
   284  
       
   285 #   formset = ProblemForm(data=request.POST)  
       
   286 #   instance=formset.save()
       
   287 # #  upload_form = UploadForm(data=request.POST)
       
   288 
       
   289   if request.method == 'POST':
       
   290     form = ProblemForm(request.POST)
       
   291   else:
       
   292     form = ProblemForm()
       
   293 
       
   294   
       
   295 
       
   296   if not request.POST:
       
   297     return respond(request, user, 'new_edit_problem', {'form':form, 'problem':None, 'creating':creating_new })
       
   298   
       
   299 #  print form
       
   300   #errors = form.errors
       
   301   #print str(errors)+"errors"
       
   302 
       
   303   
       
   304   #if not errors:
       
   305   #  try:
       
   306   
       
   307   if form.is_valid():
       
   308     
       
   309     description = form.cleaned_data['Description']
       
   310     problem_type=form.cleaned_data['Problem_type']
       
   311     solution=form.cleaned_data['Solution']
       
   312     session=form.cleaned_data['Session']
       
   313     
       
   314     author = user.username
       
   315     created = date.today()
       
   316     modified=date.today()
       
   317 
       
   318     problem=Problem(description=description,problem_type=problem_type,solution=solution,session=session,author=author,created=created,modified=modified)
       
   319     
       
   320     problem.save() 
       
   321     print "saved"
       
   322   else:
       
   323     print "form is valid"
       
   324     print form.errors
       
   325 
       
   326 #  print form.errors
       
   327   #  except ValueError, err:
       
   328   #    errors['__all__'] = unicode(err)
       
   329       
       
   330 
       
   331   # if errors:
       
   332   #   print "new world"
       
   333   #   if internal:
       
   334       
       
   335   #     print errors
       
   336   #     return ('error',errors)
       
   337   #   return respond(request, user, 'new_edit_problem', 
       
   338   #                        {'form': form, 'problem':problem, 'creating':creating_new,'error':errors})
       
   339 
       
   340   # if creating_new:
       
   341   #   # if internal:
       
   342   #   #   if len(request.POST['user_id'])>0:
       
   343   #   #     logging.info(request.POST)
       
   344   #   #     problem.author = users.User(request.POST['user_id'])
       
   345   #   #   else:
       
   346   #   #     problem.author = user
       
   347   #   # else:
       
   348     
       
   349 
       
   350 
       
   351     
       
   352   
       
   353    
       
   354 #  l = []
       
   355   # for x in problem.categories:
       
   356   #   l.extend(x.split())
       
   357   # problem.categories = l
       
   358   # problem.put()
       
   359 
       
   360   if internal:
       
   361     return ('success','success')
       
   362   
       
   363 
       
   364   return http.HttpResponseRedirect('/problems')
       
   365 
       
   366 def upload(request): 
       
   367   """ upload handler, validates the form and calls handle_uploaded_file
       
   368       for processing further
       
   369   """
       
   370   user = request.user
       
   371   if user is None:
       
   372     return http.HttpResponseForbidden('You must be an signed in to create/edit a problem.')
       
   373 
       
   374   if request.method == 'POST':
       
   375     form = UploadForm(request.POST, request.FILES)
       
   376     if form.is_valid():
       
   377       submission_report = handle_uploaded_file(request)
       
   378       print "testing"
       
   379       print submission_report
       
   380 
       
   381       return respond(request, user, 'upload', {'report':submission_report})
       
   382     else:
       
   383       return http.HttpResponseForbidden('Oops something went wrong with the upload')
       
   384 
       
   385 def handle_uploaded_file(request):
       
   386   """ Handles uploaded data, pushes it to existing problem creating code
       
   387       TODO: 1. make efficient by putting actual database code Here
       
   388             2. Add more security and validation
       
   389   """
       
   390   submission_data = request.FILES['file'].read()
       
   391   if '#---' in submission_data:
       
   392     all_submissions = submission_data.split('#---')[1:-1]
       
   393     # ^^ ignoring the first null and last __main__ code
       
   394     all_submissions = [ pykataupload.Submission(x) for x in all_submissions ]
       
   395     report = []
       
   396 
       
   397     for key,each_submission in enumerate(all_submissions):
       
   398       # TODO: handle these later by TaskQueues to avoid timeouts on big uploads
       
   399       # a good way would be to have ajax based status coming back to this page
       
   400       # about each problem in the uploaded file, their status, progress etc.
       
   401       each_submission.parse()
       
   402       request.POST.clear()
       
   403       request.POST.update (each_submission.data_dict)
       
   404       upload_status, upload_response = new_edit(request, internal=True)
       
   405 
       
   406       report.append ({'status':upload_status, 'name':each_submission['name'], 
       
   407                           'upload_response':upload_response})
       
   408 
       
   409       # Yay this hack works :D
       
   410     return report
       
   411   else:
       
   412     return http.HttpResponseForbidden('The file you uploaded is not in appropriate format.')
       
   413 
       
   414 def shell(request):
       
   415   """ need to change user in the django.contrib way"""
       
   416 
       
   417   user = request.user
       
   418   statement=request.GET.get('statement','')
       
   419   if  statement is not '':
       
   420     
       
   421     # the python compiler doesn't like network line endings
       
   422     statement = statement.replace('\r\n', '\n')
       
   423 
       
   424     # add a couple newlines at the end of the statement. this makes
       
   425     # single-line expressions such as 'class Foo: pass' evaluate happily.
       
   426     statement += '\n\n'
       
   427     print "statement"+statement 
       
   428     # log and compile the statement up front
       
   429     try:
       
   430       logging.info('Compiling and evaluating:\n%s' % statement)
       
   431       compiled = compile(statement, '<string>', 'single')
       
   432     except:
       
   433        return HttpResponse(traceback.format_exc(),mimetype="text/plain")  
       
   434 #      pass
       
   435     return HttpResponse("",mimetype="text/plain")
       
   436   else:
       
   437     return respond(request, user, 'shell')
       
   438 
       
   439