spradio-server-django/contrib/djcontrol/djcontrol.py

185 lines
4.9 KiB
Python
Raw Normal View History

2019-05-20 19:50:35 +00:00
'''
djcontrol.py
This is the helper script that glues the webapi/database to the liquidsoap
application. We make RESTful requests here to get the next song and to report
when a song has been played.
'''
import argparse
import json
2019-06-05 17:13:38 +00:00
import logging
from logging.handlers import RotatingFileHandler
2019-05-20 19:50:35 +00:00
from decouple import config
2019-05-20 19:50:35 +00:00
import requests
DJ_TOKEN = config('DJ_TOKEN')
2019-05-20 19:50:35 +00:00
API_URL = config('API_URL') # With trailing slash
2019-05-20 19:50:35 +00:00
RADIO_NAME = config('RADIO_NAME')
2019-05-20 19:50:35 +00:00
HEADERS = {
'Content-Type': 'application/json; charset=utf-8',
'Authorization': 'Token {}'.format(DJ_TOKEN)
}
2019-07-03 15:57:46 +00:00
ANNOTATE = (
'annotate:req_id="{}",'
'type="{}",'
'artist="{}",'
'title="{}",'
'game="{}",'
'replay_gain="{}":{}'
)
2019-05-20 19:50:35 +00:00
2019-06-05 17:13:38 +00:00
logging.basicConfig(
handlers=[
RotatingFileHandler(
'./song_requests.log',
maxBytes=1000000,
backupCount=5,
encoding='utf8'
)
],
level=logging.INFO,
format=('[%(asctime)s] [%(levelname)s]'
' [%(name)s.%(funcName)s] === %(message)s'),
datefmt='%Y-%m-%dT%H:%M:%S'
)
LOGGER = logging.getLogger('djcontrol')
2019-05-20 19:50:35 +00:00
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))
2019-06-05 17:13:38 +00:00
def next_request():
'''
Sends an HTTP[S] request to the radio web service to retrieve the next
requested song.
'''
LOGGER.debug('Received command to get next song request.')
2019-05-20 19:50:35 +00:00
try:
2019-06-05 19:28:35 +00:00
resp = requests.get(API_URL + 'next/', headers=HEADERS, timeout=5)
resp.encoding = 'utf-8'
resp.raise_for_status()
2019-05-20 19:50:35 +00:00
except requests.exceptions.HTTPError as errh:
2019-06-05 17:13:38 +00:00
LOGGER.error('Http Error: %s', errh)
2019-05-20 19:50:35 +00:00
except requests.exceptions.ConnectionError as errc:
2019-06-05 17:13:38 +00:00
LOGGER.error('Error Connecting: %s', errc)
2019-05-20 19:50:35 +00:00
except requests.exceptions.Timeout as errt:
2019-06-05 17:13:38 +00:00
LOGGER.error('Timeout Error: %s', errt)
2019-05-20 19:50:35 +00:00
except requests.exceptions.RequestException as err:
2019-06-05 17:13:38 +00:00
LOGGER.error('Error: %s', err)
2019-05-20 19:50:35 +00:00
else:
2019-06-05 19:28:35 +00:00
LOGGER.debug('Received JSON response: %s', resp.text)
song_request = json.loads(resp.text)
song = song_request['song']
2019-05-20 19:50:35 +00:00
if song['song_type'] == 'J':
artist = RADIO_NAME
title = 'Jingle'
game = RADIO_NAME
else:
artist = beautify_artists(song['artists'])
title = clean_quotes(song['title'])
game = clean_quotes(song['game'])
2019-06-05 17:13:38 +00:00
LOGGER.info(
2019-07-03 15:57:46 +00:00
'ID: %s, Artist[s]: %s, Title: %s, Game: %s, Gain: %s, Path: %s',
2019-06-05 19:28:35 +00:00
song_request['id'],
2019-06-05 17:13:38 +00:00
artist,
title,
game,
2019-07-03 15:57:46 +00:00
song['replaygain'],
2019-06-05 17:13:38 +00:00
song['path']
)
annotate_string = ANNOTATE.format(
2019-06-05 19:28:35 +00:00
song_request['id'],
2019-06-05 17:13:38 +00:00
song['song_type'],
artist,
title,
game,
2019-07-03 15:57:46 +00:00
song['replaygain'],
2019-06-05 17:13:38 +00:00
song['path']
)
LOGGER.debug(annotate_string)
print(annotate_string)
def just_played(request_id):
'''
Sends an HTTP[S] request to the radio web service to let it know that a
song has been played.
'''
LOGGER.debug('Received command to report a song was just played.')
2019-05-20 19:50:35 +00:00
try:
2019-06-05 19:28:35 +00:00
request_played = json.dumps({'song_request': request_id})
resp = requests.post(
API_URL + 'played/',
headers=HEADERS,
data=request_played,
timeout=5
)
resp.encoding = 'utf-8'
resp.raise_for_status()
2019-05-20 19:50:35 +00:00
except requests.exceptions.HTTPError as errh:
2019-06-05 17:13:38 +00:00
LOGGER.error('Http Error: %s', errh)
2019-05-20 19:50:35 +00:00
except requests.exceptions.ConnectionError as errc:
2019-06-05 17:13:38 +00:00
LOGGER.error('Error Connecting: %s', errc)
2019-05-20 19:50:35 +00:00
except requests.exceptions.Timeout as errt:
2019-06-05 17:13:38 +00:00
LOGGER.error('Timeout Error: %s', errt)
2019-05-20 19:50:35 +00:00
except requests.exceptions.RequestException as err:
2019-06-05 17:13:38 +00:00
LOGGER.error('Error: %s', err)
else:
LOGGER.info('Req_ID: %s', request_id)
def main():
'''Main loop of the program'''
description = 'Lets the DJ control the radio.'
parser = argparse.ArgumentParser(description=description)
subparsers = parser.add_subparsers(dest='command')
parser_next = subparsers.add_parser(
'next',
help='Gets the next song from the radio.'
)
parser_played = subparsers.add_parser(
'played',
help='Tells the radio which song just played.'
)
parser_played.add_argument(
'request',
help='Song request ID number.',
nargs=1,
type=int
)
args = parser.parse_args()
if args.command == 'next':
next_request()
elif args.command == 'played':
just_played(args.request[0])
if __name__ == '__main__':
main()