diff options
Diffstat (limited to 'mirrors/models.py')
-rw-r--r-- | mirrors/models.py | 86 |
1 files changed, 63 insertions, 23 deletions
diff --git a/mirrors/models.py b/mirrors/models.py index 19437610..d8ac7952 100644 --- a/mirrors/models.py +++ b/mirrors/models.py @@ -1,55 +1,56 @@ import socket from urlparse import urlparse -from django.db import models from django.core.exceptions import ValidationError +from django.db import models +from django.db.models.signals import pre_save from django_countries import CountryField - -TIER_CHOICES = ( - (0, 'Tier 0'), - (1, 'Tier 1'), - (2, 'Tier 2'), - (-1, 'Untiered'), -) +from .fields import IPNetworkField +from main.utils import set_created_field class Mirror(models.Model): + TIER_CHOICES = ( + (0, 'Tier 0'), + (1, 'Tier 1'), + (2, 'Tier 2'), + (-1, 'Untiered'), + ) + name = models.CharField(max_length=255, unique=True) tier = models.SmallIntegerField(default=2, choices=TIER_CHOICES) upstream = models.ForeignKey('self', null=True, on_delete=models.SET_NULL) - country = CountryField(blank=True, db_index=True) admin_email = models.EmailField(max_length=255, blank=True) + alternate_email = models.EmailField(max_length=255, blank=True) public = models.BooleanField(default=True) active = models.BooleanField(default=True) isos = models.BooleanField("ISOs", default=True) rsync_user = models.CharField(max_length=50, blank=True, default='') rsync_password = models.CharField(max_length=50, blank=True, default='') notes = models.TextField(blank=True) + created = models.DateTimeField(editable=False) class Meta: - ordering = ('country', 'name') + ordering = ('name',) def __unicode__(self): return self.name - def supported_protocols(self): - protocols = MirrorProtocol.objects.filter( - urls__mirror=self).order_by('protocol').distinct() - return sorted(protocols) - def downstream(self): return Mirror.objects.filter(upstream=self).order_by('name') def get_absolute_url(self): return '/mirrors/%s/' % self.name + class MirrorProtocol(models.Model): protocol = models.CharField(max_length=10, unique=True) is_download = models.BooleanField(default=True, help_text="Is protocol useful for end-users, e.g. FTP/HTTP") default = models.BooleanField(default=True, help_text="Included by default when building mirror list?") + created = models.DateTimeField(editable=False) def __unicode__(self): return self.protocol @@ -57,6 +58,7 @@ class MirrorProtocol(models.Model): class Meta: ordering = ('protocol',) + class MirrorUrl(models.Model): url = models.CharField("URL", max_length=255, unique=True) protocol = models.ForeignKey(MirrorProtocol, related_name="urls", @@ -67,6 +69,7 @@ class MirrorUrl(models.Model): editable=False) has_ipv6 = models.BooleanField("IPv6 capable", default=False, editable=False) + created = models.DateTimeField(editable=False) def address_families(self): hostname = urlparse(self.url).hostname @@ -78,10 +81,6 @@ class MirrorUrl(models.Model): def hostname(self): return urlparse(self.url).hostname - @property - def real_country(self): - return self.country or self.mirror.country - def clean(self): try: # Auto-map the protocol field by looking at the URL @@ -93,7 +92,7 @@ class MirrorUrl(models.Model): families = self.address_families() self.has_ipv4 = socket.AF_INET in families self.has_ipv6 = socket.AF_INET6 in families - except socket.error as e: + except socket.error: # We don't fail in this case; we'll just set both to False self.has_ipv4 = False self.has_ipv6 = False @@ -104,28 +103,69 @@ class MirrorUrl(models.Model): class Meta: verbose_name = 'mirror URL' + class MirrorRsync(models.Model): - ip = models.CharField("IP", max_length=24) + # max length is 40 chars for full-form IPv6 addr + subnet + ip = IPNetworkField("IP") mirror = models.ForeignKey(Mirror, related_name="rsync_ips") + created = models.DateTimeField(editable=False) def __unicode__(self): - return "%s" % (self.ip) + return self.ip class Meta: verbose_name = 'mirror rsync IP' + +class CheckLocation(models.Model): + hostname = models.CharField(max_length=255) + source_ip = models.GenericIPAddressField(verbose_name='source IP', + unpack_ipv4=True, unique=True) + country = CountryField() + created = models.DateTimeField(editable=False) + + class Meta: + ordering = ('hostname', 'source_ip') + + def __unicode__(self): + return self.hostname + + @property + def family(self): + info = socket.getaddrinfo(self.source_ip, None, 0, 0, 0, + socket.AI_NUMERICHOST) + families = [x[0] for x in info] + return families[0] + + @property + def ip_version(self): + '''Returns integer '4' or '6'.''' + if self.family == socket.AF_INET6: + return 6 + if self.family == socket.AF_INET: + return 4 + return None + + class MirrorLog(models.Model): url = models.ForeignKey(MirrorUrl, related_name="logs") + location = models.ForeignKey(CheckLocation, related_name="logs", null=True) check_time = models.DateTimeField(db_index=True) last_sync = models.DateTimeField(null=True) duration = models.FloatField(null=True) is_success = models.BooleanField(default=True) - error = models.CharField(max_length=255, blank=True, default='') + error = models.TextField(blank=True, default='') def __unicode__(self): return "Check of %s at %s" % (self.url.url, self.check_time) class Meta: verbose_name = 'mirror check log' + get_latest_by = 'check_time' + + +for model in (Mirror, MirrorProtocol, MirrorUrl, MirrorRsync, CheckLocation): + pre_save.connect(set_created_field, sender=model, + dispatch_uid="mirrors.models") # vim: set ts=4 sw=4 et: |