2018-12-10 Fred Gleason <fredg@paravelsystems.com>

* Changed the name of the JSON PAD field 'logMachine' to 'machine'.
	* Changed the name of the 'PyPAD.Update::logMachine()' method to
	'PyPAD.Update::machine()'.
	* Changed the name of the JSON PAD field 'logMode' to 'mode'.
	* Added a 'PyPAD.Update::mode()' method.
	* Added a 'cutNumber' field to the JSON PAD 'now' and 'next' objects.
	* Added a 'PyPAD.FIELD_CUT_NUMBER' define.
	* Added 'api/PyPAD/examples/pypad_test.py'.
This commit is contained in:
Fred Gleason
2018-12-10 11:07:07 -05:00
parent d3e35a8cab
commit 387cbad1b0
6 changed files with 180 additions and 9 deletions

View File

@@ -46,6 +46,7 @@ TYPE_NEXT='next'
FIELD_START_DATETIME='startDateTime'
FIELD_CART_NUMBER='cartNumber'
FIELD_CART_TYPE='cartType'
FIELD_CUT_NUMBER='cutNumber'
FIELD_LENGTH='length'
FIELD_YEAR='year'
FIELD_GROUP_NAME='groupName'
@@ -226,7 +227,7 @@ class Update(object):
"""
Returns the date-time of the PAD update (datetime)
"""
return self.__fromIso8601(pad_data['padUpdate']['dateTime'])
return self.__fromIso8601(self.__fields['padUpdate']['dateTime'])
def escape(self,string,esc):
"""
@@ -252,12 +253,19 @@ class Update(object):
return self.__escapeJson(string)
raise ValueError('invalid esc value')
def logMachine(self):
def machine(self):
"""
Returns the log machine number to which this update pertains
(integer).
"""
return self.__fields['padUpdate']['logMachine']
return self.__fields['padUpdate']['machine']
def mode(self):
"""
Returns the operating mode of the host log machine to which
this update pertains (string).
"""
return self.__fields['padUpdate']['mode']
def onairFlag(self):
"""
@@ -411,6 +419,8 @@ class Update(object):
PyPAD.FIELD_CLIENT - The 'Client' field (string)
PyPAD.FIELD_COMPOSER - The 'Composer' field (string)
PyPAD.FIELD_CONDUCTOR - The 'Conductor' field (string)
PyPAD.FIELD_CUT_NUMER - The 'Cut Number' field
(integer)
PyPAD.FIELD_DESCRIPTION - The 'Description' field
(string)
PyPAD.FIELD_EXTERNAL_ANNC_TYPE - The 'EXT_ANNC_TYPE'

View File

@@ -21,6 +21,7 @@
## Use automake to process this into a Makefile.in
EXTRA_DIST = now_and_next.py\
pypad_test.py\
pypad_udp.py
CLEANFILES = *~\

View File

@@ -37,13 +37,13 @@ import PyPAD
def ProcessPad(update):
print
if update.hasPadType(PyPAD.TYPE_NOW):
print "Log %03d NOW: " % update.logMachine()+update.resolvePadFields("%a - %t",PyPAD.ESCAPE_NONE)
print "Log %03d NOW: " % update.machine()+update.resolvePadFields("%a - %t",PyPAD.ESCAPE_NONE)
else:
print "Log %03d NOW: [none]" % update.logMachine()
print "Log %03d NOW: [none]" % update.machine()
if update.hasPadType(PyPAD.TYPE_NEXT):
print "Log %03d NEXT: " % update.logMachine()+update.resolvePadFields("%A - %T",PyPAD.ESCAPE_NONE)
print "Log %03d NEXT: " % update.machine()+update.resolvePadFields("%A - %T",PyPAD.ESCAPE_NONE)
else:
print "Log %03d NEXT: [none]" % update.logMachine()
print "Log %03d NEXT: [none]" % update.machine()
#
# Create an instance of 'PyPADReceiver'

145
apis/PyPAD/examples/pypad_test.py Executable file
View File

