diff options
-rwxr-xr-x | abs/core/LinHES-system/PKGBUILD | 10 | ||||
-rwxr-xr-x | abs/core/LinHES-system/idle.py | 310 | ||||
-rwxr-xr-x | abs/core/LinHES-system/myth_mtc.py | 107 | ||||
-rwxr-xr-x | abs/core/LinHES-system/mythwelcome-config.py | 2 | ||||
-rw-r--r-- | abs/core/LinHES-system/system.install | 3 |
5 files changed, 322 insertions, 110 deletions
diff --git a/abs/core/LinHES-system/PKGBUILD b/abs/core/LinHES-system/PKGBUILD index 1edffb8..8bb0e76 100755 --- a/abs/core/LinHES-system/PKGBUILD +++ b/abs/core/LinHES-system/PKGBUILD @@ -1,6 +1,6 @@ pkgname=LinHES-system pkgver=8.1 -pkgrel=13 +pkgrel=14 arch=('i686' 'x86_64') install=system.install pkgdesc="Everything that makes LinHES an automated system" @@ -23,7 +23,7 @@ binfiles="LinHES-start optimize_mythdb.py myth_mtc.py misc_recent_recordings.pl misc_status_config.py misc_status_info.sh misc_upcoming_recordings.pl misc_which_recorder.pl change_channel.sh change_channel_wrapper.sh stop_xss.sh - be_check.py checkXFSfrag.sh find_orphans.py idle.sh xwin_find.sh + be_check.py checkXFSfrag.sh find_orphans.py idle.py xwin_find.sh linhes_update.sh linhes_update2.sh myth2mkv myth2mp3 ripD_eject.sh mythwelcome-config.py mythwelcome-set-alarm.sh mythwelcome-test-wakeup.sh" @@ -79,7 +79,7 @@ md5sums=('7ab2a2c643d2b286811d8303d08982ad' 'de32a1c50101265dd7f6ca5037f7a26a' '301884fb60521627fffd1160b2cf5181' '76b2637cac0452b3acdbeeb4e8a5474b' - '22807bd1e37d2a07bc0bd3f2a9fd2bb4' + '6d473cfc5c8e2ffedbd894807824d56f' 'dc3eef2a624754e16805d72bbe488b67' '617af86b901538817ebdcaf646248dc5' '542e670e78d117657f93141e9689f54d' @@ -117,14 +117,14 @@ md5sums=('7ab2a2c643d2b286811d8303d08982ad' '8b0298f70f97cc1dc2a58b9a73c64bd3' '911b0fbc8d9178dac1a193346c9decaf' '34fc1f58ad1eabf4eff4979d420760c0' - 'c3ada01d3a739abe3f920b02d4ea3f6e' + '1118e7982ba77cb5be9b2391b7cdfd38' 'a94fe6d980f4b810f2e2ae5352084b39' '2c56266a79d058bf01f0de19c2cd042a' 'c27d3fdf59b211f9d3cd76a81f6257dc' '503df99218373dfc75e7e7f5e449a44e' '4a1fda884dcd7d65fb2690fbdbd92a83' '2b7fe3b57592823a4c7e3ec132dcb7f4' - '92950f0ffb1faf1ed64c6be2b8fbc3f6' + '20dd97b614cab2454794416a3601c497' '95c092f67036a361ef7a57436f44332e' '410795ef9039e4c6c0484e706ecfd567' 'eb879fee9603a05d5420d4ce8ed9e450' 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) diff --git a/abs/core/LinHES-system/myth_mtc.py b/abs/core/LinHES-system/myth_mtc.py index 7847313..c33a888 100755 --- a/abs/core/LinHES-system/myth_mtc.py +++ b/abs/core/LinHES-system/myth_mtc.py @@ -6,6 +6,7 @@ import socket import os import datetime,time import shlex +import idle try: from MythTV import MythBE @@ -21,9 +22,7 @@ def get_timestamp(): date = (now.strftime('%Y-%m-%d %H:%M')) return date - def optimize(): - try: cursor = mythtv.db.cursor() cursor.execute("SHOW tables") @@ -39,96 +38,6 @@ def optimize(): cmd= "%s table %s" %(op,ctable) cursor.execute(cmd) - -def upcoming_check(): - print " Checking for upcoming shows" - try: - upcoming = mythtv.getUpcomingRecordings() - except: - return True - try: - show=str(upcoming[0]) - show=show.strip() - showtime=show.partition("(")[2].strip(")") - now=time.time() - rec_time=time.strptime( showtime ,"%Y-%m-%d %H:%M:%S" ) - r=time.mktime(rec_time) - time_diff= ( r - now ) / 60 - except: - time_diff=100 - show="No show" - if ( time_diff > 30) : - return True - else: - print " %s is upcoming in %s" %(show,time_diff) - return False - - -def schemalock_check(): - print " Checking if schema is locked" - try: - c = mythtv.db.cursor() - c.execute("select count(*) from schemalock") - results=c.fetchone() - schemalock=results[0] - except: - return True - - if schemalock == 0: - return True - else: - print " schema is locked" - return False - -def job_check(): - print " Checking jobqueue" - try: - c = mythtv.db.cursor() - c.execute("select count(*) from jobqueue where status = 4") - results=c.fetchone() - except: - return True - jobs= results[0] - if jobs == 0 : - return True - else: - print " jobs are running" - return False - - -def in_use(): - print " Checking if programs are in use" - try: - c = mythtv.db.cursor() - c.execute("select count(*) from inuseprograms") - results=c.fetchone() - except: - return True - prginuse=results[0] - if prginuse == 0 : - return True - else: - print " Programs in use" - return False - -def mfd_check(): - print " Checking is mythfilldatabase is running" - ps = subprocess.Popen("ps ax -o pid= -o args= ", shell=True, stdout=subprocess.PIPE) - ps_pid = ps.pid - output = ps.stdout.read() - ps.stdout.close() - ps.wait() - proc_name="mythfilldatabase" - for line in output.split("\n"): - res = re.findall("(\d+) (.*)", line) - if res: - pid = int(res[0][0]) - if proc_name in res[0][1] and pid != os.getpid() and pid != ps_pid: - print " mythfilldatabase is running" - return False - - return True - def bail_if_another_is_running(): cmd = shlex.split("pgrep -u {} -f {}".format(os.getuid(), __file__)) pids = subprocess.check_output(cmd).strip().split('\n') @@ -138,19 +47,9 @@ def bail_if_another_is_running(): __file__, " ".join(pids)) raise SystemExit(1) - -def idle_check(): - print "\n%s Checking Idle" %(get_timestamp()) - if ( upcoming_check() and schemalock_check() and job_check() and in_use() and mfd_check() ): - idle=True - print "\n%s Myth is idle" %(get_timestamp()) - else: - idle=False - print "\n%s Myth is NOT idle" %(get_timestamp()) - return idle - def run_stuff(): - if idle_check(): + print "\n%s" %get_timestamp() + if idle.main(): print "\n#######################################" print "\n%s Running Optimize" %(get_timestamp()) optimize() diff --git a/abs/core/LinHES-system/mythwelcome-config.py b/abs/core/LinHES-system/mythwelcome-config.py index 5ab24b0..8cf78c2 100755 --- a/abs/core/LinHES-system/mythwelcome-config.py +++ b/abs/core/LinHES-system/mythwelcome-config.py @@ -24,4 +24,4 @@ if mythdb.settings[localhostname].idleTimeoutSecs == u'0': mythdb.settings.NULL.WakeupTimeFormat = u'yyyy-MM-ddThh:mm:ss' mythdb.settings.NULL.SetWakeuptimeCommand = u'/usr/bin/mythshutdown --setwakeup $time' mythdb.settings.NULL.ServerHaltCommand = u'/usr/bin/mythshutdown --shutdown' -mythdb.settings.NULL.preSDWUCheckCommand = u'/usr/LH/bin/idle.sh -s -m -r' +mythdb.settings.NULL.preSDWUCheckCommand = u'/usr/LH/bin/idle.py -s -d -l -r' diff --git a/abs/core/LinHES-system/system.install b/abs/core/LinHES-system/system.install index 9f8aa45..6975070 100644 --- a/abs/core/LinHES-system/system.install +++ b/abs/core/LinHES-system/system.install @@ -13,6 +13,9 @@ post_install() { rm -f /etc/cron.daily/myth_mtc fi + #run mythwelcome-config.py to update shutdown check to use idle.py + /usr/LH/bin/mythwelcome-config.py + sv restart msg_daemon } |