from gheat import managers import datetime import binascii import hashlib from django.core import validators from django.db import models from django.dispatch import receiver from django.utils.encoding import smart_unicode from django.utils.translation import ugettext_lazy as _ class BinaryField(models.Field): MAGIC = '###MAGIC###' description = _('Binary object using base64 (up to %(max_length)s)') __metaclass__ = models.SubfieldBase def __init__(self, *args, **kwargs): # base64 roughly max the binary size with with 4 times kwargs['max_length'] = kwargs['max_length'] * 4 + len(self.MAGIC) super(BinaryField, self).__init__(*args, **kwargs) self.validators.append(validators.MaxLengthValidator(self.max_length)) def to_python(self,value): if value.startswith(self.MAGIC): return binascii.a2b_base64(value[len(self.MAGIC):]) else: return value def get_db_prep_value(self, value, connection, prepared=False): target = self.MAGIC + binascii.b2a_base64(value) if len(target) > self.max_length: raise ValueError(len(target)) return target def get_prep_lookup(self, lookup_type, value): raise TypeError('Lookup type %r not supported.' % lookup_type) def get_internal_type(self): return 'TextField' class TileCache(models.Model): key = models.CharField(max_length=34,unique=True) data = BinaryField(max_length=10000) creation_time = models.DateTimeField(auto_now_add=True) def __unicode__(self): return self.key @staticmethod def make_key(source): return hashlib.md5(source).hexdigest() class WirelessClient(models.Model): mac = models.CharField(max_length=17, unique=True) def __unicode__(self): return self.mac ORGANIZATION_CHOICES = ( ('WirelessLeiden', 'Wireless Leiden'), ) class Node(models.Model): name = models.CharField(max_length=50) latitude = models.FloatField(null=True,blank=True) longitude = models.FloatField(null=True,blank=True) organization = models.CharField(max_length="50",choices=ORGANIZATION_CHOICES,null=True,blank=True) class Accespoint(models.Model): mac = models.CharField(max_length=17) ssid = models.CharField(max_length=64) organization = models.CharField(max_length="50",choices=ORGANIZATION_CHOICES,null=True,blank=True) encryptie = models.BooleanField() class Meta: unique_together = ('mac', 'ssid') def __unicode__(self): return "%s - %s" % (self.mac, self.ssid) @staticmethod def get_organization(ssid): """ Try to determine the organization via the SSID """ organization = '' if ssid.startswith('ap') and ssid.endswith('wleiden.net'): organization = 'WirelessLeiden' elif ssid.startswith('ap') and 'WirelessLeiden' in ssid: organization = 'WirelessLeiden' return organization def save(self, *args, **kwargs): self.organization = self.get_organization(self.ssid) super(Accespoint, self).save(*args, **kwargs) class Gebruiker(models.Model): naam = models.CharField(max_length=64) email = models.CharField(max_length=64) def __unicode__(self): return "%s - %s" % (self.naam, self.email) class Apparatuur(models.Model): antenne = models.CharField(max_length=64) kaart = models.CharField(max_length=64) def __unicode__(self): return "%s - %s" % (self.antenne, self.kaart) class MeetRondje(models.Model): datum = models.DateTimeField(blank=True,null=True) naam = models.CharField(max_length=64) gebruiker = models.ForeignKey(Gebruiker) apparatuur = models.ForeignKey(Apparatuur) def __unicode__(self): return "%s - %s" % (self.gebruiker.naam, self.naam) class MeetBestand(models.Model): meetrondje = models.ForeignKey(MeetRondje) bestand = models.FileField(upload_to='meet-bestand/%Y/%m/%d') class Meting(models.Model): meetrondje = models.ForeignKey(MeetRondje) accespoint = models.ForeignKey(Accespoint) latitude = models.FloatField(name='Latitude', db_column='lat') longitude = models.FloatField(name='Longitude', db_column='lng') signaal = models.IntegerField(max_length=3) objects = managers.MetingManager() def __unicode__(self): return "%s @ %.5f,%.5f : %s" % (self.accespoint.ssid, float(self.latitude), float(self.longitude), self.signaal) class Meta: # This implies that you cannot have multiple messurements on the same # location for a single 'run', thus the data needs cleaned before to make # this properly hold. unique_together = ('meetrondje', 'accespoint', 'latitude', 'longitude'),