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