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 |
|