icp/src/rest/views.py

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