282 lines
8.2 KiB
Python
282 lines
8.2 KiB
Python
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
|
|
import pymongo
|
|
from pymongo import MongoClient
|
|
|
|
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
|
|
|
|
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
|
|
|
|
# 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):
|
|
event_db = mongo["events"]
|
|
event_col = event_db["events"]
|
|
|
|
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)
|
|
#else:
|
|
# return JSONResponse("""{"error": "HTTP request type not allowed."}""", status=400)
|
|
|
|
|
|
|
|
|
|
# Job API
|
|
###############################################################################
|
|
#@api_view(['GET','POST'])
|
|
@csrf_exempt
|
|
def job_status(request, jid):
|
|
print("Job-status " + jid)
|
|
data = str({"field1": "value1"})
|
|
|
|
#job_db = mongo["jobs"]
|
|
#job_col = job_db["jobs"]
|
|
|
|
#return HttpResponse(status=404)
|
|
|
|
if request.method == 'GET':
|
|
|
|
task = celery_task_compile_and_run.AsyncResult(jid)
|
|
print("results")
|
|
data = {"status": task.status, "data": task.result}
|
|
print("DONE!")
|
|
|
|
#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):
|
|
job_db = mongo["jobs"]
|
|
job_col = job_db["jobs"]
|
|
|
|
|
|
# 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':
|
|
print(datetime.datetime.now(), file=sys.stderr)
|
|
print(request.data, file=sys.stderr)
|
|
|
|
slide = get_object_or_404(Slide, pk=request.data['slide'])
|
|
print("Solution from: ", slide.title, file=sys.stderr)
|
|
|
|
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
|
|
print('job_dic:', file=sys.stderr)
|
|
|
|
|
|
# Also create/update the user solution.
|
|
user_solution = None
|
|
if request.user.is_authenticated():
|
|
try:
|
|
item, created = UserSolution.objects.get_or_create(slide=slide, user=request.user)
|
|
user_solution = item
|
|
except UserSolution.DoesNotExist:
|
|
pass
|
|
|
|
print(user_solution, file=sys.stderr)
|
|
|
|
if user_solution != None:
|
|
user_solution.data = json.dumps(request.data)
|
|
user_solution.save()
|
|
|
|
|
|
pprint.pprint(job_dic, sys.stderr)
|
|
|
|
try:
|
|
task = celery_task_compile_and_run.delay(job_dic)
|
|
print(dir(task), file=sys.stderr)
|
|
print("PREP")
|
|
|
|
print(task.id, file=sys.stderr)
|
|
#print(task.status, file=sys.stderr)
|
|
job_dic["_id"] = task.id
|
|
print("DONE")
|
|
|
|
#_id = job_col.insert(request.data)
|
|
#print(_id, file=sys.stderr)
|
|
#json_docs = json.dumps(data, default=json_util.default)
|
|
return JSONResponse({"details": "OK", "id": str(task.id)}, status=201)
|
|
|
|
except:
|
|
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)
|
|
#
|