source: asadb/util/mailinglist.py @ fbdde0b

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

Show why the stderr="" assert for MailmanList? fails

  • Property mode set to 100644
File size: 4.3 KB
Line 
1import subprocess
2
3import mit
4
5
6class MailingList(object):
7    def __init__(self, name, ):
8        self.name = name
9
10    def list_members(self, ):
11        raise NotImplementedError
12
13    def change_members(self, add_members, delete_members, ):
14        raise NotImplementedError
15
16
17BLANCHE_PATH="/usr/bin/blanche"
18class MoiraList(MailingList):
19    def __init__(self, *args, **kwargs):
20        super(MoiraList, self).__init__(*args, **kwargs)
21        self._ccache = None
22
23    @property
24    def ccache(self, ):
25        if not self._ccache:
26            self._ccache = mit.kinit()
27        return self._ccache
28
29    def list_members(self, ):
30        raise NotImplementedError
31        res = subprocess.Popen(
32            [BLANCHE_PATH, self.name, ],
33            stdout=subprocess.PIPE,
34            stderr=subprocess.PIPE,
35        )
36        stdout, stderr = res.communicate()
37        if res.returncode:
38            raise RuntimeError("Failed to list members: %s" % (stderr, ))
39        members = stdout.strip().split("\n")
40        return members
41
42    def strip_mit(self, email):
43        if '@' in email:
44            local, domain = email.split('@')
45            if domain.lower() == 'mit.edu':
46                return local
47        return email
48
49    def canonicalize_member(self, member):
50        if type(member) == type(()):
51            name, email = member
52        else:
53            name = None
54            email = member
55        email = self.strip_mit(email)
56        return name, email
57
58    def change_members(self, add_members, delete_members, ):
59        """
60        Add and/or remove members from the list.
61        """
62
63        # Note that it passes all members on the commandline, so it shouldn't be
64        # used for large lists at the moment. OTOH, "large" appears to be
65        # 2M characters, so.
66        # If that becomes an issue, it should probably check the number of
67        # changes, and use -al / -dl with a tempfile as appropriate.
68
69        env = dict(KRB5CCNAME=self.ccache.name)
70        cmdline = [BLANCHE_PATH, self.name, ]
71
72        for member in add_members:
73            name, email = self.canonicalize_member(member)
74            if name:
75                cmdline.extend(('-at', email, name))
76            else:
77                cmdline.extend(('-a', email))
78
79        for member in delete_members:
80            name, email = self.canonicalize_member(member)
81            cmdline.extend(('-d', email))
82
83        res = subprocess.Popen(
84            cmdline,
85            stdout=subprocess.PIPE,
86            stderr=subprocess.STDOUT,
87            env=env,
88        )
89        stdout, stderr = res.communicate()
90        return stdout
91
92
93
94MMBLANCHE_PATH="/mit/consult/bin/mmblanche"
95class MailmanList(MailingList):
96    def list_members(self, ):
97        res = subprocess.Popen(
98            [MMBLANCHE_PATH, self.name, ],
99            stdout=subprocess.PIPE,
100            stderr=subprocess.PIPE,
101        )
102        stdout, stderr = res.communicate()
103        if res.returncode:
104            raise RuntimeError("Failed to list members: %s" % (stderr, ))
105        members = stdout.strip().split("\n")
106        return members
107
108    def change_members(self, add_members, delete_members, ):
109        """
110        Add and/or remove members from the list.
111        """
112
113        # Note that it passes all members on the commandline, so it shouldn't be
114        # used for large lists at the moment. OTOH, "large" appears to be
115        # 2M characters, so.
116        # If that becomes an issue, it should probably check the number of
117        # changes, and use -al / -dl with a tempfile as appropriate.
118
119        cmdline = [MMBLANCHE_PATH, self.name, ]
120        for member in add_members:
121            cmdline.append('-a')
122            if type(member) == type(()):
123                name, email = member
124                name = name.replace('"', "''")
125                member = '"%s" <%s>' % (name, email, )
126            cmdline.append(member)
127        for member in delete_members:
128            cmdline.append('-d')
129            if type(member) == type(()):
130                name, member = member
131            cmdline.append(member)
132        res = subprocess.Popen(
133            cmdline,
134            stdout=subprocess.PIPE,
135            stderr=subprocess.PIPE,
136        )
137        stdout, stderr = res.communicate()
138        assert stderr=="", ("stderr unexpectedly non-empty: %s" % (stderr, ))
139        return stdout
Note: See TracBrowser for help on using the repository browser.