From be7b02b1264da395346611ada3558afa2942f23d Mon Sep 17 00:00:00 2001 From: Patrick Linstruth Date: Mon, 10 Dec 2018 19:15:06 -0800 Subject: [PATCH] Initial commit --- apis/PyPAD/examples/pypad_tunein.py | 136 ++++++++++++++++++++++++++++ conf/pypad_tunein.conf | 114 +++++++++++++++++++++++ 2 files changed, 250 insertions(+) create mode 100755 apis/PyPAD/examples/pypad_tunein.py create mode 100644 conf/pypad_tunein.conf diff --git a/apis/PyPAD/examples/pypad_tunein.py b/apis/PyPAD/examples/pypad_tunein.py new file mode 100755 index 00000000..c0a951c4 --- /dev/null +++ b/apis/PyPAD/examples/pypad_tunein.py @@ -0,0 +1,136 @@ +#!/usr/bin/python + +# pypad_tunein.py +# +# Send PAD updates to TuneIn +# +# (C) Copyright 2018 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 +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +# + +from __future__ import print_function + +import os +import sys +import socket +import urllib +import xml.etree.ElementTree as ET +import syslog +import PyPAD +try: + import configparser +except ImportError: + import ConfigParser as configparser + +def eprint(*args,**kwargs): + print(pypad_name+': ',file=sys.stderr,end='',**kwargs) + print(*args,file=sys.stderr,**kwargs) + syslog.syslog(syslog.LOG_ERR,*args) + +def iprint(*args,**kwargs): + print(pypad_name+': ',file=sys.stdout,end='',**kwargs) + print(*args,sep=pypad_name+': ',file=sys.stdout,**kwargs) + syslog.syslog(syslog.LOG_INFO,*args) + +def isTrue(string): + l=['Yes','On','True','1'] + return string.lower() in map(str.lower,l) + +def ProcessPad(update): + if update.hasPadType(PyPAD.TYPE_NOW): + n=1 + while(True): + section='Station'+str(n) + try: + values={} + values['id']=config.get(section,'StationID') + values['partnerId']=config.get(section,'PartnerID') + values['partnerKey']=config.get(section,'PartnerKey') + values['title']=update.resolvePadFields(config.get(section,'TitleString'),PyPAD.ESCAPE_URL) + values['artist']=update.resolvePadFields(config.get(section,'ArtistString'),PyPAD.ESCAPE_URL) + values['album']=update.resolvePadFields(config.get(section,'AlbumString'),PyPAD.ESCAPE_URL) + url_values=urllib.urlencode(values) + url='http://air.radiotime.com/Playing.ashx?'+url_values + iprint('Updating TuneIn: artist='+values['artist']+' title='+values['title']+' album='+values['album']) + try: + response=urllib.urlopen(url) + except: + eprint(url+' code='+str(response.getcode())) + else: + xml=ET.fromstring(response.read()) + status=xml.find('./head/status') + if(status.text!='200'): + eprint('Update Failed: '+xml.find('./head/fault').text) + n=n+1 + except configparser.NoSectionError: + if(n==1): + eprint('No station config found') + return + +# +# Program Name +# +pypad_name=os.path.basename(__file__) + +# +# Open Syslog +# +syslog.openlog(logoption=syslog.LOG_PID, facility=syslog.LOG_DAEMON) + +# +# Read Configuration +# +if len(sys.argv)>=2: + fp=open(sys.argv[1]) + config=configparser.ConfigParser() + config.readfp(fp) + fp.close() +else: + eprint('You must specify a configuration file') + sys.exit(1) + +# +# Daemonize +# +try: + daemon=config.get(section,'Daemonize') +except: + daemon='0' + +if isTrue(daemon): + try: + pid=os.fork() + except: + eprint('Could not fork') + sys.exit(1) + + if (pid==0): + os.setsid() + else: + exit(0) + +# +# Create Send Socket +# +send_sock=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) + +# +# Start Receiver +# +rcvr=PyPAD.Receiver() +rcvr.setCallback(ProcessPad) +iprint('Started') +rcvr.start("localhost",PyPAD.PAD_TCP_PORT) +iprint('Stopped') diff --git a/conf/pypad_tunein.conf b/conf/pypad_tunein.conf new file mode 100644 index 00000000..8f207964 --- /dev/null +++ b/conf/pypad_tunein.conf @@ -0,0 +1,114 @@ +; pypad_tunein.conf +; +; This is the sample configuration file for the 'pypad_tunein' module for +; Rivendell, which can be used to update the metadata at TuneIn +; server using Now & Next data. +; + + +; Section Header +; +; One section per TuneIn station is configured, starting with +; 'Station1' and working up consecutively +[Station1] + + +; Daemonize +; +; Run pypad_tunein as a daemon 'Yes' or 'No'. +Daemonize=Yes + + +; StationID +; +; The Station ID of the TuneIn station to which to send updates. +StationID=s123456 + + +; PartnerID +; +; The Partner ID of the TuneIn station to which to send updates. +PartnerID=changeme + + +; PartnerKey +; +; The Partner Key of the TuneIn station to which to send updates. +PartnerKey=changeme + + +; Metadata String. The metadata fields to be sent each time RDAirPlay changes +; play state, including any wildcards as placeholders for metadata values. +; +; The list of available wildcards can be found in the 'metadata_wildcards.txt' +; file in the Rivendell documentation directory. +; +TitleString=%t +ArtistString=%a +AlbumString=%l + + +; Log Selection +; +; Set the status for each log to 'Yes', 'No' or 'Onair' to indicate whether +; state changes on that log should be output to this station. If set +; to 'Onair', then output will be generated only if RDAirPlays OnAir flag +; is active. +MasterLog=Yes +Aux1Log=Yes +Aux2Log=Yes +VLog101=No +VLog102=No +VLog103=No +VLog104=No +VLog105=No +VLog106=No +VLog107=No +VLog108=No +VLog109=No +VLog110=No +VLog111=No +VLog112=No +VLog113=No +VLog114=No +VLog115=No +VLog116=No +VLog117=No +VLog118=No +VLog119=No +VLog120=No + + +; Additional TuneIn stations can be configured by adding new +; sections... +; +;[Station2] +;StationID=s654321 +;PartnerID=changeme +;PartnerKey=changeme +;TitleString=%t +;ArtistString=%a +;AlbumString=%l +;MasterLog=No +;Aux1Log=Yes +;Aux2Log=No +;VLog101=No +;VLog102=No +;VLog103=No +;VLog104=No +;VLog105=No +;VLog106=No +;VLog107=No +;VLog108=No +;VLog109=No +;VLog110=No +;VLog111=No +;VLog112=No +;VLog113=No +;VLog114=No +;VLog115=No +;VLog116=No +;VLog117=No +;VLog118=No +;VLog119=No +;VLog120=No