#!/usr/bin/env python # Status # # Douglas Thrift # # $Id$ from __init__ import lock from ccscslab.main.models import Computer, Login, Person from ccscslab.main import utils from django.db import transaction import contextlib import optparse import re import socket if __name__ == '__main__': parser = optparse.OptionParser() parser.add_option('-D', '--debug', action = 'store_true', dest = 'debug') options = parser.parse_args()[0] lock(options.debug) linux_ = re.compile(r'^Login {3,11}Name +Tty Idle Login Time Office Office Phone$') freebsd = re.compile(r'^([a-z0-9]{1,16}) {1,16}(?:.{19} \*|.{20} )([dpv:]).*$') linux = re.compile(r'^([a-z0-9]{1,16}) {1,16}.* \*?(:|[a-z]+).*$') windows = re.compile(r'^([a-z0-9]{1,16}) {1,16}.{20} [0-9]{1,6} {1,6}([^ ]{0,13}) .*$') default = re.compile(r'^([a-z0-9]{1,16})\s.*$') @transaction.commit_on_success def status(): if options.debug: print computer.name + ':' try: users = {} with contextlib.closing(utils.finger_connection(computer.full_name())) as finger: computer.online = True if options.debug: print ' online' finger.write('\r\n') finger.flush() FreeBSD = 0 Linux = 1 Windows = 2 type = None for line in finger: line = line.rstrip() user = None local = None if line in ('', 'No one logged on.'): continue elif line == 'Login Name TTY Idle Login Time Office Phone': type = FreeBSD continue elif linux_.match(line): type = Linux continue elif line == 'Login Name Id Session Status': type = Windows continue if type == FreeBSD: match = freebsd.match(line) if match is not None: user = match.group(1) local = match.group(2) in 'dv:' elif type == Linux: match = linux.match(line) if match is not None: user = match.group(1) local = match.group(2) in ('tty', ':') elif type == Windows: match = windows.match(line) if match is not None: user = match.group(1) local = match.group(2) == 'Console' else: match = default.match(line) if match is not None: user = match.group(1) local = False if user is not None and user not in users or local: users[user] = local people = [] for user, local in users.iteritems(): try: person = Person.objects.get(name = user) except Person.DoesNotExist: continue if options.debug: print ' ' + ('%-16s %s' % (person.name, 'local') if local else person.name) login = Login.objects.get_or_create(computer = computer, person = person)[0] login.local = local login.save() people.append(person) Login.objects.filter(computer = computer).exclude(person__in = people).delete() except (socket.timeout, socket.error): computer.online = False if options.debug: print ' offline' Login.objects.filter(computer = computer).delete() if options.debug: print ' deleted' computer.save() if options.debug: print ' updated' for computer in Computer.objects.all(): status()