1 | #!/usr/bin/python |
---|
2 | import collections |
---|
3 | import csv |
---|
4 | import datetime |
---|
5 | import os |
---|
6 | import sys |
---|
7 | |
---|
8 | if __name__ == '__main__': |
---|
9 | cur_file = os.path.abspath(__file__) |
---|
10 | django_dir = os.path.abspath(os.path.join(os.path.dirname(cur_file), '..')) |
---|
11 | sys.path.append(django_dir) |
---|
12 | os.environ['DJANGO_SETTINGS_MODULE'] = 'settings' |
---|
13 | |
---|
14 | from django.db import transaction |
---|
15 | import django.contrib.auth.models |
---|
16 | import reversion |
---|
17 | |
---|
18 | import groups.models |
---|
19 | import util.emails |
---|
20 | |
---|
21 | def select_groups(select, src): |
---|
22 | raw_vals = [val.strip() for val in src] |
---|
23 | if select == 'id': |
---|
24 | vals = [int(val) for val in raw_vals] |
---|
25 | elif select == 'name': |
---|
26 | vals = raw_vals |
---|
27 | else: |
---|
28 | raise NotImplementedError, "Selecting by %s not supported" % (select, ) |
---|
29 | gs = groups.models.Group.objects |
---|
30 | if select == 'id': |
---|
31 | gs = gs.filter(id__in=vals).order_by('id') |
---|
32 | else: |
---|
33 | gs = gs.filter(name__in=vals).order_by('name') |
---|
34 | return gs |
---|
35 | |
---|
36 | def setup_revision(user, status): |
---|
37 | if user is not None: |
---|
38 | updater = django.contrib.auth.models.User.objects.get(username=user) |
---|
39 | else: |
---|
40 | updater = None |
---|
41 | reversion.set_user(updater) |
---|
42 | reversion.set_comment("Set status to %s" % (status.name, )) |
---|
43 | |
---|
44 | def output_group(out, g, new_status, email): |
---|
45 | pres_emails = ["%s@mit.edu" % (holder.person, ) for holder in g.officers('president')] |
---|
46 | treas_emails = ["%s@mit.edu" % (holder.person, ) for holder in g.officers('treasurer')] |
---|
47 | all_emails = [g.officer_email] + pres_emails + treas_emails |
---|
48 | out.writerow({ |
---|
49 | 'id': g.pk, |
---|
50 | 'name': g.name, |
---|
51 | 'old_status': g.group_status, |
---|
52 | 'email': ', '.join(all_emails), |
---|
53 | 'officer_email': g.officer_email, |
---|
54 | 'pres_emails': ', '.join(pres_emails), |
---|
55 | 'treas_emails': ', '.join(treas_emails), |
---|
56 | }) |
---|
57 | email_obj = None |
---|
58 | if email: |
---|
59 | ctx = { |
---|
60 | 'group': g, |
---|
61 | 'new_status': new_status, |
---|
62 | } |
---|
63 | email_obj = util.emails.email_from_template(email, ctx, |
---|
64 | subject="[ASA] %s has been derecognized" % (g.name, ), |
---|
65 | from_email='asa-exec@mit.edu', |
---|
66 | to=[g.officer_email], cc=pres_emails+treas_emails, |
---|
67 | ) |
---|
68 | email_obj.bcc.append('asa-admin@mit.edu') |
---|
69 | email_obj.extra_headers['Reply-To'] = 'asa-exec@mit.edu' |
---|
70 | return email_obj |
---|
71 | |
---|
72 | def update_group(g, status, message, user): |
---|
73 | g.group_status = status |
---|
74 | g.set_updater(user) |
---|
75 | g.save() |
---|
76 | if message: |
---|
77 | note = groups.models.GroupNote( |
---|
78 | author=user, |
---|
79 | body=message, |
---|
80 | acl_read_group=True, |
---|
81 | acl_read_offices=True, |
---|
82 | group=g, |
---|
83 | ) |
---|
84 | note.save() |
---|
85 | |
---|
86 | |
---|
87 | @transaction.commit_on_success |
---|
88 | def process_changes(status, select, message, user, email): |
---|
89 | # TODO: list groups that couldn't be found |
---|
90 | # TODO: dump group name, emails (officer+pres+treas?), maybe old status? |
---|
91 | fieldnames=['id', 'name', 'old_status', 'email', 'officer_email', 'pres_emails', 'treas_emails', ] |
---|
92 | out = csv.DictWriter( |
---|
93 | sys.stdout, |
---|
94 | fieldnames=fieldnames, |
---|
95 | ) |
---|
96 | out.writerow(dict(zip(fieldnames, fieldnames))) |
---|
97 | gs = select_groups(select, sys.stdin) |
---|
98 | status_obj = groups.models.GroupStatus.objects.get(slug=status) |
---|
99 | with reversion.create_revision(): |
---|
100 | setup_revision(user, status_obj) |
---|
101 | for g in gs: |
---|
102 | email_obj = output_group(out, g, status_obj, email) |
---|
103 | update_group(g, status_obj, message, user) |
---|
104 | if email_obj: email_obj.send() |
---|
105 | |
---|
106 | if __name__ == '__main__': |
---|
107 | from optparse import OptionParser |
---|
108 | parser = OptionParser() |
---|
109 | parser.add_option("--select-by", dest="select", |
---|
110 | help="take a list of TYPE on stdin (name or id)", metavar="TYPE") |
---|
111 | parser.add_option("-m", "--message", dest="message", |
---|
112 | help="add a note saying MESSAGE", metavar="MESSAGE") |
---|
113 | parser.add_option("--user", dest="user", |
---|
114 | help="username of person executing script") |
---|
115 | parser.add_option("--email", dest="email", |
---|
116 | help="send an email using TEMPLATE to the groups' officers", metavar="TEMPLATE") |
---|
117 | parser.set_defaults( |
---|
118 | select='id', |
---|
119 | message=None, |
---|
120 | author=None, |
---|
121 | email=None, |
---|
122 | ) |
---|
123 | (options, args) = parser.parse_args() |
---|
124 | assert len(args) == 1 |
---|
125 | status = args[0] |
---|
126 | process_changes(status, select=options.select, message=options.message, user=options.user, email=options.email, ) |
---|