diff --git a/oer/exercise-formats/choice/multiple/script.js b/oer/exercise-formats/choice/multiple/script.js
old mode 100644
new mode 100755
diff --git a/oer/exercise-formats/input/text/script.js b/oer/exercise-formats/input/text/script.js
old mode 100644
new mode 100755
diff --git a/oer/exercise-formats/program/match-regex-multifile/script.js b/oer/exercise-formats/program/match-regex-multifile/script.js
old mode 100644
new mode 100755
diff --git a/oer/exercise-formats/program/match-regex-parallel/script.js b/oer/exercise-formats/program/match-regex-parallel/script.js
old mode 100644
new mode 100755
diff --git a/oer/exercise-formats/program/match-regex/controller.py b/oer/exercise-formats/program/match-regex/controller.py
old mode 100644
new mode 100755
index a456f73..81c6cb2
--- a/oer/exercise-formats/program/match-regex/controller.py
+++ b/oer/exercise-formats/program/match-regex/controller.py
@@ -20,7 +20,7 @@ def build(ctx):
# start subprocess in with work_path as cwd
p = subprocess.Popen(allArgs, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=ctx.work_path)
msgs,errs = p.communicate()
- retval = p.wait()
+ retval = p.wait()
errs = errs.decode("utf-8")
msgs = msgs.decode("utf-8")
@@ -37,7 +37,7 @@ def execute(ctx):
p = subprocess.Popen(allArgs, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=ctx.work_path)
msgs,errs = p.communicate()
- retval = p.wait()
+ retval = p.wait()
errs = errs.decode("utf-8")
msgs = msgs.decode("utf-8")
@@ -62,10 +62,8 @@ def grade(ctx):
else:
return 'FAIL'
-
def response(ctx):
-
output = ""
if ctx.build_result[0] != 0:
output = ctx.build_result[1]
diff --git a/oer/exercise-formats/program/match-regex/script.js b/oer/exercise-formats/program/match-regex/script.js
old mode 100644
new mode 100755
diff --git a/oer/exercise-formats/program/scriptgrade/script.js b/oer/exercise-formats/program/scriptgrade/script.js
old mode 100644
new mode 100755
diff --git a/oer/exercise-formats/text/html/script.js b/oer/exercise-formats/text/html/script.js
old mode 100644
new mode 100755
diff --git a/src/frontend/templates/frontend/footer.html b/src/frontend/templates/frontend/footer.html
index 7f1f5ba..c74fa31 100644
--- a/src/frontend/templates/frontend/footer.html
+++ b/src/frontend/templates/frontend/footer.html
@@ -14,6 +14,8 @@
.sep { color: silver; margin: 0.3em; }
+ Privacy
+ |
Impressum
|
Contact
diff --git a/src/frontend/templates/frontend/privacy.html b/src/frontend/templates/frontend/privacy.html
new file mode 100644
index 0000000..e69de29
diff --git a/src/frontend/views.py b/src/frontend/views.py
index f42e6b3..716ea7c 100644
--- a/src/frontend/views.py
+++ b/src/frontend/views.py
@@ -34,6 +34,10 @@ def attribution(request):
data = {}
return render(request, 'frontend/attribution.html', data)
+def privacy(request):
+ data = {}
+ return render(request, 'frontend/privacy.html', data)
+
def dashboard(request):
# only registered users can see their statistics
if not request.user.is_authenticated:
diff --git a/src/main/urls.py b/src/main/urls.py
index 1bce2cc..4aa22e6 100644
--- a/src/main/urls.py
+++ b/src/main/urls.py
@@ -29,6 +29,7 @@ urlpatterns = [
url(r'^dashboard/$', frontend.views.dashboard, name='dashboard'),
url(r'^settings/$', frontend.views.settings, name='settings'),
url(r'^attribution/$', frontend.views.attribution, name='attribution'),
+ url(r'^privacy/$', frontend.views.privacy, name='privacy'),
# Courses
url(r'^courses/', include('courses.urls', namespace='courses')),
diff --git a/src/rest/views.py b/src/rest/views.py
index f498c50..c190424 100644
--- a/src/rest/views.py
+++ b/src/rest/views.py
@@ -27,6 +27,7 @@ import sys
import os
import pprint
import re
+import os.path
from courses.models import Course
from courses.models import Section
@@ -34,14 +35,26 @@ from courses.models import Slide
from courses.models import UserCourse
from courses.models import UserSolution
+from runner.tasks import compile_and_run
+import json
+
def local_execute(dic):
- print("LOCAL EXECUTE")
- print(dic)
- return {"id" : 100}
+ #print("LOCAL EXECUTE")
+ id = 100
+ ret = compile_and_run(id, dic)
+ print(ret, file=sys.stderr)
+ return {"status" : 'SUCCESS', "id" : id, "result": ret}
def local_execute_result(id):
- print("Retrieving: " + id)
- return {"status" : 201, "result": {"output" : False, "grade" : "PASS"}}
+ #return {"status" : 201, "result": {"output" : False, "grade" : "PASS"}}
+ file = "/data/run/jobs/%s/job.json" % (id)
+ print("Retrieving: " + file)
+ if os.path.isfile(file):
+ with open(file) as json_data:
+ d = json.load(json_data)
+ return {"status" : 'SUCCESS', "result": d["response"]}
+ else:
+ return {"status" : 0, "result": {"output" : False}}
# helpers
class JSONResponse(HttpResponse):
@@ -178,7 +191,6 @@ def job_status(request, jid):
#data = JSONParser().parse(json_docs)
return JSONResponse(data)
-
return HttpResponse("huh", status=401)
diff --git a/src/runner/tasks.py b/src/runner/tasks.py
index 2e6d7fc..81d24fb 100644
--- a/src/runner/tasks.py
+++ b/src/runner/tasks.py
@@ -1,34 +1,23 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
-from runner.celery import app
+#from runner.celery import app
import subprocess
import os
import sys
import shutil
import json
-
-
import importlib.machinery
-
-# To conserve resources consider using the ignore result decorator, when the result is not used by someone else
-#@app.task(ignore_result=True)
-
-###############################################################################
-# Settings
-###############################################################################
-WORK_DIR = os.path.expanduser(os.environ["WORKER_DIR"])
-OER_FORMATS_PATH = os.path.expanduser(os.environ["WORKER_OER_DIR"] + "/exercise-formats/")
-###############################################################################
-
+WORK_DIR = "/data/run/jobs"
+OER_FORMATS_PATH = "/data/oer/exercise-formats/"
def load_handler(path):
- handler = {'name': None, 'loader': None, 'mod': None}
+ handler = {'name': None, 'loader': None, 'mod': None}
+ #print(path, file=sys.stderr)
for root, dirs, files in os.walk(path):
- #print(root, file=sys.stderr)
#print(dirs, file=sys.stderr)
#print(files, file=sys.stderr)
if 'controller.py' in files:
@@ -50,7 +39,7 @@ def load_handler(path):
class Job(object):
"""
- The job class for tasks implements some default behaivior for every
+ The job class for tasks implements some default behaivior for every
format and tries to call special event handlers when they are defined
for the formats or exercises.
@@ -66,8 +55,8 @@ class Job(object):
"""
- def __init__(self, job, celery_task=None):
- print("Job.__init__()", file=sys.stderr)
+ def __init__(self, job):
+ #print("Job.__init__()", file=sys.stderr)
self.data = job
self.work_path = WORK_DIR + '/' + str(job['_id']) + '/'
self.handler_format = {'name': None, 'loader': None, 'mod': None}
@@ -78,31 +67,22 @@ class Job(object):
self.grade_result = 'FAIL'
self.response_data = {}
-
-
-
-
- # allow controllers to manipulate celery task
- # e.g. to set meta data after submitting slurm jobs
- self.celery_task = celery_task
-
def import_handlers(self):
print("Job.init_handlers()", file=sys.stderr)
# find exercise specific and default handler for exercise format
self.handler_format = load_handler("%s/%s" % (OER_FORMATS_PATH, self.data['type']))
- self.handler_exercise = load_handler( self.data['source_path'])
+ self.handler_exercise = load_handler(self.data['source_path'])
- if self.handler_format != None:
+ if self.handler_format != None:
print("INFO: Format handler found ;", file=sys.stderr)
- if self.handler_exercise != None:
+ if self.handler_exercise != None:
print("INFO: Exercise handlers found ;", file=sys.stderr)
def extract(self):
- print("Job.extract()", file=sys.stderr)
-
+ #print("Job.extract()", file=sys.stderr)
# creates workdir and files
print(self.data['source_path'], file=sys.stderr)
print(self.work_path, file=sys.stderr)
@@ -111,7 +91,7 @@ class Job(object):
src = self.data['source_path']
dst = self.work_path
shutil.copytree(src, dst)
-
+
self.sourcefile = self.work_path + 'program.c'
self.programfile = self.work_path + 'program'
@@ -121,14 +101,6 @@ class Job(object):
source.close()
-
-
-
-
-
- pass
-
-
def build(self):
print("Job.build()", file=sys.stderr)
@@ -208,11 +180,8 @@ class Job(object):
fp = open(self.jobfile, 'w')
json.dump({"job": self.data, "response": self.response_data}, fp)
fp.close()
-
# into mongodb
-
-
def get_file_content(self, filename):
try:
with open(self.work_path + '/' + filename, 'r') as f:
@@ -228,60 +197,43 @@ class Job(object):
-@app.task(time_limit=20)
-def timelimited_task():
- try:
- return do_work()
- except SoftTimeLimitExceeded:
- cleanup_in_a_hurry()
-
-@app.task
-def compile():
- return True
+#@app.task(time_limit=20)
+#def timelimited_task():
+# try:
+# return do_work()
+# except SoftTimeLimitExceeded:
+# cleanup_in_a_hurry()
+#
+#@app.task
+#def compile():
+# return True
-@app.task(bind=True)
-def compile_and_run(self, data):
-
- print(data, file=sys.stderr)
- print(self.request.id, file=sys.stderr)
-
- print(data['type'], file=sys.stderr)
- print(data['action'], file=sys.stderr)
- print(data['source_path'], file=sys.stderr)
-
- data['_id'] = self.request.id
-
+#@app.task(bind=True)
+def compile_and_run(id, data):
+ #print(data, file=sys.stderr)
+ #print(data['type'], file=sys.stderr)
+ #print(data['action'], file=sys.stderr)
+ #print(data['source_path'], file=sys.stderr)
+ data['_id'] = id
# create job object and call the different handlers
- j = Job(data, celery_task=self)
-
+ j = Job(data)
j.import_handlers()
-
if data['action'] not in ["quiz"]:
j.extract()
j.build()
-
+
if data['action'] in ["test", "execute", "run"]:
j.execute()
-
+
if data['action'] in ["grade", "quiz"]:
j.grade()
- print("Result prepare")
+ #print("Result prepare")
ret = j.response()
+ j.response_data = ret
j.store_result()
- print("Result sent!")
+ #print("Result sent!")
return ret
-
- # self.update_state(state='SUBMITTED TO SLURM', meta={})
-
-
-
-
-# Convienence task definitions for programming assignments
-@app.task
-def compile_run_and_grade():
- # start the celeryropriete subtasks
- return True