@@ -0,0 +1,145 @@
#!/usr/bin/python
# pypad_test.py
#
# PyPAD regression test script for Rivendell
#
# Exercise every method of 'PyPAD.Update' for each update.
#
# (C) Copyright 2018 Fred Gleason <fredg@paravelsystems.com>
#
# 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.
#
import PyPAD
def ProcessPad(update):
print
print '*** Log %03d Update ***********************************************' % update.machine()
print '** HEADER INFO **'
print ' dateTime(): '+update.dateTime().isoformat(' ')
print ' machine(): %d' % update.machine()
print ' mode(): '+update.mode()
print ' onairFlag(): '+str(update.onairFlag())
print
if update.hasLog():
print '** LOG INFO **'
print ' logName(): '+update.logName()
print
else:
print '**NO LOG INFO PRESENT**'
print
if update.hasService():
print '** SERVICE INFO **'
print ' serviceName(): '+update.serviceName()
print 'serviceDescription(): '+update.serviceDescription()
print 'serviceProgramCode(): '+update.serviceProgramCode()
print
else:
print '** NO SERVICE INFO PRESENT **'
print
if update.hasPadType(PyPAD.TYPE_NOW):
print '** NOW PLAYING INFO **'
try:
print ' startDateTime(): '+update.startDateTime(PyPAD.TYPE_NOW).isoformat(' ')
except AttributeError:
print ' startDateTime(): None'
print ' cartType(): '+update.padField(PyPAD.TYPE_NOW,PyPAD.FIELD_CART_TYPE)
print ' cartNumber(): %u / ' % update.padField(PyPAD.TYPE_NOW,PyPAD.FIELD_CART_NUMBER)+update.resolvePadFields("%n",PyPAD.ESCAPE_NONE)
print ' cutNumber(): %u / ' % update.padField(PyPAD.TYPE_NOW,PyPAD.FIELD_CUT_NUMBER)+update.resolvePadFields("%j",PyPAD.ESCAPE_NONE)
print ' length(): %u / ' % update.padField(PyPAD.TYPE_NOW,PyPAD.FIELD_LENGTH)+update.resolvePadFields("%h",PyPAD.ESCAPE_NONE)
try:
print ' year(): %u / ' % update.padField(PyPAD.TYPE_NOW,PyPAD.FIELD_YEAR)+update.resolvePadFields("%y",PyPAD.ESCAPE_NONE)
except TypeError:
print ' year(): None / '+update.resolvePadFields("%Y",PyPAD.ESCAPE_NONE)
print ' groupName(): '+update.padField(PyPAD.TYPE_NOW,PyPAD.FIELD_GROUP_NAME)+' / '+update.resolvePadFields('%g',PyPAD.ESCAPE_NONE)
print ' title(): '+update.padField(PyPAD.TYPE_NOW,PyPAD.FIELD_TITLE)+' / '+update.resolvePadFields('%t',PyPAD.ESCAPE_NONE)
print ' artist(): '+update.padField(PyPAD.TYPE_NOW,PyPAD.FIELD_ARTIST)+' / '+update.resolvePadFields('%a',PyPAD.ESCAPE_NONE)
print ' publisher(): '+update.padField(PyPAD.TYPE_NOW,PyPAD.FIELD_PUBLISHER)+' / '+update.resolvePadFields('%p',PyPAD.ESCAPE_NONE)
print ' composer(): '+update.padField(PyPAD.TYPE_NOW,PyPAD.FIELD_COMPOSER)+' / '+update.resolvePadFields('%m',PyPAD.ESCAPE_NONE)
print ' album(): '+update.padField(PyPAD.TYPE_NOW,PyPAD.FIELD_ALBUM)+' / '+update.resolvePadFields('%l',PyPAD.ESCAPE_NONE)
print ' label(): '+update.padField(PyPAD.TYPE_NOW,PyPAD.FIELD_LABEL)+' / '+update.resolvePadFields('%b',PyPAD.ESCAPE_NONE)
print ' client(): '+update.padField(PyPAD.TYPE_NOW,PyPAD.FIELD_CLIENT)+' / '+update.resolvePadFields('%c',PyPAD.ESCAPE_NONE)
print ' agency(): '+update.padField(PyPAD.TYPE_NOW,PyPAD.FIELD_AGENCY)+' / '+update.resolvePadFields('%e',PyPAD.ESCAPE_NONE)
print ' conductor(): '+update.padField(PyPAD.TYPE_NOW,PyPAD.FIELD_CONDUCTOR)+' / '+update.resolvePadFields('%r',PyPAD.ESCAPE_NONE)
print ' userDefined(): '+update.padField(PyPAD.TYPE_NOW,PyPAD.FIELD_USER_DEFINED)+' / '+update.resolvePadFields('%u',PyPAD.ESCAPE_NONE)
print ' songId(): '+update.padField(PyPAD.TYPE_NOW,PyPAD.FIELD_SONG_ID)+' / '+update.resolvePadFields('%s',PyPAD.ESCAPE_NONE)
print ' outcue(): '+update.padField(PyPAD.TYPE_NOW,PyPAD.FIELD_OUTCUE)+' / '+update.resolvePadFields('%o',PyPAD.ESCAPE_NONE)
print ' description(): '+update.padField(PyPAD.TYPE_NOW,PyPAD.FIELD_DESCRIPTION)+' / '+update.resolvePadFields('%i',PyPAD.ESCAPE_NONE)
print ' externalEventId(): '+update.padField(PyPAD.TYPE_NOW,PyPAD.FIELD_EXTERNAL_EVENT_ID)
print ' externalData(): '+update.padField(PyPAD.TYPE_NOW,PyPAD.FIELD_EXTERNAL_DATA)
print ' externalAnncType(): '+update.padField(PyPAD.TYPE_NOW,PyPAD.FIELD_EXTERNAL_EVENT_ID)
print
else:
print '** NO NOW PLAYING INFO **'
print
if update.hasPadType(PyPAD.TYPE_NEXT):
print '** NEXT PLAYING INFO **'
try:
print ' startDateTime(): '+update.startDateTime(PyPAD.TYPE_NEXT).isoformat(' ')
except AttributeError:
print ' startDateTime(): None'
print ' cartType(): '+update.padField(PyPAD.TYPE_NEXT,PyPAD.FIELD_CART_TYPE)
print ' cartNumber(): %u / ' % update.padField(PyPAD.TYPE_NEXT,PyPAD.FIELD_CART_NUMBER)+update.resolvePadFields("%N",PyPAD.ESCAPE_NONE)
print ' cutNumber(): %u / ' % update.padField(PyPAD.TYPE_NEXT,PyPAD.FIELD_CUT_NUMBER)+update.resolvePadFields("%J",PyPAD.ESCAPE_NONE)
print ' length(): %u / ' % update.padField(PyPAD.TYPE_NEXT,PyPAD.FIELD_LENGTH)+update.resolvePadFields("%H",PyPAD.ESCAPE_NONE)
try:
print ' year(): %u / ' % update.padField(PyPAD.TYPE_NEXT,PyPAD.FIELD_YEAR)+update.resolvePadFields("%Y",PyPAD.ESCAPE_NONE)
except TypeError:
print ' year(): None / '+update.resolvePadFields("%Y",PyPAD.ESCAPE_NONE)
print ' groupName(): '+update.padField(PyPAD.TYPE_NEXT,PyPAD.FIELD_GROUP_NAME)+' / '+update.resolvePadFields('%G',PyPAD.ESCAPE_NONE)
print ' title(): '+update.padField(PyPAD.TYPE_NEXT,PyPAD.FIELD_TITLE)+' / '+update.resolvePadFields('%T',PyPAD.ESCAPE_NONE)
print ' artist(): '+update.padField(PyPAD.TYPE_NEXT,PyPAD.FIELD_ARTIST)+' / '+update.resolvePadFields('%A',PyPAD.ESCAPE_NONE)
print ' publisher(): '+update.padField(PyPAD.TYPE_NEXT,PyPAD.FIELD_PUBLISHER)+' / '+update.resolvePadFields('%P',PyPAD.ESCAPE_NONE)
print ' composer(): '+update.padField(PyPAD.TYPE_NEXT,PyPAD.FIELD_COMPOSER)+' / '+update.resolvePadFields('%M',PyPAD.ESCAPE_NONE)
print ' album(): '+update.padField(PyPAD.TYPE_NEXT,PyPAD.FIELD_ALBUM)+' / '+update.resolvePadFields('%L',PyPAD.ESCAPE_NONE)
print ' label(): '+update.padField(PyPAD.TYPE_NEXT,PyPAD.FIELD_LABEL)+' / '+update.resolvePadFields('%B',PyPAD.ESCAPE_NONE)
print ' client(): '+update.padField(PyPAD.TYPE_NEXT,PyPAD.FIELD_CLIENT)+' / '+update.resolvePadFields('%C',PyPAD.ESCAPE_NONE)
print ' agency(): '+update.padField(PyPAD.TYPE_NEXT,PyPAD.FIELD_AGENCY)+' / '+update.resolvePadFields('%E',PyPAD.ESCAPE_NONE)
print ' conductor(): '+update.padField(PyPAD.TYPE_NEXT,PyPAD.FIELD_CONDUCTOR)+' / '+update.resolvePadFields('%R',PyPAD.ESCAPE_NONE)
print ' userDefined(): '+update.padField(PyPAD.TYPE_NEXT,PyPAD.FIELD_USER_DEFINED)+' / '+update.resolvePadFields('%U',PyPAD.ESCAPE_NONE)
print ' songId(): '+update.padField(PyPAD.TYPE_NEXT,PyPAD.FIELD_SONG_ID)+' / '+update.resolvePadFields('%S',PyPAD.ESCAPE_NONE)
print ' outcue(): '+update.padField(PyPAD.TYPE_NEXT,PyPAD.FIELD_OUTCUE)+' / '+update.resolvePadFields('%O',PyPAD.ESCAPE_NONE)
print ' description(): '+update.padField(PyPAD.TYPE_NEXT,PyPAD.FIELD_DESCRIPTION)+' / '+update.resolvePadFields('%I',PyPAD.ESCAPE_NONE)
print ' externalEventId(): '+update.padField(PyPAD.TYPE_NEXT,PyPAD.FIELD_EXTERNAL_EVENT_ID)
print ' externalData(): '+update.padField(PyPAD.TYPE_NEXT,PyPAD.FIELD_EXTERNAL_DATA)
print ' externalAnncType(): '+update.padField(PyPAD.TYPE_NEXT,PyPAD.FIELD_EXTERNAL_EVENT_ID)
print
else:
print '** NO NEXT PLAYING INFO **'
print
print '******************************************************************'
#
# Create an instance of 'PyPADReceiver'
#
rcvr=PyPAD.Receiver()
#
# Tell it to use the callback
#
rcvr.setCallback(ProcessPad)
#
# Start the receiver, giving it the hostname or IP address and TCP port of
# the target Rivendell system. Once started, all further processing can only
# be done in the callback method!
#
rcvr.start("localhost",PyPAD.PAD_TCP_PORT)