testappproj/testapp/views (copy).py
changeset 0 0b061d58aea3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/testappproj/testapp/views (copy).py	Mon May 17 22:33:59 2010 +0530
@@ -0,0 +1,386 @@
+# Python imports
+import doctest
+import logging
+import os
+import traceback
+
+# # AppEngine imports
+
+from django.contrib.auth.models import User 
+
+from testappproj.testapp.models import *
+from django.http import HttpResponse
+
+# from google.appengine.api import users
+# from google.appengine.ext.webapp import template 
+
+# from google.appengine.ext import db
+# from google.appengine.ext.db import djangoforms
+
+
+# Django imports 
+#from django.conf import settings
+#settings._target = None
+#os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
+#import django
+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
+
+
+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 execute_test_cases(request, test_cases, g):
+  li = []
+  
+  solved = True
+  for e in test_cases:
+    if not e.want:
+      exec e.source in g
+      continue
+    call = e.source.strip()
+    got = eval(e.source.strip(), g)
+    expected = eval(e.want, g)
+    
+    if got == expected:
+      status = 'pass'
+    else:
+      status = 'fail'
+      solved = False
+    li.append([call, expected, "%r" % got, status])
+
+  return li, solved
+
+
+
+
+def index(request):
+  """ need to change user in the django.contrib way"""
+
+  user = request.user
+  
+  return respond(request , user, 'index')
+
+# def contribution(request):
+# #  user = users.get_current_user()
+#   return respond(request, user, 'contribution')
+  
+# def help(request):
+# #  user = users.get_current_user()
+#   return respond(request, user, 'help')
+  
+# def about(request):
+# #  user = users.get_current_user()
+#   return respond(request, user, 'about')
+
+# def vision(request):
+# #  user = users.get_current_user()
+#   return respond(request, user, 'vision')
+
+# def statements(request):
+# #  user = users.get_current_user()
+#   return respond(request, user, 'statements')
+
+
+def get_pu(problem):
+  '''
+  returns:
+   - "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
+   - "PU_NOT_FOUND": for signed in users when no solution has been attempted.
+   - ProblemUser: for signed in users when a solution has been attempted
+  
+  '''
+#  user = users.get_current_user()
+#  if not user:
+#    return "USER_NOT_SIGNED_IN"
+  pu_query = models.ProblemUser.all().filter('problem = ', problem).filter('user =', users.get_current_user())
+  pu_results = pu_query.fetch(1)
+  if pu_results: 
+    return pu_results[0]
+  return "PU_NOT_FOUND"
+   
+def is_solved(problem):
+  pu = get_pu(problem)
+  if pu == "PU_NOT_FOUND" or pu == "USER_NOT_SIGNED_IN": return False
+  return pu.solved
+
+def problems(request, category=None):
+  user = request.user
+  
+  # if category is None:
+  #   problems = db.GqlQuery('SELECT * FROM Problem ORDER BY created DESC')
+  # else:
+  #   problems = db.GqlQuery('SELECT * FROM Problem WHERE categories = :1 ORDER BY created DESC', category)
+  
+  
+
+
+  # entries = []
+  # for problem in problems:
+  #   e = dict(problem=problem,
+  #            username=problem.author.nickname().partition('@')[0],
+  #            solved=is_solved(problem))
+  #   entries.append(e)
+  # problems = entries
+  entries=[]
+  problems=Problem.objects.all()
+  for problem in problems:
+     e = dict(problem=problem.name,
+              username=user.username,
+              problem_id=problem.id
+              )
+     entries.append(e)
+  
+#  print entries
+
+
+
+  return respond(request, user, 'problems',{'entries' : entries }  )
+
+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.')
+  
+#  pu = get_pu(problem)
+#  if pu == "PU_NOT_FOUND":  # user is attempting problem for the first time
+#    pu = models.ProblemUser(problem=problem, user=users.get_current_user(), solution='', solved=False)
+#    pu.put()
+#    pu = None
+
+  return respond(request, request.user ,'code' , )
+
+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.HttpResponseNotFound('No such problem.')
+  
+  user_code = request.POST.get('user_code')
+
+  if not user_code:
+    return http.HttpResponse('bad request')
+  
+  # pu = get_pu(problem)
+  # # update ProblemUser object for this user
+  # if (pu.__class__ == models.ProblemUser):
+  #   pu.solution = user_code
+  #   pu.put()
+
+  user_code = user_code.replace('\r\n', '\n')
+  user_code += '\n\n'
+
+  errors = ''
+  
+  
+  try:
+    print user_code
+    compiled = compile(user_code, 'error_file', 'exec')
+    g = {}
+    exec compiled in g
+
+#    s = problem.tests.replace('\r\n', '\n')
+#    s += '\n\n'
+    # test_cases = doctest.DocTestParser().get_examples(s) 
+    # results, solved = execute_test_cases(request, test_cases, g)
+    # if solved:
+    #   pu = get_pu(problem)
+    #   if pu.__class__ == models.ProblemUser:
+    #     pu.solved = True
+    #     pu.put()
+    # else:
+    #   pu = get_pu(problem)
+    #   if pu.__class__ == models.ProblemUser:
+    #     pu.solved = False
+    #     pu.put()
+  except:
+    errors = traceback.format_exc()
+    return respond(request, user, 'traceback', {'errors': errors})
+  results="solved"
+  return respond(request, request.user, 'run', {'results': results})
+  
+def new_edit(request, problem_id=None, internal=False):
+  # internal indicates that it is being called internally by uploader
+  #
+  user = request.user
+  print user.username
+  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
+    
+  problem = None
+  # if problem_id:
+  #   problem = models.Problem.get(db.Key.from_path(models.Problem.kind(), int(problem_id)))
+  #   if problem.author != user and not users.is_current_user_admin():
+  #     return http.HttpResponseForbidden('You can only edit your own problems.')
+  #   if problem is None:
+  #     return http.HttpResponseNotFound('No such problem.')  
+ 
+  form = ProblemForm(data=request.POST or None, instance=problem)
+  upload_form = UploadForm(data=request.POST)
+
+  if not request.POST:
+    return respond(request, user, 'new_edit_problem', {'form':form, 'problem':problem, 'creating':creating_new , 'upload_form' : upload_form })
+  
+  
+  errors = form.errors
+  if not errors:
+    try:
+      problem = form.save(commit=False)
+    except ValueError, err:
+      errors['__all__'] = unicode(err)
+      
+
+  if errors:
+    print "new world"
+    if internal:
+      return ('error',errors)
+    return respond(request, user, 'new_edit_problem', 
+                         {'form': form, 'problem':problem, 'creating':creating_new})
+
+  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:
+    
+
+
+    
+    problem.author = user.username
+    problem.created = date.today()
+    problem. modified=date.today()
+
+    problem.save()  
+#  l = []
+  # for x in problem.categories:
+  #   l.extend(x.split())
+  # problem.categories = l
+  # problem.put()
+
+  if internal:
+    return ('success','success')
+  
+
+  return http.HttpResponseRedirect('/problems')
+
+def upload(request): 
+  """ upload handler, validates the form and calls handle_uploaded_file
+      for processing further
+  """
+  user = request.user
+  if user is None:
+    return http.HttpResponseForbidden('You must be an signed in to create/edit a problem.')
+
+  if request.method == 'POST':
+    form = UploadForm(request.POST, request.FILES)
+    if form.is_valid():
+      submission_report = handle_uploaded_file(request)
+      print "testing"
+      print submission_report
+
+      return respond(request, user, 'upload', {'report':submission_report})
+    else:
+      return http.HttpResponseForbidden('Oops something went wrong with the upload')
+
+def handle_uploaded_file(request):
+  """ Handles uploaded data, pushes it to existing problem creating code
+      TODO: 1. make efficient by putting actual database code Here
+            2. Add more security and validation
+  """
+  submission_data = request.FILES['file'].read()
+  if '#---' in submission_data:
+    all_submissions = submission_data.split('#---')[1:-1]
+    # ^^ ignoring the first null and last __main__ code
+    all_submissions = [ pykataupload.Submission(x) for x in all_submissions ]
+    report = []
+
+    for key,each_submission in enumerate(all_submissions):
+      # TODO: handle these later by TaskQueues to avoid timeouts on big uploads
+      # a good way would be to have ajax based status coming back to this page
+      # about each problem in the uploaded file, their status, progress etc.
+      each_submission.parse()
+      request.POST.clear()
+      request.POST.update (each_submission.data_dict)
+      upload_status, upload_response = new_edit(request, internal=True)
+
+      report.append ({'status':upload_status, 'name':each_submission['name'], 
+                          'upload_response':upload_response})
+
+      # Yay this hack works :D
+    return report
+  else:
+    return http.HttpResponseForbidden('The file you uploaded is not in appropriate format.')
+
+def shell(request):
+  """ need to change user in the django.contrib way"""
+
+  user = request.user
+  statement=request.GET.get('statement','')
+  if  statement is not '':
+    
+    # the python compiler doesn't like network line endings
+    statement = statement.replace('\r\n', '\n')
+
+    # add a couple newlines at the end of the statement. this makes
+    # single-line expressions such as 'class Foo: pass' evaluate happily.
+    statement += '\n\n'
+    print "statement"+statement 
+    # log and compile the statement up front
+    try:
+      logging.info('Compiling and evaluating:\n%s' % statement)
+      compiled = compile(statement, '<string>', 'single')
+    except:
+       return HttpResponse(traceback.format_exc(),mimetype="text/plain")  
+#      pass
+    return HttpResponse("",mimetype="text/plain")
+  else:
+    return respond(request, user, 'shell')
+
+