# CCS CS Lab Laptops Models # # Douglas Thrift # # $Id$ from ccscslab.facebook.models import DualUserModel, User from datetime import datetime from django.db import models from dt_django_uuid import UUIDField import socket import uuid class MACAddressField(models.Field): def __init__(self, *args, **kwargs): super(MACAddressField, self).__init__(*args, **kwargs) def db_type(self, connection): return 'macaddr' def formfield(self, **kwargs): from ccscslab.laptops.forms import MACAddressField as MACAddressFormField defaults = {'form_class': MACAddressFormField} defaults.update(kwargs) return super(MACAddressField, self).formfield(**defaults) class Laptop(DualUserModel): mac_address = MACAddressField(db_index = True) online = models.BooleanField(default = False) ip_address = models.IPAddressField(blank = True, null = True) name = models.CharField(blank = True, max_length = 50) fancy_name = models.CharField(blank = True, max_length = 50) class Meta: ordering = ('-online', 'user', 'person', 'ip_address', 'mac_address') unique_together = ('person', 'user', 'mac_address') def __unicode__(self): return self.mac_address def laptop_name(self): if self.fancy_name != '': return self.fancy_name elif self.name != '': return self.name else: return self.ip_address def oui_iab(self): return OUI.objects.lookup(self.mac_address) class Sync(models.Model): name = models.CharField(max_length = 50, unique = True) when = models.DateTimeField(auto_now = True, auto_now_add = True) last_uuid = UUIDField(null = True) class Meta: ordering = ('name',) def __unicode__(self): return self.name @classmethod def sync(cls, both = False): sync = cls.objects.get_or_create(name = socket.gethostname()) return sync if both else sync[0] class Entry(models.Model): person = models.ForeignKey('main.Person') mac_address = MACAddressField(db_index = True) name = models.CharField(blank = True, max_length = 50) deleted = models.BooleanField(default = False) when = models.DateTimeField(db_index = True, default = datetime.now) uuid = UUIDField(default = uuid.uuid1, unique = True) sync = models.ForeignKey(Sync, default = Sync.sync) class Meta: ordering = ('when',) def __call__(self, user = None): if user is None: try: user = self.person.facebook_user_set.get() except User.DoesNotExist: pass if not self.deleted: laptop, inserted = Laptop.objects.get_or_create(person = self.person, user = user, mac_address = self.mac_address) laptop.fancy_name = self.name laptop.save() return laptop, inserted else: Laptop.objects.filter(person = self.person, user = user, mac_address = self.mac_address).delete() def __unicode__(self): return '%s %s %s %s' % (self.person, self.mac_address, 'deleted' if self.deleted else 'updated', self.when) class OUIManager(models.Manager): def lookup(self, mac_address): try: oui = self.extra(where = ['trunc(macaddr %s) = prefix'], params = [mac_address]).get() try: return oui.iab_set.get(lower__lte = mac_address, upper__gte = mac_address) except IAB.DoesNotExist: return oui except OUI.DoesNotExist: return None class OUI(models.Model): prefix = MACAddressField(unique = True) company = models.CharField(max_length = 100) objects = OUIManager() class Meta: ordering = ('prefix',) def __unicode__(self): return self.prefix[:8] + ' ' + self.company class IAB(models.Model): oui = models.ForeignKey(OUI) lower = MACAddressField() upper = MACAddressField() company = models.CharField(max_length = 100) class Meta: ordering = ('lower',) unique_together = ('oui', 'lower', 'upper') def __unicode__(self): return self.oui.prefix[:8] + ' ' + self.lower[9:] + '-' + self.upper[9:] + ' ' + self.company