summaryrefslogtreecommitdiffstats
path: root/linhes/linhes-system/idle.py
diff options
context:
space:
mode:
Diffstat (limited to 'linhes/linhes-system/idle.py')
-rwxr-xr-xlinhes/linhes-system/idle.py379
1 files changed, 379 insertions, 0 deletions
diff --git a/linhes/linhes-system/idle.py b/linhes/linhes-system/idle.py
new file mode 100755
index 0000000..778677d
--- /dev/null
+++ b/linhes/linhes-system/idle.py
@@ -0,0 +1,379 @@
+#!/usr/bin/python
+
+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," %s programs are in use." %prginuse)
+ cursor.execute("select recusage,chanid,lastupdatetime from inuseprograms")
+ results=cursor.fetchall()
+ for i in results:
+ msg(cmdargs," %s - %s - %s" %(i[0],i[1],i[2]))
+ 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 userlogins_check(cmdargs):
+ if (cmdargs.logins):
+ u=False
+ msg(cmdargs," Checking for users logged in...")
+ users=subprocess.check_output("who")
+ names=([x.split() for x in users.splitlines()])
+ for i in names:
+ if (i[0] == "mythtv" and i[4] == "(:0)"):
+ msg(cmdargs," Ignoring %s %s" %(i[0],i[4]))
+ else:
+ msg(cmdargs," User logged in: %s %s" %(i[0],i[4]))
+ u=True
+ if u:
+ return False
+ else:
+ return True
+ else:
+ return True
+
+def sambafiles_check(cmdargs):
+ if (cmdargs.sambafiles):
+ msg(cmdargs," Checking if Samba files are in use...")
+ try:
+ smbstatus=subprocess.check_output(["smbstatus", "-L"])
+ except:
+ smbstatus="No locked files"
+ if "No locked files" in smbstatus:
+ msg(cmdargs," Samba files are NOT in use.")
+ return True
+ else:
+ msg(cmdargs," Samba files are in use.")
+ return False
+ else:
+ return True
+
+def mythfe_check(cmdargs,cursor,mythDB):
+ #checks to see if a frontend is considered idle
+ # True means FE is idle
+
+ if ( cmdargs.runningfe ):
+ msg(cmdargs," Checking for running and playing mythfrontends...")
+ else:
+ msg(cmdargs," Checking for playing mythfrontends...")
+ try:
+ cursor.execute("select distinct hostname from settings where hostname is not null;")
+ 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 == "standbymode":
+ msg(cmdargs," %s's mythfrontend is in Standby Mode." %i)
+ continue
+
+ if ( location.startswith('Playback ') ):
+ msg(cmdargs," %s's mythfrontend is PLAYING." %i)
+ return False
+ else:
+ msg(cmdargs," %s's mythfrontend is NOT playing." %i)
+
+ if '.xml' in location or 'mainmenu' in location:
+ msg(cmdargs," %s's mythfrontend is in MENUS." %i)
+ else:
+ #FE is not in menus, so it must be active in a plugin
+ msg(cmdargs," %s's mythfrontend is NOT in menus." %i)
+ return False
+ except:
+ msg(cmdargs," Could not connect to %s's mythfrontend." %i)
+
+ if ( cmdargs.runningfe ):
+ msg(cmdargs," mythfrontends are not running or playing or are in menus.")
+ else:
+ msg(cmdargs," mythfrontends are not playing or are in menus.")
+
+ 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 -g) users are logged in return busy
+ ignores mythtv (:0) for busy
+ - (option -f) Samba files are in use return busy
+ - (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
+ - (option -r) mythfrontends running return busy
+ - mythfrontends playing back a recording or video return busy
+ - mythfrontends not in menus return busy
+
+ 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('-g', '--logins', action='store_true', help='Include user logins in system busy. Ignores mythtv (:0) in system busy.')
+ parser.add_argument('-f', '--sambafiles', action='store_true', help='Include Samba files in use in system busy.')
+ 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...")
+
+ if (userlogins_check(cmdargs)):
+ idle = True
+ else:
+ idle = False
+
+ if (idle and sambafiles_check(cmdargs)):
+ idle = True
+ else:
+ idle = False
+
+ 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 and idle ):
+ 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)