From 568b3f2f66fd88575938f1403f222b66f30c25c0 Mon Sep 17 00:00:00 2001 From: Josh W Date: Sat, 8 Feb 2020 00:07:04 -0500 Subject: [PATCH] Provide an annotate string directly if requested. --- savepointradio/api/renderers.py | 52 +++++++++++++++++++++++ savepointradio/api/views/controls.py | 11 +++++ savepointradio/core/utils.py | 17 ++++++++ savepointradio/savepointradio/settings.py | 2 + 4 files changed, 82 insertions(+) create mode 100644 savepointradio/api/renderers.py diff --git a/savepointradio/api/renderers.py b/savepointradio/api/renderers.py new file mode 100644 index 0000000..39b83df --- /dev/null +++ b/savepointradio/api/renderers.py @@ -0,0 +1,52 @@ +from django.conf import settings + +from rest_framework import renderers + +from core.utils import beautify_artists, clean_quotes + + +ANNOTATE_FORMAT = ( + 'annotate:req_id="{}",' + 'type="{}",' + 'artist="{}",' + 'title="{}",' + 'game="{}",' + 'replay_gain="{}":{}' +) + + +def build_annotate_string(request_obj): + ''' + Takes the song request object and returns a Liquidsoap annotate string + from the attributes. + ''' + song = request_obj['song'] + if song['song_type'] == 'J': + artist = settings.RADIO_NAME + title = 'Jingle' + game = settings.RADIO_NAME + else: + artist = beautify_artists(song['artists']) + title = clean_quotes(song['title']) + game = clean_quotes(song['game']) + return ANNOTATE_FORMAT.format( + request_obj['id'], + song['song_type'], + artist, + title, + game, + song['replaygain'], + song['path'] + ) + + +class LiquidsoapAnnotateRenderer(renderers.BaseRenderer): + ''' + Custom renderer to accept and respond with an "annotate" string + specific to Liquidsoap requests. + ''' + media_type = 'application/vnd.liquidsoap.annotate' + format = 'txt' + + def render(self, data, media_type=None, renderer_context=None): + return data.encode(self.charset) diff --git a/savepointradio/api/views/controls.py b/savepointradio/api/views/controls.py index 17c5b33..5b56ed9 100644 --- a/savepointradio/api/views/controls.py +++ b/savepointradio/api/views/controls.py @@ -6,6 +6,7 @@ from rest_framework.authentication import (SessionAuthentication, TokenAuthentication) from rest_framework.generics import RetrieveAPIView from rest_framework.permissions import IsAuthenticated +from rest_framework.renderers import BrowsableAPIRenderer, JSONRenderer from rest_framework.response import Response from rest_framework.views import APIView @@ -14,6 +15,7 @@ from profiles.exceptions import MakeRequestError from profiles.models import RadioProfile, SongRequest from radio.models import Song from ..permissions import IsDJ +from ..renderers import build_annotate_string, LiquidsoapAnnotateRenderer from ..serializers.controls import (JustPlayedSerializer, MakeRequestSerializer, GetRequestSerializer) @@ -51,6 +53,11 @@ class NextRequest(RetrieveAPIView): authentication_classes = [TokenAuthentication] permission_classes = [IsDJ] queryset = SongRequest.objects.all() + renderer_classes = [ + JSONRenderer, + BrowsableAPIRenderer, + LiquidsoapAnnotateRenderer + ] serializer = GetRequestSerializer def retrieve(self, request): @@ -74,6 +81,10 @@ class NextRequest(RetrieveAPIView): next_play.save(update_fields=['queued_at']) serializer = GetRequestSerializer(next_play, many=False) + + media_type = request.accepted_renderer.media_type + if media_type == 'application/vnd.liquidsoap.annotate': + return Response(build_annotate_string(serializer.data)) return Response(serializer.data) diff --git a/savepointradio/core/utils.py b/savepointradio/core/utils.py index 24d73eb..91070d8 100644 --- a/savepointradio/core/utils.py +++ b/savepointradio/core/utils.py @@ -191,3 +191,20 @@ def iri_to_path(iri): return '\\' + url2ntpathname('/' + parse.netloc + parse.path) return url2ntpathname(parse.path) return url2pathname(urlparse(uri).path) + + +def clean_quotes(unclean_string): + ''' + Escapes quotes for use in the Liquidsoap parser. + ''' + return unclean_string.replace('"', '\\"') + + +def beautify_artists(artists): + ''' + Turns a list of one or more artists into a proper English listing. + ''' + output = ', ' + if len(artists) == 2: + output = ' & ' + return clean_quotes(output.join(artists)) diff --git a/savepointradio/savepointradio/settings.py b/savepointradio/savepointradio/settings.py index a03e56a..e2f0151 100644 --- a/savepointradio/savepointradio/settings.py +++ b/savepointradio/savepointradio/settings.py @@ -145,3 +145,5 @@ REST_FRAMEWORK = { RADIO_DJ_EMAIL = config('RADIO_DJ_EMAIL', default='dj@radiostation.net') RADIO_DJ_NAME = config('RADIO_DJ_NAME', default='DJ Reinhardt') + +RADIO_NAME = config('RADIO_NAME', default='Django Unstringed')