First commit with working script
This commit is contained in:
145
manage_mail.py
Normal file
145
manage_mail.py
Normal file
@@ -0,0 +1,145 @@
|
||||
import argparse
|
||||
from collections.abc import Mapping
|
||||
from dataclasses import dataclass
|
||||
|
||||
from pyexcel_odsr import get_data
|
||||
|
||||
COLUMN_HEADER = {
|
||||
"firstname": "Vorname",
|
||||
"lastname": "Nachname",
|
||||
"email": "Email",
|
||||
"status": "Status",
|
||||
}
|
||||
|
||||
|
||||
@dataclass
|
||||
class Person:
|
||||
firstname: str
|
||||
lastname: str
|
||||
email: str
|
||||
status: str
|
||||
row_number: int
|
||||
member_of: list[str]
|
||||
|
||||
|
||||
@dataclass
|
||||
class Mailinglist:
|
||||
name: str
|
||||
members: list[Person]
|
||||
extra_recipients: list[str]
|
||||
|
||||
def pretty_print(self, include_names: bool = False):
|
||||
print(f"{self.name}allmende-gufi.de:\n")
|
||||
for member in sorted(self.members, key=lambda x: x.email):
|
||||
printout = member.email.strip()
|
||||
if include_names:
|
||||
printout = f"{printout:<30} ({member.firstname} {member.lastname})"
|
||||
print(printout)
|
||||
for extra_recipient in self.extra_recipients:
|
||||
print(extra_recipient)
|
||||
|
||||
|
||||
def read_member_file(data: list[list]) -> list[Person]:
|
||||
"""
|
||||
Reads the memeber ODS file and returns a List of all the people in the project.
|
||||
"""
|
||||
header_row = data["Tabelle1"][0]
|
||||
|
||||
result = []
|
||||
|
||||
for index, row in enumerate(data["Tabelle1"][2:], start=1):
|
||||
if len(row) == 0:
|
||||
continue
|
||||
person = Person(
|
||||
firstname=row[header_row.index(COLUMN_HEADER["firstname"])],
|
||||
lastname=row[header_row.index(COLUMN_HEADER["lastname"])],
|
||||
email=row[header_row.index(COLUMN_HEADER["email"])],
|
||||
status=row[header_row.index(COLUMN_HEADER["status"])],
|
||||
row_number=index,
|
||||
member_of=[],
|
||||
)
|
||||
for h_index, header in enumerate(header_row):
|
||||
if header.endswith("@") and len(row) > h_index and row[h_index] == "x":
|
||||
person.member_of.append(header)
|
||||
if person.status != "Ehemalig":
|
||||
result.append(person)
|
||||
return result
|
||||
|
||||
|
||||
def compute_mailing_lists(people: list[Person]) -> list[Mailinglist]:
|
||||
"""
|
||||
Takes the list of people in the projects and returns a list of all Mailinglists.
|
||||
"""
|
||||
|
||||
result: dict[str, Mailinglist] = {}
|
||||
for person in people:
|
||||
for l in person.member_of:
|
||||
if l not in result:
|
||||
result[l] = Mailinglist(name=l, members=[], extra_recipients=[])
|
||||
|
||||
result[l].members.append(person)
|
||||
|
||||
return list(sorted(result.values(), key=lambda x: x.name))
|
||||
|
||||
|
||||
def create_wiki_article(
|
||||
mailing_lists: list[Mailinglist], omit: list[str] = ["alle@", "mitglieder@"]
|
||||
) -> str:
|
||||
"""
|
||||
Creates a DokuWiki article source listing the mailing lists in a table
|
||||
with their address and first names of the persons on it.
|
||||
"""
|
||||
wiki = "===== Mailing Lists =====\n\n"
|
||||
wiki += "^ Mail-Adresse ^ Mitglieder*innen ^\n"
|
||||
for ml in sorted(mailing_lists, key=lambda x: x.name):
|
||||
if ml.name in omit:
|
||||
continue
|
||||
address = ml.name + "allmende-gufi.de"
|
||||
first_names = ", ".join(
|
||||
[p.firstname for p in sorted(ml.members, key=lambda x: x.firstname)]
|
||||
)
|
||||
wiki += f"| {address} | {first_names} |\n"
|
||||
return wiki
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="Mail list manager",
|
||||
description="Generate Allmende mailing lists from an .ods file",
|
||||
)
|
||||
parser.add_argument(
|
||||
"input_file",
|
||||
type=str,
|
||||
help="Path to the .ods file containing the member data. It's usually located at 05_Organisation/allmende_menschen.ods",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--names",
|
||||
action="store_true",
|
||||
help="If given, peoples full names will be included in the printout",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--wiki",
|
||||
action="store_true",
|
||||
help="Output as DokuWiki article instead of pretty print",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
data = get_data(args.input_file)
|
||||
header_row = data["Tabelle1"][0]
|
||||
extra_recipients_row = data["Tabelle1"][1]
|
||||
people = read_member_file(data)
|
||||
|
||||
mailing_lists = compute_mailing_lists(people)
|
||||
|
||||
# add extra recipients to mailing_lists
|
||||
for l in mailing_lists:
|
||||
index = header_row.index(l.name)
|
||||
if len(extra_recipients_row) > index:
|
||||
extra_recipients = extra_recipients_row[header_row.index(l.name)]
|
||||
l.extra_recipients = extra_recipients.split(",")
|
||||
|
||||
if args.wiki:
|
||||
print(create_wiki_article(mailing_lists))
|
||||
else:
|
||||
for l in mailing_lists:
|
||||
l.pretty_print(include_names=args.names)
|
||||
print("\n=======\n")
|
||||
Reference in New Issue
Block a user