1 | #!/usr/local/bin/python |
---|
2 | # |
---|
3 | # |
---|
4 | import os |
---|
5 | import sys |
---|
6 | import curses |
---|
7 | import re |
---|
8 | from MythTV import Frontend, MythTV |
---|
9 | import socket |
---|
10 | from curses.wrapper import wrapper |
---|
11 | |
---|
12 | PORT = 6546 |
---|
13 | FE = None |
---|
14 | |
---|
15 | try: |
---|
16 | FE = Frontend(sys.argv[1],PORT) |
---|
17 | except: |
---|
18 | print "polling frontends..." |
---|
19 | mythtv = MythTV() |
---|
20 | fes = mythtv.getFrontends() |
---|
21 | if len(fes) == 0: |
---|
22 | print "No accessible frontends found" |
---|
23 | sys.exit(1) |
---|
24 | print "Select a frontend:" |
---|
25 | print " 0. quit" |
---|
26 | for i in range(0,len(fes)): |
---|
27 | print " %d. %s:%d" % (i+1,fes[i].host,fes[i].port) |
---|
28 | i = None |
---|
29 | while not i: |
---|
30 | try: |
---|
31 | i = int(raw_input("> ")) |
---|
32 | except KeyboardInterrupt: |
---|
33 | sys.exit(0) |
---|
34 | except: |
---|
35 | print "Invalid input... Please choose between 0 and %d" %len(fes) |
---|
36 | continue |
---|
37 | print i |
---|
38 | if i == 0: |
---|
39 | sys.exit(0) |
---|
40 | if (i < 1) | (i > len(fes)): |
---|
41 | print "Invalid input... Please choose between 0 and %d" %len(fes) |
---|
42 | i = None |
---|
43 | continue |
---|
44 | FE = fes[i-1] |
---|
45 | |
---|
46 | keys = { |
---|
47 | 9: 'tab', |
---|
48 | 10: 'enter', |
---|
49 | 27: 'escape', |
---|
50 | 32: 'space', |
---|
51 | 127: 'backspace', |
---|
52 | 258: 'down', |
---|
53 | 259: 'up', |
---|
54 | 260: 'left', |
---|
55 | 261: 'right', |
---|
56 | 262: 'home', |
---|
57 | 263: 'backspace', |
---|
58 | 330: 'delete', |
---|
59 | 331: 'insert', |
---|
60 | 338: 'pagedown', |
---|
61 | 339: 'pageup', |
---|
62 | 353: 'backtab', |
---|
63 | 360: 'end', |
---|
64 | } |
---|
65 | |
---|
66 | def padstr(str, size, align='right'): |
---|
67 | pl = 0 |
---|
68 | pr = 0 |
---|
69 | for i in range(len(str),size): |
---|
70 | if align == 'left': |
---|
71 | str += ' ' |
---|
72 | pr += 1 |
---|
73 | elif align == 'right': |
---|
74 | str = ' '+str |
---|
75 | pl += 1 |
---|
76 | elif align == 'center': |
---|
77 | if pl > pr: |
---|
78 | str += ' ' |
---|
79 | pr += 1 |
---|
80 | else: |
---|
81 | str = ' '+str |
---|
82 | pl += 1 |
---|
83 | else: |
---|
84 | return str |
---|
85 | return str |
---|
86 | |
---|
87 | def process_time(screen): |
---|
88 | date, time = FE.sendQuery('time').split('T') |
---|
89 | screen.addstr(0,0,date) |
---|
90 | screen.addstr(0,72,time) |
---|
91 | |
---|
92 | def process_memory(screen): |
---|
93 | phytot, phyfree, swptot, swpfree = FE.sendQuery('memstats').split(' ') |
---|
94 | screen.addstr(5, 67, padstr("%s/%s MB" % (phyfree,phytot),13)) |
---|
95 | screen.addstr(6, 67, padstr("%s/%s MB" % (swpfree,swptot),13)) |
---|
96 | |
---|
97 | def process_load(screen): |
---|
98 | load = FE.sendQuery('load').split(' ') |
---|
99 | screen.addstr(10,62, padstr('%2.2f' % float(load[0]),5)) |
---|
100 | screen.addstr(10,68, padstr('%2.2f' % float(load[1]),5)) |
---|
101 | screen.addstr(10,74, padstr('%2.2f' % float(load[2]),5)) |
---|
102 | |
---|
103 | def process_status(screen): |
---|
104 | stat = FE.sendQuery('location') |
---|
105 | screen.addstr(2, 0, ' ') |
---|
106 | screen.addstr(3, 0, ' ') |
---|
107 | |
---|
108 | dat = re.match('Playback (?P<type>[a-zA-Z]*) (?P<pos>[0-9:]*) of (?P<len>[0-9:]*) (?P<rate>[-0-9\.]*x) (?P<chan>[0-9]*) (?P<datetime>[0-9-T:]*)',stat) |
---|
109 | if dat: |
---|
110 | show = '' |
---|
111 | if dat.group('type') == 'Recording': |
---|
112 | show = re.match('[0-9]* [0-9-T:]* (?P<show>.*)',FE.sendQuery('recording %s %s' % (dat.group('chan'),dat.group('datetime')))).group('show') |
---|
113 | screen.addstr(2, 0, 'Playback: %s' % show) |
---|
114 | elif dat.group('type') == 'LiveTV': |
---|
115 | show = re.match('[0-9]* [0-9-T: ]* (?P<show>.*)',FE.sendQuery('liveTV %s' % dat.group('chan'))).group('show') |
---|
116 | screen.addstr(2, 0, 'LiveTV: %s - %s' % (dat.group('chan'),show)) |
---|
117 | screen.addstr(3, 0, ' %s of %s @ %s' % (dat.group('pos'),dat.group('len'),dat.group('rate'))) |
---|
118 | else: |
---|
119 | screen.addstr(2, 0, stat) |
---|
120 | |
---|
121 | |
---|
122 | def main(screen): |
---|
123 | curses.halfdelay(10) |
---|
124 | screen.addstr(0, 26, '-= MythTV console remote =-') |
---|
125 | screen.addstr(1, 0, '--------------------------------------------------------------------------------') |
---|
126 | screen.addstr(2, 60, '|') |
---|
127 | screen.addstr(2, 61, padstr('%s:%s' % (FE.host,FE.port),19,'center')) |
---|
128 | screen.addstr(3, 60, '|-------------------') |
---|
129 | screen.addstr(4, 60, '| -= Free Mem =- ') |
---|
130 | screen.addstr(5, 60, '| Phy: ') |
---|
131 | screen.addstr(6, 60, '| Swp: ') |
---|
132 | screen.addstr(7, 60, '|-------------------') |
---|
133 | screen.addstr(8, 60, '| -= Load =- ') |
---|
134 | screen.addstr(9, 60, '| 1 5 15 ') |
---|
135 | screen.addstr(10,60, '| ') |
---|
136 | screen.addstr(11,60, '--------------------') |
---|
137 | try: |
---|
138 | while True: |
---|
139 | c = None |
---|
140 | process_time(screen) |
---|
141 | process_memory(screen) |
---|
142 | process_load(screen) |
---|
143 | process_status(screen) |
---|
144 | try: |
---|
145 | c = screen.getch() |
---|
146 | curses.flushinp() |
---|
147 | if c == 274: |
---|
148 | os.system('tvoff') |
---|
149 | if c == 275: |
---|
150 | os.system('tvon') |
---|
151 | elif c in keys: |
---|
152 | s = 'key %s\n' % keys[c] |
---|
153 | screen.addstr(6, 3, s) |
---|
154 | FE.sendKey(keys[c]) |
---|
155 | elif c >= 0: |
---|
156 | if c <= 256: |
---|
157 | s = 'key %s\n' % chr(c) |
---|
158 | FE.sendKey(chr(c)) |
---|
159 | else: |
---|
160 | s = 'key #%s\n' % c |
---|
161 | FE.sendKey('#%s' %c) |
---|
162 | screen.addstr(6, 3, s) |
---|
163 | except EOFError: |
---|
164 | FE.disconnect() |
---|
165 | FE.connect() |
---|
166 | except KeyboardInterrupt: |
---|
167 | screen.addstr("Exiting...") |
---|
168 | except socket.error: |
---|
169 | screen.addstr("Remote side closed connection...") |
---|
170 | except TypeError: |
---|
171 | screen.addstr("Remote side closed connection...") |
---|
172 | except: |
---|
173 | pass |
---|
174 | curses.endwin() |
---|
175 | |
---|
176 | wrapper(main) |
---|