diff options
Diffstat (limited to 'abs/core/LinHES-system/idle.py')
-rwxr-xr-x | abs/core/LinHES-system/idle.py | 310 |
1 files changed, 310 insertions, 0 deletions
diff --git a/abs/core/LinHES-system/idle.py b/abs/core/LinHES-system/idle.py new file mode 100755 index 0000000..40bbb16 --- /dev/null +++ b/abs/core/LinHES-system/idle.py @@ -0,0 +1,310 @@ +#!/usr/bin/python2 + +import argparse, os, re, subprocess, sys, time +from datetime import datetime, date, timedelta + +def msg(cmdargs,msg): + if cmdargs.silent is False: + print "%s" %msg + +def mythshutdownlock_check(cmdargs,cursor): + if (cmdargs.lock): + msg(cmdargs," Checking mythshutdown for lock...") + try: + cursor.execute("select data from settings where value = 'MythShutdownLock'") + results=cursor.fetchone() + except: + return True + lock=results[0] + if int(lock) == 0 : + msg(cmdargs," mythshutdown is NOT locked.") + return True + else: + msg(cmdargs," mythshutdown is locked.") + return False + else: + return True + +def dailywake_check(cmdargs,cursor): + if (cmdargs.daily): + msg(cmdargs," Checking if in a daily wake period...") + dailyWake=False + today = date.today() + now = datetime.now() + try: + cursor.execute("select data from settings where value = 'DailyWakeupStartPeriod1'") + results=cursor.fetchone() + p1Start=datetime.strptime(' '.join([str(today), results[0]]), "%Y-%m-%d %H:%M") + cursor.execute("select data from settings where value = 'DailyWakeupEndPeriod1'") + results=cursor.fetchone() + p1End=datetime.strptime(' '.join([str(today), results[0]]), "%Y-%m-%d %H:%M") + cursor.execute("select data from settings where value = 'DailyWakeupStartPeriod2'") + results=cursor.fetchone() + p2Start=datetime.strptime(' '.join([str(today), results[0]]), "%Y-%m-%d %H:%M") + cursor.execute("select data from settings where value = 'DailyWakeupEndPeriod2'") + results=cursor.fetchone() + p2End=datetime.strptime(' '.join([str(today), results[0]]), "%Y-%m-%d %H:%M") + except: + print "error" + return True + + # Check for time periods that cross midnight + if (p1End < p1Start): + if (now > p1End): + p1End = p1End + timedelta(days=1) + else: + p1Start = p1Start + timedelta(days=-1) + if (p2End < p2Start): + if (now > p2End): + p2End = p2End + timedelta(days=1) + else: + p2Start = p2Start + timedelta(days=-1) + + #Check for one of the daily wakeup periods + if (p1Start != p1End): + if (now >= p1Start and now <= p1End): + msg(cmdargs," Currently in daily wake period 1.") + return False + if (p2Start != p2End): + if (now >= p2Start and now <= p2End): + msg(cmdargs," Currently in daily wake period 2.") + return False + + #Are we about to start a daily wakeup period using the -t TIME var + if (p1Start != p1End): + delta=p1Start-now + if (delta.seconds >= 0 and delta.seconds <= cmdargs.time * 60): + msg(cmdargs," Daily wake period 1 will start in less than %s minutes." %cmdargs.time) + return False + if (p2Start != p2End): + delta=p2Start-now + if (delta.seconds >= 0 and delta.seconds <= cmdargs.time * 60): + msg(cmdargs," Daily wake period 2 will start in less than %s minutes." %cmdargs.time) + return False + + msg(cmdargs," Currently NOT in a daily wake period.") + return True + else: + return True + +def schemalock_check(cmdargs,cursor): + msg(cmdargs," Checking if the schema is locked...") + try: + cursor.execute("select count(*) from schemalock") + results=cursor.fetchone() + except: + return True + schemalock=results[0] + if schemalock == 0: + msg(cmdargs," The schema is NOT locked.") + return True + else: + msg(cmdargs," The schema is locked.") + return False + +def in_use(cmdargs,cursor): + msg(cmdargs," Checking if programs are in use...") + try: + cursor.execute("select count(*) from inuseprograms") + results=cursor.fetchone() + except: + return True + prginuse=results[0] + if prginuse == 0 : + msg(cmdargs," Programs are NOT in use.") + return True + else: + msg(cmdargs," Programs are in use.") + return False + +def job_check(cmdargs,cursor): + msg(cmdargs," Checking jobqueue for active jobs...") + try: + cursor.execute("select count(*) from jobqueue where status between 2 and 5") + results=cursor.fetchone() + except: + return True + jobs=results[0] + if jobs == 0 : + msg(cmdargs," No jobs are active.") + return True + else: + msg(cmdargs," Jobs are active.") + return False + +def upcoming_check(cmdargs,mythBE): + msg(cmdargs," Checking for recordings in the next %s minutes..." %cmdargs.time) + try: + upcoming = mythBE.getUpcomingRecordings() + except: + msg(cmdargs," Could not get upcoming recordings.") + return True + time_diff=10000 + r=0 + for i in upcoming: + r += 1 + if r > 1: + break + show=str(i) + show=show.strip() + showtime=re.split("[-+]\d\d:\d\d",str(i.starttime))[0] + now=time.time() + rec_time=time.strptime( showtime ,"%Y-%m-%d %H:%M:%S" ) + r=time.mktime(rec_time) + time_diff = ( r - now ) / 60 + + if ( time_diff > cmdargs.time) : + msg(cmdargs," No recordings starting in %s minutes." %cmdargs.time) + return True + else: + msg(cmdargs," A recording is starting in %s minutes." %int(time_diff)) + return False + +def mfd_check(cmdargs): + msg(cmdargs," Checking if mythfilldatabase is running...") + with open(os.devnull, "w") as fnull: + mythfilldatabase_ret = subprocess.call(["pidof", "mythfilldatabase"], stdout=fnull) + if mythfilldatabase_ret == 0 : + msg(cmdargs," mythfilldatabase is running.") + return False + else: + msg(cmdargs," mythfilldatabase is NOT running.") + return True + +def mythtvsetup_check(cmdargs): + msg(cmdargs," Checking if mythtv-setup is running...") + with open(os.devnull, "w") as fnull: + mythsetup_ret = subprocess.call(["pidof", "mythtv-setup"], stdout=fnull) + if mythsetup_ret == 0 : + msg(cmdargs," mythtv-setup is running.") + return False + else: + msg(cmdargs," mythtv-setup is NOT running.") + return True + +def mythfe_check(cmdargs,cursor,mythDB): + if ( cmdargs.runningfe ): + msg(cmdargs," Checking for running and playing mythfrontends...") + else: + msg(cmdargs," Checking for playing mythfrontends...") + try: + #frontends = mythDB.getFrontends() #use cursor instead so it doesn't test connection + cursor.execute("select hostname from settings where value = 'FrontendIdleTimeout'") + frontends=cursor.fetchall() + except: + return True + + for i in frontends: + try: + msg(cmdargs," Checking %s's mythfrontend status..." %i) + frontend = mythDB.getFrontend(''.join(i)) + if ( cmdargs.runningfe ): + msg(cmdargs," %s's mythfrontend is RUNNING." %i) + return False + location = frontend.sendQuery('Location') + if ( location.startswith('Playback ') ): + msg(cmdargs," %s's mythfrontend is PLAYING." %i) + return False + else: + msg(cmdargs," %s's mythfrontend is NOT playing." %i) + except: + msg(cmdargs," Could not connect to %s's mythfrontend." %i) + + if ( cmdargs.runningfe ): + msg(cmdargs," No mythfrontends are running or playing.") + else: + msg(cmdargs," No mythfrontends are playing.") + + return True + +def usage(): + line = ''' + idle.py checks if the system is idle. + Use idle.py -h to see options. + + idle.py checks these parts of the system in this order to + determine if it is idle: + - (option -l) mythshutdown is locked return busy + - (option -d) In a daily wake period or + about to start a daily wake period return busy + checks the next 15 minutes. -t TIME changes time + - schema is locked return busy + - There are in use programs return busy + - There are active jobs in the job queue return busy + - mythfilldatabase is running return busy + - mythtv-setup is running return busy + - There are upcoming recordings return busy + checks the next 15 minutes. -t TIME changes time + - mythfrontends playing back a recording or video + - (option -r) mythfrontends running + + idle.py stops checking and returns false (busy) when the first busy is found. + ''' + print line + sys.exit(0) + +def main(args=[False]): + parser = argparse.ArgumentParser() + parser.add_argument('-d', '--daily', action='store_true', help='Include daily wake & about to start wake in system busy. (default: daily wake & about to start wake is system idle)') + parser.add_argument('-l', '--lock', action='store_true', help='Include mythshutdown lock in system busy. (default: mythshutdown lock is system idle)') + parser.add_argument('-r', '--runningfe', action='store_true', help='Include running mythfrontends in system busy. (default: running mythfrontends are system idle)') + parser.add_argument('-s', '--silent', action='store_true', help='Run without printing output. Recommended for use in cron jobs or scripts.') + parser.add_argument('-t', '--time', type=int, default=15, help='Minutes of idle time needed to return idle for upcoming recordings and daily wake.') + parser.add_argument('-u', '--usage', action='store_true', help='Print usage instructions.') + if args[0] is False: + cmdargs = parser.parse_args() + else: + cmdargs = parser.parse_args(args) + + if cmdargs.usage: + usage() + idle=True + msg(cmdargs,"Checking system idle...") + + try: + from MythTV import MythDB + mythDB = MythDB() + cursor = mythDB.cursor() + db_conn=True + except: + msg(cmdargs,"Couldn't connect to MythTV database.") + db_conn=False + + try: + from MythTV import MythBE + mythBE = MythBE() + be_conn=True + except: + msg(cmdargs,"Couldn't connect to MythTV backend.") + be_conn=False + + if ( db_conn ): + if (mythshutdownlock_check(cmdargs,cursor) and dailywake_check(cmdargs,cursor) and schemalock_check(cmdargs,cursor) and in_use(cmdargs,cursor) and job_check(cmdargs,cursor)): + idle=True + else: + idle=False + + if ( be_conn and idle ): + if (mfd_check(cmdargs) and mythtvsetup_check(cmdargs) and upcoming_check(cmdargs,mythBE)): + idle=True + else: + idle=False + + if ( db_conn and idle ): + if ( mythfe_check(cmdargs,cursor,mythDB) ): + idle=True + else: + idle=False + + if ( idle ): + msg(cmdargs,"System is idle.") + else: + msg(cmdargs,"System is busy.") + return idle + +if __name__ == "__main__": + idle=main() + if ( idle ): + exit(0) + else: + exit(1) |