home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
misc
/
volume30
/
radio2.0
/
part02
/
checkradio.py
< prev
next >
Wrap
Text File
|
1992-06-29
|
9KB
|
340 lines
# /***********************************************************
# Copyright 1991, 1992 by Stichting Mathematisch Centrum, Amsterdam, The
# Netherlands.
#
# All Rights Reserved
#
# Permission to use, copy, modify, and distribute this software and its
# documentation for any purpose and without fee is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear in
# supporting documentation, and that the names of Stichting Mathematisch
# Centrum or CWI not be used in advertising or publicity pertaining to
# distribution of the software without specific, written prior permission.
#
# STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
# FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# ******************************************************************/
# Continuously check radio transmissions on one or more ports.
# After an idea of Behr de Ruiter.
#
# usage: checkradio [-t] [port] ...
#
# Ports are given as command line arguments, default is radio's default.
# Shorthands 1..99 can be used as for radio's -p argument.
#
# With the -t option, repeatedly print status for each port argument.
# Without -t, pop up a GL window displaying the CD file if there is noise.
# For best results, use /ufs/guido/bin/sgi/python to execute this.
# Don't make the file executable; then dynamic loading of audioop fails!
# XXX To do:
# - need an option to suppress looping when using -t
# - need a `status only' option that sets exit status only
# - DELAY and LOOP should be under control of command line options
# - add options to specify font, colors and so on
# - optionally tune radio to the first station transmitting noise
# - should listen to info packets instead
# - move the symbolic constants and some subroutines to separate modules
import sys
import socket
import audioop
import string
import time
import os
from stat import *
from SOCKET import *
import getopt
# Parametrizations
CTL_PORT = 54319 # control port
PORT_OFFSET = 54320 # port offset if 1 <= port <= 99
DEF_PORT = 54321 # default port (if no args)
LOOP = 15 # listen for this many tenths seconds
DELAY = 10 # seconds between successive tries
LIMIT = 256 # silence threshold
BUFSIZE = 1500 # read buffer size
# Status constants returned by checkport()
TUNED = 'already tuned in'
BINDFAILURE = 'bind failure'
DEAD = 'not transmitting'
SILENT = 'transmitting silence'
NOISY = 'transmitting'
# Main program
def main():
try:
optlist, args = getopt.getopt(sys.argv[1:], 'tx:y:')
except getopt.error:
sys.stdout = sys.stderr
print 'usage: checkradio',
print '[-x xorg] [-y yorg] [-t] [port] ...'
print '-x xorg, -y yorg: left top origin of window',
print '(negative values: right bottom)'
print '-t: tty mode output (looping), no window'
sys.exit(2)
#
do_win = 1
x, y = 140, 4
for opt, arg in optlist:
if opt == '-t':
do_win = 0
elif opt == '-x':
x = int(eval(arg))
elif opt == '-y':
y = int(eval(arg))
#
ports = []
for arg in args:
p = int(eval(arg))
if 1 <= p <= 99:
p = p + PORT_OFFSET
ports.append(p)
if not ports:
ports.append(DEF_PORT)
#
if do_win:
wincode(ports, (x, y))
else:
ttycode(ports)
# Code for tty version
def ttycode(ports):
while 1:
for p in ports:
print 'port', p, ':',
sys.stdout.flush()
status, sender = checkport(p)
if status in (NOISY, SILENT):
cdname = getinfostring(p, sender)
if cdname:
status = status + ': ' + cdname
print status
time.sleep(DELAY)
def getinfostring(port, sender):
name, port, transmitting, logfile, age, contents = \
getinfo(port, sender)
if 0 <= age < 99999:
contents = contents + ' (' + formatage(age) + ')'
return contents
def formatage(age):
if age < 60: return `age` + ' sec'
if age < 3600: return `age/60` + ' min'
if age < 24*3600: return `age/3600` + ' hrs'
return `age/(24*3600)` + ' days'
# Code for GL window version
# Parameters
timer_rate = 60 # Seconds
color_choices = [95, 94, 93, 92, 91, 90, 89, 88]
def wincode(ports, org):
if len(ports) > 1:
sys.stderr.write('warning: only the first port arg is used\n')
port = ports[0]
import gl, GL, DEVICE, fm
#gl.foreground()
fh = fm.findfont('Helvetica').scalefont(8)
fh.setfont()
str, age = getinfopair(port)
# Always create the window initially -- to initialize gl
wid = createwin(org, fh, str)
gl.qdevice(DEVICE.TIMER1)
gl.noise(DEVICE.TIMER1, timer_rate*60) # 60th of a second
while 1:
dev, val = gl.qread()
if dev == DEVICE.REDRAW:
redraw_window(wid, str, age)
elif dev == DEVICE.TIMER1:
oldstr = str
str, age = getinfopair(port)
if str <> oldstr:
if wid > 0:
org = currentorg(org)
deletewin(wid)
wid = -1
if str:
wid = createwin(org, fh, str)
elif wid > 0:
redraw_window(wid, str, age)
def currentorg((oldx, oldy)):
import gl, GL
x, y = gl.getorigin()
if oldx >= 0 and oldy >= 0: return (oldx, oldy)
xsize, ysize = gl.getsize()
xmax = gl.getgdesc(GL.GD_XPMAX)
ymax = gl.getgdesc(GL.GD_YPMAX)
if oldx < 0:
x = (x + xsize) - (xmax+1)
if x >= 0: x = -1
if oldy < 0:
y = (y + ysize) - (ymax+1)
if y >= 0: y = -1
return x, y
def redraw_window(wid, str, age):
import gl, GL, fm
mins = age/60 # Convert to minutes
gl.color(color_choices[min(max(0, mins/9), len(color_choices)-1)])
gl.clear()
gl.color(GL.BLACK)
xsize, ysize = gl.getsize()
gl.bgnclosedline()
gl.v2i(0, 0)
gl.v2i(0, ysize-1)
gl.v2i(xsize-1, ysize-1)
gl.v2i(xsize-1, 0)
gl.endclosedline()
gl.cmov2i(4, 4)
fm.prstr(str)
def createwin((x, y), fh, str):
import gl, GL, DEVICE
gl.noborder()
xsize = fh.getstrwidth(str) + 7
ysize = 16
if x < 0 or y < 0:
xmax = gl.getgdesc(GL.GD_XPMAX)
ymax = gl.getgdesc(GL.GD_YPMAX)
if x < 0: x = x + (xmax+1) - xsize
if y < 0: y = y + (ymax+1) - ysize
gl.prefposition(x, x + xsize, y, y + ysize)
wid = gl.winopen('checkradio')
gl.qenter(DEVICE.REDRAW, wid)
return wid
def deletewin(wid):
import gl, GL, DEVICE
gl.winclose(wid)
def getinfopair(port):
state, sender = checkport(port)
if state not in (NOISY, SILENT):
return '', 99999
name, port, transmitting, logfile, age, contents = \
getinfo(port, sender)
return contents, age
# Common code
def checkport(port):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
s.setsockopt(SOL_SOCKET, SO_REUSEPORT, 1)
except socket.error:
print 'warning: cannot set socket option SO_REUSEPORT'
try:
s.bind('', port)
except socket.error, msg:
if msg == (114, 'Address already in use'):
return TUNED, msg
else:
return BINDFAILURE, msg
transmitting = 0
noise = 0
sender = None
for i in range(LOOP):
if i: time.millisleep(100)
while s.avail():
data, sender = s.recvfrom(BUFSIZE)
if data[:6] == 'radio:': continue
transmitting = 1
lindata = audioop.ulaw2lin(data, 2)
n = audioop.max(lindata, 2)
if n > LIMIT:
noise = n
break
if noise: break
s.close()
if not transmitting:
return DEAD, sender
if not noise:
return SILENT, sender
return NOISY, sender
def getinfo(port, sender):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.sendto('radio:s', (sender[0], CTL_PORT))
for i in range(LOOP):
time.millisleep(100)
while s.avail():
data, realsender = s.recvfrom(BUFSIZE)
if data[:7] == 'radio:S':
return decodeinfo(data)
def decodeinfo(data):
fields = string.splitfields(data, ':')
name = fields[2]
port = eval(fields[3])
if fields[4:]:
transmitting = eval(fields[4])
logfile = fields[5]
age = eval(fields[6])
contents = string.joinfields(fields[7:], ':')
else:
transmitting = -1
programfile = '/ufs/' + name + '/CD'
logfile = programfile + 'log'
age = getage(programfile)
if age == None:
age = -1
contents = getcontents(programfile)
if contents == None:
contents = '???'
return name, port, transmitting, logfile, age, contents
return None
def getcontents(filename):
try:
f = open(filename, 'r')
except IOError:
return None
res = f.readline()
f.close()
return string.strip(res)
def getage(filename):
try:
st = os.stat(filename)
except os.error:
return None
return time.time() - st[ST_MTIME]
# Call the main program
try:
main()
except KeyboardInterrupt:
print
print '[Interrupt]'