146 lines
4.4 KiB
Python
146 lines
4.4 KiB
Python
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")
|