icp/src/rest/views.py

304 lines
9.1 KiB
Python
Raw Normal View History

2018-05-05 22:18:02 +00:00
from __future__ import absolute_import
# django
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
# rest framework
from rest_framework.renderers import JSONRenderer
from rest_framework.parsers import JSONParser
from rest_framework import serializers
from rest_framework.decorators import api_view
from rest_framework.response import Response
from django.shortcuts import get_object_or_404
# mongo
2018-05-05 23:46:11 +00:00
#import pymongo
#from pymongo import MongoClient
2018-05-05 22:18:02 +00:00
import json
from bson import json_util
from bson.objectid import ObjectId
from bson.errors import InvalidId
import datetime
import sys
import os
import pprint
import re
2018-05-06 09:20:32 +00:00
import os.path
2018-05-06 10:35:06 +00:00
import shutil
2018-05-05 22:18:02 +00:00
from courses.models import Course
from courses.models import Section
from courses.models import Slide
from courses.models import UserCourse
from courses.models import UserSolution
2018-05-06 09:20:32 +00:00
from runner.tasks import compile_and_run
import json
2018-05-06 10:35:06 +00:00
import random
2018-05-05 23:46:11 +00:00
def local_execute(dic):
2018-05-06 10:35:06 +00:00
id = random.randint(1,10000000)
file = "/data/run/jobs/%s/job.json" % (id)
while os.path.isfile(file):
id = random.randint(1,10000000)
file = "/data/run/jobs/%s/job.json" % (id)
2018-05-06 09:20:32 +00:00
ret = compile_and_run(id, dic)
print(ret, file=sys.stderr)
2018-05-06 10:35:06 +00:00
return {"details": "OK", "id" : id, "data": ret}
2018-05-05 23:46:11 +00:00
def local_execute_result(id):
2018-05-06 09:20:32 +00:00
#return {"status" : 201, "result": {"output" : False, "grade" : "PASS"}}
2018-05-06 10:35:06 +00:00
if not id.isdigit():
return {"status" : 0, "result": {"output" : False}}
dir = "/data/run/jobs/%s/" % (id)
print("Retrieving: " + dir)
if os.path.isfile(dir + "job.json"):
with open(dir + "job.json") as json_data:
2018-05-06 09:20:32 +00:00
d = json.load(json_data)
2018-05-06 10:35:06 +00:00
# cleanup of outdated directories
2018-05-06 14:17:41 +00:00
shutil.rmtree(dir) # remove files directories
2018-05-06 10:35:06 +00:00
2018-05-06 09:20:32 +00:00
return {"status" : 'SUCCESS', "result": d["response"]}
else:
return {"status" : 0, "result": {"output" : False}}
2018-05-05 23:46:11 +00:00
2018-05-05 22:18:02 +00:00
# helpers
class JSONResponse(HttpResponse):
"""
An HttpResponse that renders its content into JSON.
"""
def __init__(self, data, **kwargs):
content = JSONRenderer().render(data)
kwargs['content_type'] = 'application/json'
super(JSONResponse, self).__init__(content, **kwargs)
class Entry(object):
def __init__(self):
pass
class EntrySerializer(serializers.Serializer):
def restore_object(self, attrs, instance=None):
if instance:
return instance
return Entry()
# django views
###############################################################################
def course(request, cid):
#try:
# user_course = UserCourse.objects.get(course=course_id)
#except UserCourse.DoesNotExist:
# raise Http404("Question does not exist")
data = {}
course = get_object_or_404(Course, pk=cid)
return render(request, 'courses/course.html', {'course': course, 'data': data})
def section(request, cid, seid):
data = {}
course = get_object_or_404(Course, pk=cid)
return render(request, 'courses/course.html', {'course': course, 'data': data})
def slide(request, cid, seid, slid):
data = {}
course = get_object_or_404(Course, pk=cid)
return render(request, 'courses/course.html', {'course': course, 'data': data})
def slide_check(request, cid, seid, slid):
data = {}
course = get_object_or_404(Course, pk=cid)
return render(request, 'courses/course.html', {'course': course, 'data': data})
###
def index(request):
return HttpResponse("Usage: /api/rest/..")
#@api_view(['GET','POST'])
@csrf_exempt
def entry_list(request, database_id):
data = str({"field1": "value1"})
if request.method == 'GET':
json_docs = [json.dumps(doc, default=json_util.default) for doc in cursor]
return HttpResponse("[%s]" % (",".join(json_docs)))
elif request.method == 'POST':
data = JSONParser().parse(request)
try:
_id = collection.insert(data)
data["_id"] = _id
json_docs = json.dumps(data, default=json_util.default)
return HttpResponse("%s" % json_docs, status=201)
except:
return JSONResponse("""{"error": "insert failed."}""", status=400)
# Event Stream API
###############################################################################
@api_view(['POST'])
@csrf_exempt
def event(request):
2018-05-05 23:46:11 +00:00
#event_db = mongo["events"]
#event_col = event_db["events"]
return JSONResponse({"details": "OK"}, status=201)
#if request.method == 'POST':
# # populate additional fields
# request.data["timestamp"] = datetime.datetime.now()
# request.data["referrer"] = request.META.get('HTTP_REFERER') # sic
# request.data["user_id"] = request.user.id
# #print(request.data, file=sys.stderr)
# try:
# _id = event_col.insert(request.data)
# print(request.data['type'], _id, file=sys.stderr)
# #json_docs = json.dumps(data, default=json_util.default)
# return JSONResponse({"details": "OK", "id": str(_id)}, status=201)
# except:
# return JSONResponse({"details": "insert failed."}, status=400)
2018-05-05 22:18:02 +00:00
#else:
# return JSONResponse("""{"error": "HTTP request type not allowed."}""", status=400)
# Job API
###############################################################################
#@api_view(['GET','POST'])
@csrf_exempt
def job_status(request, jid):
2018-05-05 23:46:11 +00:00
#print("Job-status " + jid)
2018-05-05 22:18:02 +00:00
data = str({"field1": "value1"})
#job_db = mongo["jobs"]
#job_col = job_db["jobs"]
#return HttpResponse(status=404)
if request.method == 'GET':
2018-05-05 23:46:11 +00:00
#task = celery_task_compile_and_run.AsyncResult(jid)
task = local_execute_result(jid)
#print("results")
data = {"status": task["status"], "data": task["result"]}
#print("DONE!")
2018-05-05 22:18:02 +00:00
#json_docs = json.dumps(data, default=json_util.default)
#data = JSONParser().parse(json_docs)
return JSONResponse(data)
return HttpResponse("huh", status=401)
@api_view(['POST'])
@csrf_exempt
def job_new(request):
2018-05-05 23:46:11 +00:00
#job_db = mongo["jobs"]
#job_col = job_db["jobs"]
2018-05-05 22:18:02 +00:00
# Snipped in-case we would like to force the referrer to match the slide.
#slid = None
#referrer = request.META.get('HTTP_REFERER')
#result = re.findall(r'/courses/(?P<cid>[0-9]+)/(?P<seid>[0-9]+)/(?P<slid>[0-9]+)/$', referrer)
#print(result, file=sys.stderr)
#try:
# slid = Slide.objects.get(pk=result[0][2])
#except Comment.DoesNotExist:
# slid = None
#
#print(slid, file=sys.stderr)
if request.method == 'POST':
2018-05-05 23:46:11 +00:00
#print(datetime.datetime.now(), file=sys.stderr)
#print(request.data, file=sys.stderr)
2018-05-05 22:18:02 +00:00
slide = get_object_or_404(Slide, pk=request.data['slide'])
2018-05-05 23:46:11 +00:00
#print("Solution from: ", slide.title, file=sys.stderr)
2018-05-05 22:18:02 +00:00
job_dic = {}
#job_dic['timestamp'] = datetime.datetime.now()
job_dic['solution'] = request.data['solution']
job_dic['action'] = request.data['action']
job_dic['source_path'] = slide.source_path
job_dic['type'] = slide.slide_type
job_dic['data'] = json.loads(slide.data)
job_dic['user_id'] = request.user.id
2018-05-05 23:46:11 +00:00
#print('job_dic:', file=sys.stderr)
2018-05-05 22:18:02 +00:00
# Also create/update the user solution.
user_solution = None
2018-05-05 23:04:26 +00:00
if request.user.is_authenticated:
2018-05-05 22:18:02 +00:00
try:
item, created = UserSolution.objects.get_or_create(slide=slide, user=request.user)
user_solution = item
except UserSolution.DoesNotExist:
pass
2018-05-05 23:46:11 +00:00
#print(user_solution, file=sys.stderr)
2018-05-05 22:18:02 +00:00
if user_solution != None:
user_solution.data = json.dumps(request.data)
user_solution.save()
2018-05-05 23:46:11 +00:00
#pprint.pprint(job_dic, sys.stderr)
2018-05-05 22:18:02 +00:00
try:
2018-05-05 23:46:11 +00:00
#task = celery_task_compile_and_run.delay(job_dic)
2018-05-06 10:35:06 +00:00
data = local_execute(job_dic)
2018-05-05 22:18:02 +00:00
#_id = job_col.insert(request.data)
#print(_id, file=sys.stderr)
#json_docs = json.dumps(data, default=json_util.default)
2018-05-06 10:35:06 +00:00
return JSONResponse(data, status=201)
2018-05-05 22:18:02 +00:00
except:
2018-05-05 23:46:11 +00:00
print(sys.exc_info()[0])
2018-05-05 22:18:02 +00:00
return JSONResponse({"details": "Job submission failed."}, status=400)
#else:
# return JSONResponse("""{"error": "HTTP request type not allowed."}""", status=400)
#else:
# return JSONResponse("""{"error": "HTTP request type not allowed."}""", status=400)
# return HttpResponse("huh")
#
# if request.method == 'GET':
# data = collection.find_one({"_id": _id})
# json_docs = json.dumps(data, default=json_util.default)
# return HttpResponse("%s" % json_docs)
#
# elif request.method == 'PUT':
# data = JSONParser().parse(request)
# data.pop("_id", None) # remove _id key from data for pymongo
# print >>sys.stdout, data
# try:
# collection.update({"_id": _id}, data)
# data["_id"] = _id
# json_docs = json.dumps(data, default=json_util.default)
# return HttpResponse("%s" % json_docs)
# except:
# return JSONResponse("""{"error": "update failed."}""", status=400)
#
# elif request.method == 'DELETE':
# collection.remove({"_id": _id})
# return HttpResponse(status=204)
#