* refactor: replace datetime.now with timezone.now * refactor: migrate model fields to use timezone.now as default * refactor: replace datetime.today with timezone.now datetime.datetime.today() is equivalent to datetime.datetime.now(); both return a naive datetime with the current local time. * refactor: rephrase datetime.now(tz) as timezone.now().astimezone(tz) This is effectively the same, but is less likely to encourage accidental use of naive datetimes. * refactor: revert datetime.today() change to old migrations * refactor: change a missed datetime.now to timezone.now * chore: renumber timezone_now migration * chore: renumber migrations
106 lines
4.5 KiB
Python
Executable file
106 lines
4.5 KiB
Python
Executable file
# Copyright The IETF Trust 2012-2021, All Rights Reserved
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# This was written as a script by Markus Stenberg <markus.stenberg@iki.fi>.
|
|
# It was turned into a management command by Russ Housley <housley@vigisec.com>.
|
|
|
|
import datetime
|
|
import io
|
|
import os
|
|
import shutil
|
|
import stat
|
|
import time
|
|
|
|
from tempfile import mkstemp
|
|
|
|
from django.conf import settings
|
|
from django.core.management.base import BaseCommand
|
|
from django.utils import timezone
|
|
|
|
import debug # pyflakes:ignore
|
|
|
|
from ietf.group.models import Group
|
|
from ietf.group.utils import get_group_ad_emails, get_group_role_emails, get_child_group_role_emails
|
|
from ietf.name.models import GroupTypeName
|
|
from ietf.utils.aliases import dump_sublist
|
|
|
|
DEFAULT_YEARS = 5
|
|
ACTIVE_STATES=['active','bof','proposed']
|
|
GROUP_TYPES=['wg','rg','dir','team','review','program']
|
|
NO_AD_GROUP_TYPES=['rg','team','program']
|
|
IETF_DOMAIN=['ietf.org', ]
|
|
IRTF_DOMAIN=['irtf.org', ]
|
|
IAB_DOMAIN=['iab.org', ]
|
|
|
|
class Command(BaseCommand):
|
|
help = ('Generate the group-aliases and group-virtual files for Internet-Draft '
|
|
'mail aliases, placing them in the file configured in '
|
|
'settings.GROUP_ALIASES_PATH and settings.GROUP_VIRTUAL_PATH, '
|
|
'respectively. The generation includes aliases for groups that '
|
|
'have seen activity in the last %s years.' % (DEFAULT_YEARS))
|
|
|
|
def handle(self, *args, **options):
|
|
show_since = timezone.now() - datetime.timedelta(DEFAULT_YEARS*365)
|
|
|
|
date = time.strftime("%Y-%m-%d_%H:%M:%S")
|
|
signature = '# Generated by %s at %s\n' % (os.path.abspath(__file__), date)
|
|
|
|
ahandle, aname = mkstemp()
|
|
os.close(ahandle)
|
|
afile = io.open(aname,"w")
|
|
|
|
vhandle, vname = mkstemp()
|
|
os.close(vhandle)
|
|
vfile = io.open(vname,"w")
|
|
|
|
afile.write(signature)
|
|
vfile.write(signature)
|
|
vfile.write("%s anything\n" % settings.GROUP_VIRTUAL_DOMAIN)
|
|
|
|
# Loop through each group type and build -ads and -chairs entries
|
|
for g in GROUP_TYPES:
|
|
domains = []
|
|
domains += IETF_DOMAIN
|
|
if g == 'rg':
|
|
domains += IRTF_DOMAIN
|
|
if g == 'program':
|
|
domains += IAB_DOMAIN
|
|
|
|
entries = Group.objects.filter(type=g).all()
|
|
active_entries = entries.filter(state__in=ACTIVE_STATES)
|
|
inactive_recent_entries = entries.exclude(state__in=ACTIVE_STATES).filter(time__gte=show_since)
|
|
interesting_entries = active_entries | inactive_recent_entries
|
|
|
|
for e in interesting_entries.distinct().iterator():
|
|
name = e.acronym
|
|
|
|
# Research groups, teams, and programs do not have -ads lists
|
|
if not g in NO_AD_GROUP_TYPES:
|
|
dump_sublist(afile, vfile, name+'-ads', domains, settings.GROUP_VIRTUAL_DOMAIN, get_group_ad_emails(e))
|
|
# All group types have -chairs lists
|
|
dump_sublist(afile, vfile, name+'-chairs', domains, settings.GROUP_VIRTUAL_DOMAIN, get_group_role_emails(e, ['chair', 'secr']))
|
|
|
|
# The area lists include every chair in active working groups in the area
|
|
areas = Group.objects.filter(type='area').all()
|
|
active_areas = areas.filter(state__in=ACTIVE_STATES)
|
|
for area in active_areas:
|
|
name = area.acronym
|
|
area_ad_emails = get_group_role_emails(area, ['pre-ad', 'ad', 'chair'])
|
|
dump_sublist(afile, vfile, name+'-ads', IETF_DOMAIN, settings.GROUP_VIRTUAL_DOMAIN, area_ad_emails)
|
|
dump_sublist(afile, vfile, name+'-chairs', IETF_DOMAIN, settings.GROUP_VIRTUAL_DOMAIN, (get_child_group_role_emails(area, ['chair', 'secr']) | area_ad_emails))
|
|
|
|
# Other groups with chairs that require Internet-Draft submission approval
|
|
gtypes = GroupTypeName.objects.values_list('slug', flat=True)
|
|
special_groups = Group.objects.filter(type__features__req_subm_approval=True, acronym__in=gtypes, state='active')
|
|
for group in special_groups:
|
|
dump_sublist(afile, vfile, group.acronym+'-chairs', IETF_DOMAIN, settings.GROUP_VIRTUAL_DOMAIN, get_group_role_emails(group, ['chair', 'delegate']))
|
|
|
|
afile.close()
|
|
vfile.close()
|
|
|
|
os.chmod(aname, stat.S_IWUSR|stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH)
|
|
os.chmod(vname, stat.S_IWUSR|stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH)
|
|
|
|
shutil.move(aname, settings.GROUP_ALIASES_PATH)
|
|
shutil.move(vname, settings.GROUP_VIRTUAL_PATH)
|