# 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