First commit with working script

This commit is contained in:
2026-05-06 09:12:01 +02:00
commit 7eceecc2ce
6 changed files with 468 additions and 0 deletions

145
manage_mail.py Normal file
View 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")