ircradio/ircradio/radio.py

81 lines
2.4 KiB
Python
Raw Permalink Normal View History

2021-06-17 00:27:35 +01:00
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) 2021, dsc@xmr.pm
import logging
2021-06-17 00:27:35 +01:00
import re
import json
2021-06-17 00:27:35 +01:00
import os
import socket
from typing import List, Optional, Dict
import asyncio
import sys
import settings
from ircradio.models import Song
from ircradio.station import Station
2021-06-17 00:27:35 +01:00
from ircradio.utils import httpget
from ircradio.youtube import YouTube
class Radio:
@staticmethod
async def icecast_metadata(radio: Station) -> dict:
cache_key = f"icecast_meta_{radio.id}"
2021-06-17 00:27:35 +01:00
from quart import current_app
if current_app: # caching only when Quart is active
cache: SessionInterface = current_app.session_interface
res = await cache.get(cache_key)
if res:
return json.loads(res)
2021-06-17 00:27:35 +01:00
url = f"http://{settings.icecast2_bind_host}:{settings.icecast2_bind_port}"
url = f"{url}/status-json.xsl"
2021-06-17 00:27:35 +01:00
blob = await httpget(url, json=True)
if not isinstance(blob, dict) or "icestats" not in blob:
raise Exception("icecast2 metadata not dict")
2021-06-17 00:27:35 +01:00
arr = blob["icestats"].get('source')
if not isinstance(arr, list) or not arr:
raise Exception("no metadata results #1")
2021-06-17 00:27:35 +01:00
try:
res = next(r for r in arr if radio.mount_point == r['server_name'])
2021-06-17 00:27:35 +01:00
from quart import current_app
if current_app: # caching only when Quart is active
cache: SessionInterface = current_app.session_interface
await cache.set(cache_key, json.dumps(res), expiry=4)
2021-06-17 00:27:35 +01:00
return res
2021-06-17 00:27:35 +01:00
except Exception as ex:
raise Exception("no metadata results #2")
2021-06-17 00:27:35 +01:00
@staticmethod
async def command(cmd: str) -> bytes:
2021-06-17 00:27:35 +01:00
"""via LiquidSoap control port"""
from datetime import datetime
if settings.debug:
print(f"cmd: {cmd}")
2021-06-17 00:27:35 +01:00
try:
reader, writer = await asyncio.open_connection(
settings.liquidsoap_host, settings.liquidsoap_port)
2021-06-17 00:27:35 +01:00
except Exception as ex:
raise Exception(f"error connecting to {settings.liquidsoap_host}:{settings.liquidsoap_port}: {ex}")
2021-06-17 00:27:35 +01:00
writer.write(cmd.encode() + b"\n")
await writer.drain()
2021-06-17 00:27:35 +01:00
try:
task = reader.readuntil(b"\x0d\x0aEND\x0d\x0a")
data = await asyncio.wait_for(task, 1)
except Exception as ex:
logging.error(ex)
return b""
2021-06-17 00:27:35 +01:00
2023-09-02 20:11:38 +01:00
writer.close()
return data