dr.botzo/markov/views.py

83 lines
2.9 KiB
Python

"""Manipulate Markov data via the Django site."""
import json
import logging
import time
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, render
from rest_framework.authentication import BasicAuthentication
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.decorators import api_view, authentication_classes, permission_classes
import markov.lib as markovlib
from markov.models import MarkovContext
logger = logging.getLogger(__name__)
def index(request):
"""Display nothing, for the moment."""
return HttpResponse()
def context_index(request, context_id):
"""Display the context index for the given context."""
start_t = time.time()
context = get_object_or_404(MarkovContext, pk=context_id)
chain = " ".join(markovlib.generate_line(context))
end_t = time.time()
return render(request, 'markov/context.html', {'chain': chain, 'context': context, 'elapsed': end_t - start_t})
@api_view(['POST'])
@authentication_classes((BasicAuthentication, ))
@permission_classes((IsAuthenticated, ))
def rpc_generate_line_for_context(request, context):
"""Generate a line from a given context, with optional topics included."""
if request.method != 'POST':
return Response({'detail': "Supported method: POST."}, status=405)
topics = None
try:
if request.body:
markov_data = json.loads(request.body)
topics = markov_data.get('topics', [])
except (json.decoder.JSONDecodeError, KeyError):
return Response({'detail': "Request body, if provided, must be JSON with an optional 'topics' parameter."},
status=400)
context_id = markovlib.get_or_create_target_context(context)
try:
generated_words = markovlib.generate_line(context_id, topics)
except ValueError as vex:
return Response({'detail': f"Could not generate line: {vex}", 'context': context, 'topics': topics},
status=400)
else:
return Response({
'context': context, 'topics': topics,
'generated_line': ' '.join(generated_words), 'generated_words': generated_words
})
@api_view(['POST'])
@authentication_classes((BasicAuthentication, ))
@permission_classes((IsAuthenticated, ))
def rpc_learn_line_for_context(request, context):
"""Learn a line for a given context."""
if request.method != 'POST':
return Response({'detail': "Supported method: POST."}, status=405)
try:
markov_data = json.loads(request.body)
line = markov_data.get('line', [])
except (json.decoder.JSONDecodeError, KeyError):
return Response({'detail': "Request body must be JSON with a 'line' parameter."}, status=400)
context_id = markovlib.get_or_create_target_context(context)
markovlib.learn_line(line, context_id)
return Response({'status': "OK", 'context': context, 'line': line})