Browse Source

Grading (but no meaningful database manipulation yet)

raylu 14 năm trước cách đây
mục cha
commit
029e953d4c
5 tập tin đã thay đổi với 61 bổ sung3 xóa
  1. 29 0
      graders/lab1.py
  2. 1 1
      pyc/grader/models.py
  3. 20 2
      pyc/grader/views.py
  4. 10 0
      pyc/templates/submit.html
  5. 1 0
      requirements.txt

+ 29 - 0
graders/lab1.py

@@ -0,0 +1,29 @@
+#!/usr/bin/env python
+
+from sandbox import Sandbox, SandboxConfig
+import sys
+from os import path
+
+importname = sys.argv[1]
+if importname.endswith('.py'):
+	importname = importname[:len(importname)-3]
+else:
+	print 'Filename did not end with .py for some reason...'
+	sys.exit(2)
+
+sys.path.insert(0, path.expanduser('~/submissions'))
+sys.dont_write_bytecode = True
+
+def run():
+	exec("import %s as submission" % importname)
+	if submission.test() == 1:
+		return 100
+	else:
+		return 0
+
+config = SandboxConfig()
+config.timeout = 5
+config.allowModule(importname, 'test')
+sandbox = Sandbox(config)
+score = sandbox.call(run)
+print score

+ 1 - 1
pyc/grader/models.py

@@ -10,7 +10,7 @@ class Submission(models.Model):
 	from django.contrib.auth.models import User
 	def upload_filename(instance, filename):
 		from time import time
-		return "%d-%d.%d" % (instance.lab.id, instance.user.id, int(time()))
+		return "s%d_%d_%d.py" % (instance.lab.id, instance.user.id, int(time()))
 	lab = models.ForeignKey(Lab)
 	user = models.ForeignKey(User)
 	time = models.DateTimeField(auto_now_add=True)

+ 20 - 2
pyc/grader/views.py

@@ -21,20 +21,38 @@ from django.contrib.auth.decorators import login_required
 @login_required
 def submit(request, lab_id):
 	from django.http import HttpResponseRedirect
+	from django.db import IntegrityError
 	if request.method == 'POST':
 		form = SubmissionForm(request.POST, request.FILES)
 		if form.is_valid():
 			labobj = Lab.objects.get(pk=lab_id)
 			rfile = request.FILES['file']
 			submission = Submission(lab=labobj, user=request.user, file=rfile)
-			submission.save()
-			return HttpResponseRedirect("/lab/%s/" % lab_id)
+			try:
+				submission.save()
+			except IntegrityError:
+				pass
+			score, err = grade(submission.file.name, lab_id)
+			return render_to_response('submit.html', {
+					'err' : err,
+					'score' : score,
+					'form' : form,
+					}, context_instance=RequestContext(request))
 	else:
 		form = SubmissionForm()
 	return render_to_response('submit.html', {
 			'form' : form,
 			}, context_instance=RequestContext(request))
 
+def grade(file, id):
+	import subprocess
+	from os import path
+	graderfile = "lab%s.py" % id
+	graderdir = path.dirname(__file__) + '/../../graders/'
+	grader = graderdir + graderfile
+	p = subprocess.Popen([grader, file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+	return p.communicate()
+
 from django import forms
 class SubmissionForm(forms.Form):
 	file = forms.FileField()

+ 10 - 0
pyc/templates/submit.html

@@ -1,5 +1,15 @@
 {% extends 'base.html' %}
 {% block body %}
+
+{% if score %}
+<p>You scored {{ score }}</p>
+{% endif %}
+{% if err %}
+<pre>
+{{ err }}
+</pre>
+{% endif %}
+
 <p>
 <form method="POST" enctype="multipart/form-data">
 {{ form }}

+ 1 - 0
requirements.txt

@@ -1 +1,2 @@
 django
+pysandbox