# TV grabber mod_python module import os, fcntl, time from tempfile import mktemp import webutil _title = "Beat Bolli's homepage - TV" _sizes = [ '192x144', '200x150', '256x192', '300x225', '384x288', '400x300', '512x384', '768x576' ] _refresh = ['0', '5', '10', '20', '30', '45', '60', '120', '300'] def _allstations(): f = open("/etc/X11/xawtvrc").readlines() f = [l[1:-2] for l in f if l[0] == '[' and l[-2] == ']'] return [l for l in f if not l in ('global', 'defaults')] _concat = ''.join def _select(name, list, default=''): options = [ '<option%s>%s</option>\n' % ( (default and item == default) and ' selected="selected"' or '', item ) for item in list ] return '<select id="%s" name="%s" size="1">\n%s</select>\n' % ( name, name, _concat(options) ) def _label(name, text): return '<label for="%s">%s</label>\n' % (name, text) def _submit(): return '<input type="submit" />\n' def _img(st, s, tm=''): alt = tm and st + ' on ' + tm or st width, height = s.split('x') return ('<img src="snap?st=%(st)s&s=%(s)s" ' 'width="%(width)s" height="%(height)s" ' 'title="%(alt)s" alt="%(alt)s" />') % locals() def _link(ch): return 'station?st=%s' % ch _station_header = """\ <p class="nav">Nav: <a href="/">Home</a> / <a href="/bb/">Beat</a> / <a href="/bb/bblog.html">bblog</a> : <a href="/bb/news.html">news</a> : <a href="/bb/links.html">links</a> : <a href="/bb/py/">Python</a> : <a href="/bb/js/">JavaScript</a> : TV / <a href="overview">Overview</a> : Single station </p> <h1>TV page</h1> """ _station_main_1 = """\ <form action="station"> <p>Here you can “watch” TV. The available stations, sizes and refresh rates are:</p> <p> %s</p> </form>%s """ _station_main_2 = """ </div> <div class="div"> <p>This is the snapshot of station %s on %s:</p> <p>%s</p> """ def station(req, st='', s='', r=''): req.content_type = 'text/html' req.headers_out.add('Content-Type', 'text/html; charset="iso-8859-1"') req.headers_out.add('Pragma', 'no-cache') if r and r != _refresh[0]: req.headers_out.add('Refresh', r) if not s: s = _sizes[0] if st: tm = time.asctime(time.gmtime()) + ' UTC' station = _station_main_2 % (st, tm, _img(st, s, tm)) else: station = '' form = [ _label('st', 'Station: '), _select('st', _allstations(), st), _label('s', 'Sizes: '), _select('s', _sizes, s), _label('r', 'Refresh rate (sec): '), _select('r', _refresh, r), _submit(), ] return webutil._template % ( _title, _station_header, _station_main_1 % (_concat(form), station) ) _overview_header = """\ <p class="nav">Nav: <a href="/">Home</a> / <a href="/bb/">Beat</a> / <a href="/bb/cgi/blosxom.pl">bblog</a> : <a href="/bb/cgi/blosxom.pl/news">news</a> : <a href="/bb/py/">Python</a> : <a href="/bb/js/">JavaScript</a> : TV / Overview : <a href="station">Single station</a> </p> <h1>TV overview</h1> """ _overview_main_1 = """\ <form action="overview"> <p>This is a more or less current overview of all configured stations.</p> <p> %s</p> </form> </div> <div class="div"> <h2>Current snapshots</h2> <table cellpadding="4"> """ _overview_main_2 = ' <td><a href="%s">%s</a></td>\n' _overview_main_3 = '</table>\n' def overview(req, r='', w='3'): req.content_type = 'text/html' req.headers_out.add('Content-Type', 'text/html; charset="iso-8859-1"') if r and r != _refresh[0]: req.headers_out.add('Refresh', r) form = [ _label('r', 'Refresh rate (sec): '), _select('r', [0] + _refresh[-3:], r), _label('w', 'Width: '), _select('w', [1, 2, 3, 4, 5], w), _submit(), ] main = [_overview_main_1 % _concat(form)] add = main.append try: w = int(w) except ValueError: w = 3 i = 0 for st in _allstations(): if i % w == 0: add('<tr>\n') add(_overview_main_2 % (_link(st), _img(st, _sizes[0]))) i += 1 if i % w == 0: add('</tr>\n') if i % w != 0: add('</tr>\n') add(_overview_main_3) return webutil._template % ( _title, _overview_header, _concat(main) ) def snap(req, st, s): lock = open('/tmp/tv.lock', 'w') fcntl.lockf(lock, fcntl.LOCK_EX) capture = mktemp() jpeg = '' try: os.system('v4lctl setstation "%s" 2>/dev/null' % st) os.system('v4lctl snap jpeg %s %s 2>/dev/null' % (s, capture)) try: f = open(capture) jpeg = f.read() f.close() req.content_type = 'image/jpeg' except IOError: pass finally: try: os.unlink(capture) except: pass fcntl.lockf(lock, fcntl.LOCK_UN) lock.close() return jpeg