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[0-9]+)/(?P[0-9]+)/(?P[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) #