From 0ef5a88a022307ab45486fca4a309f50621db736 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Wed, 29 May 2024 15:20:20 -0400 Subject: [PATCH] 2024-05-29 Fred Gleason * Fixed a bug in the 'pypad_icecast2.py PyPAD script that caused mojibake when sending ISO-8859-1 characters with code points >= 0x80. Signed-off-by: Fred Gleason --- ChangeLog | 3 +++ apis/pypad/scripts/pypad_icecast2.py | 18 ++++++++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 14b280b7..e8ff9091 100644 --- a/ChangeLog +++ b/ChangeLog @@ -24791,3 +24791,6 @@ * Removed the resynchronization code from the 'RDJsonFramer' class. * Fixed a bug in rdpadd(8) that could cause corruption when processing JSON updates. +2024-05-29 Fred Gleason + * Fixed a bug in the 'pypad_icecast2.py PyPAD script that caused + mojibake when sending ISO-8859-1 characters with code points >= 0x80. diff --git a/apis/pypad/scripts/pypad_icecast2.py b/apis/pypad/scripts/pypad_icecast2.py index ed895401..5bdf8332 100755 --- a/apis/pypad/scripts/pypad_icecast2.py +++ b/apis/pypad/scripts/pypad_icecast2.py @@ -4,7 +4,7 @@ # # Send PAD updates to Icecast2 mountpoint # -# (C) Copyright 2018-2022 Fred Gleason +# (C) Copyright 2018-2024 Fred Gleason # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License version 2 as @@ -25,8 +25,10 @@ import sys import socket import requests from requests.auth import HTTPBasicAuth +from requests import Session, Request import xml.etree.ElementTree as ET import syslog +from urllib.parse import quote try: from rivendellaudio import pypad except ModuleNotFoundError: @@ -36,6 +38,10 @@ import configparser def eprint(*args,**kwargs): print(*args,file=sys.stderr,**kwargs) +def IcecastQuote(string): + string=quote(string,safe=' ',encoding='ISO-8859-1',errors='replace') + return string + def ProcessPad(update): if update.hasPadType(pypad.TYPE_NOW): n=1 @@ -47,7 +53,6 @@ def ProcessPad(update): try: values={} values['mount']=update.config().get(section,'Mountpoint') - values['song']=update.resolvePadFields(update.config().get(section,'FormatString'),pypad.ESCAPE_NONE) values['mode']='updinfo' hostname=update.config().get(section,'Hostname') tcpport=update.config().get(section,'Tcpport') @@ -64,9 +69,13 @@ def ProcessPad(update): # if update.shouldBeProcessed(section): try: - response=requests.get(url,auth=HTTPBasicAuth(username,password),params=values) + req=Request('GET',url,auth=HTTPBasicAuth(username,password),params=values) + prep=req.prepare() + song=update.resolvePadFields(update.config().get(section,'FormatString'),pypad.ESCAPE_NONE) + prep.url=prep.url+'&song='+IcecastQuote(song) + response=sess.send(prep) response.raise_for_status() - update.syslog(syslog.LOG_INFO,'Updating '+hostname+': song='+values['song']) + update.syslog(syslog.LOG_INFO,'Updating http://'+hostname+values['mount']+': song='+song) except requests.exceptions.RequestException as e: update.syslog(syslog.LOG_WARNING,str(e)) n=n+1 @@ -91,4 +100,5 @@ except IndexError: eprint('pypad_icecast2: USAGE: cmd ') sys.exit(1) rcvr.setPadCallback(ProcessPad) +sess=Session() rcvr.start(sys.argv[1],int(sys.argv[2]))