source: asadb/groups/load_people.py @ 52fb1d5

space-accessstablestage
Last change on this file since 52fb1d5 was 161ce5f, checked in by Alex Dehnert <adehnert@…>, 13 years ago

Describe changes made by load_people (ASA-#192)

groups/load_people.py outputs a summary of the changes it made --- the numbers
of people processed, the usernames imported, etc.. However, it doesn't describe
what *specific* changes occurred --- what fields were updated, what account
class new users are in, etc.. This adds that data. In particular, showing the
account classes of freshly created and destroyed users will probably help to
notice any weird bursts of activity.

  • Property mode set to 100755
File size: 5.7 KB
Line 
1#!/usr/bin/python
2
3import sys
4import os
5
6if __name__ == '__main__':
7    cur_file = os.path.abspath(__file__)
8    django_dir = os.path.abspath(os.path.join(os.path.dirname(cur_file), '..'))
9    proj_dir = os.path.abspath(os.path.join(django_dir, '..'))
10    sys.path.append(django_dir)
11    sys.path.append(proj_dir)
12    os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
13
14import groups.models
15
16import collections
17import datetime
18
19from django.db import transaction
20
21fields = [
22    # Django field, in order matching the input fields
23    'username',
24    'mit_id',
25    'first_name',
26    'last_name',
27    'account_class',
28]
29
30def load_dcm(dcm_stream):
31    dcm_people = {}
32    for line in dcm_stream:
33        line = line.strip()
34        field_list = line.split("\t")
35        field_dict = {}
36        for index, field in enumerate(fields):
37            field_dict[field] = field_list[index]
38        dcm_people[field_dict['username']] = field_dict
39    return dcm_people
40
41@transaction.commit_manually
42def load_people(dcm_people):
43    django_people = groups.models.AthenaMoiraAccount.objects.all()
44    stat_loops = 0
45    stat_django_people = len(django_people)
46    stat_dcm_people = len(dcm_people)
47    stat_changed = 0
48    stat_mut_ign = 0
49    stat_unchanged = 0
50    stat_del = 0
51    stat_pre_del = 0
52    stat_undel = 0
53    stat_add = 0
54    stat_people = collections.defaultdict(list)
55    for django_person in django_people:
56        stat_loops += 1
57        if stat_loops % 100 == 0:
58            transaction.commit()
59            pass
60        mutable = django_person.mutable
61        if django_person.username in dcm_people:
62            # great, they're still in the dump
63            changed = False
64            changes = []
65            dcm_person = dcm_people[django_person.username]
66            del dcm_people[django_person.username]
67
68            # Check for changes: first fields, then deletions
69            for key in fields:
70                if django_person.__dict__[key] != dcm_person[key]:
71                    changed = True
72                    if key == 'mit_id':
73                        changes.append((key, '[redacted]', '[redacted]', ))
74                    else:
75                        changes.append((key, django_person.__dict__[key], dcm_person[key]))
76                    if mutable:
77                        django_person.__dict__[key] = dcm_person[key]
78            if django_person.del_date is not None:
79                changed = True
80                if mutable:
81                    django_person.del_date = None
82                    stat_undel += 1
83                    changes.append(('[account]', '[deleted]', '[undeleted]', ))
84                    stat_people['undel'].append((django_person.username, changes))
85
86            if changed:
87                stat_name = ''
88                if mutable:
89                    django_person.mod_date = datetime.date.today()
90                    django_person.save()
91                    stat_changed += 1
92                    stat_name = 'changed'
93                else:
94                    stat_mut_ign += 1
95                    stat_name = 'mut_ign'
96                stat_people[stat_name].append((django_person.username, changes))
97            else:
98                stat_unchanged += 1
99
100        else:
101            # They're not in the dump
102            if django_person.del_date is None:
103                stat_name = ''
104                if mutable:
105                    django_person.del_date = datetime.date.today()
106                    stat_del += 1
107                    stat_name = 'del'
108                    django_person.save()
109                else:
110                    stat_mut_ign += 1
111                    stat_name = 'mut_ign'
112                changes = [('account_class', django_person.account_class, '[deleted]')]
113                stat_people[stat_name].append((django_person.username, changes))
114            else:
115                stat_pre_del += 1
116
117    transaction.commit()
118
119    # Import new people from the DCM
120    for username, dcm_person in dcm_people.items():
121        stat_loops += 1
122        if stat_loops % 100 == 0:
123            transaction.commit()
124            pass
125        django_person = groups.models.AthenaMoiraAccount()
126        for key in fields:
127            django_person.__dict__[key] = dcm_person[key]
128        django_person.add_date = datetime.date.today()
129        stat_add += 1
130        changes = [('account_class', '[missing]', dcm_person['account_class'], )]
131        stat_people['add'].append((django_person.username, changes))
132        django_person.save()
133    transaction.commit()
134
135    stats = {
136        'loops': stat_loops,
137        'django_people': stat_django_people,
138        'dcm_people': stat_dcm_people,
139        'changed': stat_changed,
140        'mut_ign': stat_mut_ign,
141        'unchanged': stat_unchanged,
142        'del': stat_del,
143        'pre_del': stat_pre_del,
144        'undel': stat_undel,
145        'add': stat_add,
146    }
147    return stats, stat_people
148
149
150if __name__ == '__main__':
151    print "Phase 1 (DCM parsing): starting at %s" % (datetime.datetime.now(), )
152    dcm_people = load_dcm(sys.stdin)
153    print "Phase 1 (DCM parsing): complete at %s" % (datetime.datetime.now(), )
154    print "Phase 2 (Django updating): starting at %s" % (datetime.datetime.now(), )
155    stats, stat_people = load_people(dcm_people)
156    print "Phase 2 (Django updating): complete at %s" % (datetime.datetime.now(), )
157    print """
158Loop iterations:    %(loops)6d
159Initial in Django:  %(django_people)6d
160People in DCM:      %(dcm_people)6d
161Already Deleted:    %(pre_del)6d
162Unchanged:          %(unchanged)6d
163Changed:            %(changed)6d
164Change ignored:     %(mut_ign)6d
165Deleted:            %(del)6d
166Undeleted:          %(undel)6d
167Added:              %(add)6d
168""" % stats
169
170    for change_type, people in stat_people.items():
171        for person, changes in people:
172            print "%12s\t%12s\t%s" % (change_type, person, changes, )
173        print ""
Note: See TracBrowser for help on using the repository browser.