diff -r 000000000000 -r 0b061d58aea3 testappproj/testapp/views.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testappproj/testapp/views.py Mon May 17 22:33:59 2010 +0530 @@ -0,0 +1,439 @@ +# Python imports +import doctest +import logging +import os +import traceback +import random + + +# # 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 +from django.contrib.auth.decorators import permission_required +from models import Problem + + +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=[] + all_sessions=set([element.session for element in Problem.objects.all()]) + print all_sessions + + # for problem in problems: + # e = dict(problem=problem.description, + # username=user.username, + # problem_id=problem.id + + # ) + # entries.append(e) + +# print entries + + + #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 } ) + +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}) + + +@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 +# print user.get_all_permissions() + 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.') + +# formset = ProblemForm(data=request.POST) +# instance=formset.save() +# # upload_form = UploadForm(data=request.POST) + + if request.method == 'POST': + form = ProblemForm(request.POST) + else: + form = ProblemForm() + + + + if not request.POST: + return respond(request, user, 'new_edit_problem', {'form':form, 'problem':None, 'creating':creating_new }) + +# print form + #errors = form.errors + #print str(errors)+"errors" + + + #if not errors: + # try: + + if form.is_valid(): + + description = form.cleaned_data['Description'] + problem_type=form.cleaned_data['Problem_type'] + solution=form.cleaned_data['Solution'] + session=form.cleaned_data['Session'] + + 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) + + problem.save() + print "saved" + else: + print "form is valid" + print form.errors + +# print form.errors + # except ValueError, err: + # errors['__all__'] = unicode(err) + + + # if errors: + # print "new world" + # if internal: + + # print errors + # return ('error',errors) + # 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') + +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, '', 'single') + except: + return HttpResponse(traceback.format_exc(),mimetype="text/plain") +# pass + return HttpResponse("",mimetype="text/plain") + else: + return respond(request, user, 'shell') + +