mythtv-scripts/python/mythremctl.py
2010-12-07 04:38:11 -05:00

213 lines
6.5 KiB
Python
Executable File

#!/usr/bin/env python
from MythTV import MythDB, MythError, MythLog, Frontend
from datetime import datetime, timedelta
from curses import wrapper, ascii
from time import sleep
import sys, socket, curses, re
#note for ticket, on-screen-keyboard remotely does not have focus
MythLog._setlevel('none')
frontend = None
rplaytype = re.compile('Playback ([a-zA-Z]+)')
rrecorded = re.compile('Playback ([a-zA-Z]+) ([\d:]+) of ([\d:]+) ([-0-9\.]+x) (\d*) ([0-9-T:]+)')
rlivetv = rrecorded
rvideo = re.compile('Playback [a-zA-Z]+ ([\d:]+) ([-0-9\.]+x) .*/(.*) \d+ [\.\d]+')
rrname = re.compile('\d+ [0-9-T:]+ (.*)')
rlname = re.compile('\d+ [0-9-T: ]+ (.*)')
def align(side, window, y, string, flush=0):
w = window.getmaxyx()[1]-1
if len(string) > w:
string = string[:w]
if side == 0:
x = 1
elif side == 1:
x = (w-len(string))/2+1
elif side == 2:
x = w-len(string)
window.addstr(y,x,string)
def query_time(w, _dat=[0]):
if _dat[0] == 0:
ltime = datetime.now()
fetime = frontend.getTime()
_dat[0] = fetime - ltime
time = datetime.now()+_dat[0]
w.erase()
w.border(curses.ACS_VLINE, curses.ACS_VLINE,
curses.ACS_HLINE, curses.ACS_HLINE,
curses.ACS_ULCORNER, curses.ACS_TTEE,
curses.ACS_LTEE, curses.ACS_RTEE)
align(1,w,1,time.strftime('%H:%M:%S'))
w.noutrefresh()
def query_load(w, _dat=[0]):
if _dat[0] == 0:
_dat[0] = datetime.now()
now = datetime.now()
if _dat[0] > now:
return
_dat[0] = now+timedelta(seconds=5)
loads = frontend.getLoad()
w.erase()
w.border(curses.ACS_VLINE, curses.ACS_VLINE,
curses.ACS_HLINE, curses.ACS_HLINE,
curses.ACS_LTEE, curses.ACS_RTEE,
curses.ACS_LTEE, curses.ACS_RTEE)
align(0,w,2,'loads')
align(2,w,1,' 1: {0:0.2f}'.format(loads[0]))
align(2,w,2,' 5: {0:0.2f}'.format(loads[1]))
align(2,w,3,'15: {0:0.2f}'.format(loads[2]))
w.noutrefresh()
def query_loc(w, _dat=[0]):
if _dat[0] == 0:
_dat[0] = datetime.now()
now = datetime.now()
if _dat[0] > now:
return
_dat[0] = now+timedelta(seconds=5)
loc = frontend.sendQuery('location')
pb = rplaytype.match(loc)
w.erase()
w.border(curses.ACS_VLINE, curses.ACS_VLINE,
curses.ACS_HLINE, curses.ACS_HLINE,
curses.ACS_TTEE, curses.ACS_URCORNER,
curses.ACS_BTEE, curses.ACS_LRCORNER)
if pb:
if pb.group(1) == 'Video':
pb = rvideo.match(loc)
align(0,w,1,' Playback: %s' % pb.group(3))
align(0,w,2,' %s @ %s' % (pb.group(1),pb.group(2)))
else:
pb = rrecorded.match(loc)
if pb.group(1) == 'Recorded':
show = frontend.sendQuery('recording %s %s' \
% (pb.group(5),pb.group(6)))
name = rrname.match(show).group(1)
align(0,w,1,' Playback: %s' % name)
elif pb.group(1) == 'LiveTV':
show = frontend.sendQuery('liveTV %s' % pb.group(5))
name = rlname.match(show).group(1)
align(0,w,1,' LiveTV: %s - %s' % (pb.group(5),name))
align(0,w,2,' %s of %s @ %s' \
% (pb.group(2),pb.group(3),pb.group(4)))
else:
align(0,w,1,' '+loc)
w.noutrefresh()
def query_mem(w, _dat=[0]):
if _dat[0] == 0:
_dat[0] = datetime.now()
now = datetime.now()
if _dat[0] > now:
return
_dat[0] = now+timedelta(seconds=15)
mem = frontend.getMemory()
w.erase()
w.border(curses.ACS_VLINE, curses.ACS_VLINE,
curses.ACS_HLINE, curses.ACS_HLINE,
curses.ACS_LTEE, curses.ACS_RTEE,
curses.ACS_LLCORNER, curses.ACS_BTEE)
align(0,w,1,'phy:')
align(0,w,2,'swp:')
align(2,w,1,"%sM/%sM" % (mem['freemem'],mem['totalmem']))
align(2,w,2,"%sM/%sM" % (mem['freeswap'],mem['totalswap']))
w.noutrefresh()
def main(w):
curses.halfdelay(10)
frontend.connect()
y,x = w.getmaxyx()
mem = w.derwin(4,20,9,0)
query_mem(mem)
load = w.derwin(5,20,5,0)
query_load(load)
conn = w.derwin(4,20,2,0)
align(2,conn,1,frontend.host)
align(2,conn,2,"%s:%d" % frontend.socket.getpeername())
conn.border(curses.ACS_VLINE, curses.ACS_VLINE,
curses.ACS_HLINE, curses.ACS_HLINE,
curses.ACS_LTEE, curses.ACS_RTEE,
curses.ACS_LTEE, curses.ACS_RTEE)
time = w.derwin(3,20,0,0)
query_time(time)
loc = w.derwin(13,x-20,0,19)
loc.timeout(1)
while True:
a = None
s = None
try:
query_time(time)
query_load(load)
query_loc(loc)
query_mem(mem)
align(1,w,0,' MythFrontend Remote Socket Interface ')
curses.doupdate()
a = w.getch()
curses.flushinp()
frontend.key[a]
except KeyboardInterrupt:
break
except EOFError:
break
except MythError:
print "Remote side closed connection..."
break
except:
raise
if __name__ == '__main__':
if len(sys.argv) == 2:
try:
db = MythDB()
frontend = db.getFrontend(sys.argv[1])
wrapper(main)
except socket.timeout:
print "Could not connect to "+sys.argv[1]
pass
except TypeError:
print sys.argv[1]+" does not exist"
pass
except KeyboardInterrupt:
sys.exit()
except:
raise
else:
print "Please choose from the following available frontends:"
frontends = None
while frontend is None:
if frontends is None:
frontends = list(Frontend.fromUPNP())
if len(frontends) == 0:
print "No frontends detected"
sys.exit()
for i,f in enumerate(frontends):
print "%d. %s" % (i+1, f)
try:
i = int(raw_input('> '))-1
if i in range(0,len(frontends)):
frontend = frontends[i]
wrapper(main)
except KeyboardInterrupt:
sys.exit()
except EOFError:
sys.exit()
except:
raise
print "This input will only accept a number. Use Crtl-C to exit"