From 5bb2211ceadbd1e56c643a7e899ee3612f7de810 Mon Sep 17 00:00:00 2001 From: Fred Gleason Date: Thu, 11 Nov 2021 16:35:11 -0500 Subject: [PATCH] 2021-11-11 Fred Gleason * Added a 'ListCarts()' method to the 'rivwebpyapi' API. Signed-off-by: Fred Gleason --- ChangeLog | 2 + apis/rivwebpyapi/api/rivwebpyapi.py | 87 ++++++++++++++++++++++ apis/rivwebpyapi/tests/Makefile.am | 3 +- apis/rivwebpyapi/tests/list_carts.py | 107 +++++++++++++++++++++++++++ web/rdxport/carts.cpp | 5 +- 5 files changed, 202 insertions(+), 2 deletions(-) create mode 100755 apis/rivwebpyapi/tests/list_carts.py diff --git a/ChangeLog b/ChangeLog index 8e980e46..3973c98d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -22607,3 +22607,5 @@ 2021-11-10 Fred Gleason * Added 'all' to the set of available cart types in 'web/tests/listcarts.html'. +2021-11-11 Fred Gleason + * Added a 'ListCarts()' method to the 'rivwebpyapi' API. diff --git a/apis/rivwebpyapi/api/rivwebpyapi.py b/apis/rivwebpyapi/api/rivwebpyapi.py index 07ad5443..31860636 100755 --- a/apis/rivwebpyapi/api/rivwebpyapi.py +++ b/apis/rivwebpyapi/api/rivwebpyapi.py @@ -18,6 +18,8 @@ # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # +import sys + import datetime from datetime import timedelta import requests @@ -195,6 +197,91 @@ class rivwebpyapi(object): self.__connection_username=username self.__connection_password=password + def ListCarts(self,group_name='',filter_string='',cart_type='all', + include_cuts=False): + """ + Returns a list of Rivendell carts (dictionary) + + Takes the following arguments: + + group_name - Filter returns to only include carts belonging to + the specified group. Default is to not filter by + group. (string) + + filter_string - Filter returns to only include carts matching the + filter string. Default is not to filter by phrase. + (string) + + cart_type - Filter returns to only include carts matching the + specified type. Recognized values are 'all', 'audio' + or 'macro'. Default is 'all'. (string) + + include_cuts - Include cut information in the return. Default is + False. (boolean) + """ + + # + # Build the WebAPI arguments + # + postdata={ + 'COMMAND': '6', + 'LOGIN_NAME': self.__connection_username, + 'PASSWORD': self.__connection_password, + 'GROUP_NAME': str(group_name), + 'FILTER': filter_string, + 'TYPE': cart_type.lower(), + 'INCLUDE_CUTS': '0' + } + if(include_cuts): + postdata['INCLUDE_CUTS']='1' + + # + # Fetch the XML + # + r=requests.post(self.__connection_url,data=postdata) + if(r.status_code!=requests.codes.ok): + r.raise_for_status() + + # + # Generate the output dictionary + # + fields={ + 'number': 'integer', + 'type': 'string', + 'groupName': 'string', + 'title': 'string', + 'artist': 'string', + 'album': 'string', + 'year': 'integer', + 'label': 'string', + 'client': 'string', + 'agency': 'string', + 'publisher': 'string', + 'composer': 'string', + 'conductor': 'string', + 'userDefined': 'string', + 'usageCode': 'integer', + 'forcedLength': 'string', + 'averageLength': 'string', + 'lengthDeviation': 'string', + 'averageSegueLength': 'string', + 'averageHookLength': 'string', + 'minimumTalkLength': 'string', + 'maximumTalkLength': 'string', + 'cutQuantity': 'integer', + 'lastCutPlayed': 'integer', + 'enforceLength': 'boolean', + 'asyncronous': 'boolean', + 'owner': 'string', + 'metadataDatetime': 'datetime', + 'songId': 'string' + } + handler=RivWebPyApi_ListHandler(base_tag='cart',fields=fields) + print(r.text) + xml.sax.parseString(r.text,handler) + + return handler.output() + def ListGroup(self,group_name): """ Returns a list of Rivendell groups (dictionary). diff --git a/apis/rivwebpyapi/tests/Makefile.am b/apis/rivwebpyapi/tests/Makefile.am index 5a1972ed..99355ee0 100644 --- a/apis/rivwebpyapi/tests/Makefile.am +++ b/apis/rivwebpyapi/tests/Makefile.am @@ -20,7 +20,8 @@ ## ## Use automake to process this into a Makefile.in -EXTRA_DIST = list_group.py\ +EXTRA_DIST = list_carts.py\ + list_group.py\ list_groups.py\ list_log.py\ list_logs.py\ diff --git a/apis/rivwebpyapi/tests/list_carts.py b/apis/rivwebpyapi/tests/list_carts.py new file mode 100755 index 00000000..b3cfc9c9 --- /dev/null +++ b/apis/rivwebpyapi/tests/list_carts.py @@ -0,0 +1,107 @@ +#!%PYTHON_BANGPATH% + +# list_carts.py +# +# RivWebPyApi test script for Rivendell +# +# Test the ListLogs Web API call +# +# (C) Copyright 2021 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. +# + +import getpass +import rivwebpyapi +import sys + +url=''; +username='' +password='' +cart_type='all' +include_cuts=False +group_name='' +filter_string='' + +# +# Get login parameters +# +usage='list_carts --url= --username= [--password=] [--audio-only] [--macro-only] [--include-cuts] [--group-name=] [--filter-string=]' +for arg in sys.argv: + f0=arg.split('=') + if(len(f0)==1): + if(f0[0]=='--audio-only'): + cart_type='audio' + if(f0[0]=='--macro-only'): + cart_type='macro' + if(f0[0]=='--include-cuts'): + include_cuts=True + if(len(f0)==2): + if(f0[0]=='--url'): + url=f0[1] + if(f0[0]=='--username'): + username=f0[1] + if(f0[0]=='--password'): + password=f0[1] + if(f0[0]=='--group-name'): + group_name=f0[1] + if(f0[0]=='--filter-string'): + filter_string=f0[1] +if(not password): + password=getpass.getpass() +if((not url)or(not username)): + print(usage) + sys.exit(1) + +# +# Get the cart list +# +webapi=rivwebpyapi.rivwebpyapi(url=url,username=username,password=password) +carts=webapi.ListCarts(group_name=group_name,filter_string=filter_string, + cart_type=cart_type,include_cuts=include_cuts) + +# +# Display the cart list +# +for cart in carts: + print('number: '+str(cart['number'])) + print('type: '+str(cart['type'])) + print('groupName: '+str(cart['groupName'])) + print('title: '+str(cart['title'])) + print('artist: '+str(cart['artist'])) + print('album: '+str(cart['album'])) + print('year: '+str(cart['year'])) + print('label: '+str(cart['label'])) + print('client: '+str(cart['client'])) + print('agency: '+str(cart['agency'])) + print('publisher: '+str(cart['publisher'])) + print('composer: '+str(cart['composer'])) + print('conductor: '+str(cart['conductor'])) + print('userDefined: '+str(cart['userDefined'])) + print('usageCode: '+str(cart['usageCode'])) + print('forcedLength: '+str(cart['forcedLength'])) + print('averageLength: '+str(cart['averageLength'])) + print('lengthDeviation: '+str(cart['lengthDeviation'])) + print('averageSegueLength: '+str(cart['averageSegueLength'])) + print('averageHookLength: '+str(cart['averageHookLength'])) + print('minimumTalkLength: '+str(cart['minimumTalkLength'])) + print('maximumTalkLength: '+str(cart['maximumTalkLength'])) + print('cutQuantity: '+str(cart['cutQuantity'])) + print('lastCutPlayed: '+str(cart['lastCutPlayed'])) + print('enforceLength: '+str(cart['enforceLength'])) + print('asyncronous: '+str(cart['asyncronous'])) + print('owner: '+str(cart['owner'])) + print('metadataDatetime: '+str(cart['metadataDatetime'])) + print('songId: '+str(cart['songId'])) + print('') diff --git a/web/rdxport/carts.cpp b/web/rdxport/carts.cpp index 6cf58a26..7c9cc37e 100644 --- a/web/rdxport/carts.cpp +++ b/web/rdxport/carts.cpp @@ -174,7 +174,10 @@ void Xport::ListCarts() printf("Status: 200\n\n"); printf("\n"); printf("\n"); - printf("%s\n",(const char *)RDCart::xml(q,include_cuts,true).toUtf8()); + QByteArray data=RDCart::xml(q,include_cuts,true).toUtf8(); + // printf("%s\n",RDCart::xml(q,include_cuts,true).toUtf8().constData()); + fwrite(data,1,data.size(),stdout); + rda->syslog(LOG_NOTICE,"xml size: %d",data.size()); printf("\n"); delete q; Exit(0);