#!/usr/bin/env python3 # -*- coding: utf-8 -*- ############################################################################## # Test that mythbackend is present and responding to API calls. # # This program is Python 2 and Python 3 compatible. For MythTV <= v30, use # Python 2. For MythTV >= v31, use Python 3. To change the Python version # being used, change the #! line at the top of the file so the last word is # "python3" or "python2". # # Author: J S Worthington ############################################################################## from __future__ import print_function import argparse import sys py_version = '3' if sys.version_info.major == 2: py_version = '2' if py_version == '2': try: from enum import IntEnum except: print('Please install the Python 2 enum34 package.') print('In Ubuntu, do "sudo apt install python-enum34".') exit(9) else: from enum import IntEnum try: from MythTV.services_api import send as api except: print('Please install the MythTV services_api version compatible with your MythTV backend.') print('In Ubuntu, to get the current version of the MythTV services_api, do "sudo apt install libmyth-python".') print('If you still get this message after installing libmyth-python, do "sudo apt install python-future python-requests".') raise exit(9) """ Version 1.0: - Initial release. Version 1.1 2021-10-11 - Also support Python 2. - Remove some more redundant code. Version 1.2 2021-10-12 - Fix import of enum. - Fix import of services_api for non-MythTV boxes. Version 1.3 2021-10-12 - Notify about Python 2 libmyth-python dependencies that must be manually installed as the packages do not list them. Version 1.4 2021-10-17 - Only attempt to get settings from the database if the -n and -p options have not been used. - Eliminate text message output - just use result codes unless there is an install problem. """ VERSION = '1.4' HOST = 'localhost' PORT = 6544 class RecStatus(IntEnum): Pending = -15 Failing = -14 #OtherRecording = -13 (obsolete) #OtherTuning = -12 (obsolete) MissedFuture = -11 Tuning = -10 Failed = -9 TunerBusy = -8 LowDiskSpace = -7 Cancelled = -6 Missed = -5 Aborted = -4 Recorded = -3 Recording = -2 WillRecord = -1 Unknown = 0 DontRecord = 1 PreviousRecording = 2 CurrentRecording = 3 EarlierShowing = 4 TooManyRecordings = 5 NotListed = 6 Conflict = 7 LaterShowing = 8 Repeat = 9 Inactive = 10 NeverRecord = 11 Offline = 12 #OtherShowing = 13 (obsolete) ############################################################################## # Main ############################################################################## host = HOST port = PORT try: import MythTV mythtv_bindings_ok = True except: mythtv_bindings_ok = False parser = argparse.ArgumentParser( description='Test that mythbackend is running and responding to API calls (Version: ' + VERSION + ')', formatter_class=lambda prog: argparse.HelpFormatter(prog, max_help_position=15) ) parser.add_argument('-V', '--version', dest='version', default=False, action='store_true', help='display the version number and exit') parser.add_argument('-n', '--host', action='store', help='MythTV backend hostname or IP address (default: '+host+')') parser.add_argument('-p', '--port', type=int, action='store', help='MythTV backend API port number (default: '+str(port)+')') args = parser.parse_args() if args.version: print('Version '+VERSION) exit(1) if args.port == None and args.host == None and mythtv_bindings_ok: try: db = MythTV.MythDB() dbc = db.cursor() rows = dbc.execute("select data,hostname from settings where value='BackendStatusPort'") if rows != 0: row = dbc.fetchone() args.port = int(row[0]) args.host = row[1] except: pass if args.port != None: port = args.port if args.host != None: host = args.host #print('host='+host, 'port='+str(port)) backend = api.Send(host=host, port=port) try: resp_dict = backend.send(endpoint='Dvr/GetUpcomingList') except RuntimeError: #print('Connection to backend failed - is mythbackend running?') exit(2) if list(resp_dict.keys())[0] in ['Abort', 'Warning']: #print('GetUpcomingList failed') exit(3) pending_count = int(resp_dict['ProgramList']['Count']) if pending_count == 0: #print('No recordings scheduled!') exit(4) exit(0) # Example of the dictionary data returned by Dvr/GetUpcomingList API call via Utilities.py: #{u'Category': u'Education/Science/Factual', u'SubProps': u'0', u'CatType': u'series', u'Title': u'24 Hours In A&E', u'LastModified': u'2017-04-18T14:39:29Z', u'Stars': u'0', u'Episode': u'0', u'EndTime': u'2017-04-18T19:25:00Z', u'Channel': {u'Programs': [], u'ChanFilters': u'', u'UseEIT': u'false', u'Visible': u'true', u'IconURL': u'', u'SourceId': u'6', u'FineTune': u'0', u'Format': u'Default', u'ATSCMajorChan': u'0', u'MplexId': u'0', u'ChanNum': u'4074', u'ChanId': u'10074', u'CommFree': u'false', u'CallSign': u'KNOWLGE', u'InputId': u'0', u'DefaultAuth': u'', u'ServiceId': u'1059', u'FrequencyId': u'', u'ChannelName': u'BBC Knowledge', u'ATSCMinorChan': u'0', u'XMLTVID': u'documentary.sky.co.nz'}, u'SeriesId': u'1490837', u'Repeat': u'false', u'Description': u'54-year-old epileptic Mike arrives in minors with a bandage round his jaw after falling face first onto a pavement.', u'Season': u'0', u'HostName': u'mypvr', u'ProgramFlags': u'0', u'SubTitle': u'Always On My Mind', u'VideoProps': u'0', u'TotalEpisodes': u'0', u'Artwork': {u'ArtworkInfos': []}, u'Recording': {u'Status': u'-1', u'RecordedId': u'0', u'EncoderName': u'SAT>IP 1.1 (90)', u'RecGroup': u'CRW and JSW', u'DupMethod': u'8', u'RecordId': u'11099', u'LastModified': u'2017-04-18T14:39:29Z', u'HostName': u'mypvr', u'StartTs': u'2017-04-18T18:35:00Z', u'FileName': u'', u'Priority': u'0', u'EncoderId': u'90', u'Profile': u'Default', u'StorageGroup': u'Default', u'EndTs': u'2017-04-18T19:30:00Z', u'DupInType': u'15', u'RecType': u'4', u'PlayGroup': u'Default', u'FileSize': u'0'}, u'Cast': {u'CastMembers': []}, u'Inetref': u'', u'Airdate': u'', u'AudioProps': u'0', u'FileName': u'', u'ProgramId': u'', u'FileSize': u'0', u'StartTime': u'2017-04-18T18:35:00Z'}