[9a2cd17] | 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': |
---|
[1f16213] | 31 | gs = gs.filter(id__in=vals).order_by('id') |
---|
[9a2cd17] | 32 | else: |
---|
[1f16213] | 33 | gs = gs.filter(name__in=vals).order_by('name') |
---|
[9a2cd17] | 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, ) |
---|