source: asadb/space/models.py @ d85ba8f

space-accessstablestage
Last change on this file since d85ba8f was bec7760, checked in by Alex Dehnert <adehnert@…>, 14 years ago

office access: initial diff script

  • Property mode set to 100755
File size: 5.4 KB
RevLine 
[bec7760]1import collections
[a86a924]2import datetime
3
4from django.db import models
[bec7760]5from django.db.models import Q
[a86a924]6
7import reversion
8
9import groups.models
10
11# Create your models here.
12
13class Space(models.Model):
14    number = models.CharField(max_length=20, unique=True, )
15    asa_owned = models.BooleanField(default=True, )
16    notes = models.TextField(blank=True, )
17
18    def __unicode__(self, ):
19        if self.asa_owned:
20            asa_str = "ASA"
21        else:
22            asa_str = "Non-ASA"
23        return u"%s (%s)" % (self.number, asa_str)
[bec7760]24
25    def build_access(self, time=None, group=None, ):
26        """Assemble a list of who had access to this Space.
27
28        time:
29            optional; indicate that you want access as of a particular time.
30            If omitted, uses the present.
31        group:
32            optional; indicates that you want access via a particular group.
33            If omitted, finds access via any group.
34
35        Return value:
36            tuple (access, assignments, aces, errors)
37            access is the main field that matters, but the others are potentially useful supplementary information
38
39            access:
40                Group.pk -> (ID -> Set name)
41                Indicates who has access. Grouped by group and ID number.
42                Usually, the sets will each have one member, but ID 999999999 is decently likely to have several.
43                The SpaceAccessListEntrys will be filtered to reflect assignments as of that time.
44            assignments:
45                [SpaceAssignment]
46                QuerySet of all SpaceAssignments involving the space and group at the time
47            aces:
48                [SpaceAccessListEntry]
49                QuerySet of all SpaceAccessListEntrys involving the space and group at the time.
50                This is not filtered for the ace's group having a relevant SpaceAssignment.
51            errors:
52                [String]
53                errors/warnings that occurred.
54                Includes messages about groups no longer having access.
55        """
56
57        if time is None:
58            time = datetime.datetime.now()
59        errors = []
60        time_q = Q(end__gte=time, start__lte=time)
61        assignments = SpaceAssignment.objects.filter(time_q, space=self)
62        aces = SpaceAccessListEntry.objects.filter(time_q, space=self)
63        if group:
64            assignments = assignments.filter(group=group)
65            aces = aces.filter(group=group)
66        access = {}    # Group.pk -> (ID -> Set name)
67        for assignment in assignments:
68            if assignment.group.pk not in access:
69                access[assignment.group.pk] = collections.defaultdict(set)
70        for ace in aces:
71            if ace.group.pk in access:
72                access[ace.group.pk][ace.card_number].add(ace.name)
73            else:
74                # This group appears to no longer have access...
75                errors.append("Group %s no longer has access to %s, but has live ACEs." % (ace.group, self, ))
76        return access, assignments, aces, errors
77
[a86a924]78reversion.register(Space)
79
[6ff04b1]80
81class CurrentAssignmentManager(models.Manager):
82    def get_query_set(self, ):
83        return super(CurrentAssignmentManager, self).get_query_set().filter(
84            start__lte=datetime.date.today,
85            end__gte=datetime.date.today,
86        )
87
[a86a924]88class SpaceAssignment(models.Model):
89    END_NEVER       = datetime.datetime.max
90
91    group = models.ForeignKey(groups.models.Group)
92    space = models.ForeignKey(Space)
93    start = models.DateField(default=datetime.datetime.now)
94    end = models.DateField(default=END_NEVER)
95
96    notes = models.TextField(blank=True, )
97    locker_num = models.CharField(max_length=10, blank=True, help_text='Locker number. If set, will use the "locker-access" OfficerRole to maintain access. If unset/blank, uses "office-access" and SpaceAccessListEntry for access.')
98
[6ff04b1]99    objects = models.Manager()
100    current = CurrentAssignmentManager()
101
[a86a924]102    def expire(self, ):
103        self.end_time = datetime.datetime.now()-self.EXPIRE_OFFSET
104        self.save()
105
[6ff04b1]106    def is_locker(self, ):
107        return bool(self.locker_num)
108
109    def __unicode__(self, ):
110        return u"<SpaceAssignment group=%s space=%s locker=%s start=%s end=%s>" % (
111            self.group,
112            self.space,
113            self.locker_num,
114            self.start,
115            self.end,
116        )
117
118
119class CurrentACLEntryManager(models.Manager):
120    def get_query_set(self, ):
121        return super(CurrentACLEntryManager, self).get_query_set().filter(
122            start__lte=datetime.datetime.now,
123            end__gte=datetime.datetime.now,
124        )
125
[a86a924]126class SpaceAccessListEntry(models.Model):
127    END_NEVER       = datetime.datetime.max
128
129    group = models.ForeignKey(groups.models.Group)
130    space = models.ForeignKey(Space)
131    start = models.DateTimeField(default=datetime.datetime.now)
132    end = models.DateTimeField(default=END_NEVER)
133
134    name = models.CharField(max_length=50)
135    card_number = models.CharField(max_length=20)
136
[6ff04b1]137    objects = models.Manager()
138    current = CurrentACLEntryManager()
139
[a86a924]140    def expire(self, ):
141        self.end_time = datetime.datetime.now()-self.EXPIRE_OFFSET
142        self.save()
[6ff04b1]143
144    def format_name(self, ):
145        return u"%s (%s)" % (self.name, self.card_number, )
146
147    def __unicode__(self, ):
148        return u"<SpaceAccessListEntry group=%s space=%s name=%s start=%s end=%s>" % (
149            self.group,
150            self.space,
151            self.name,
152            self.start,
153            self.end,
154        )
Note: See TracBrowser for help on using the repository browser.