This is an automated email from the ASF dual-hosted git repository. gstein pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/steve.git
commit a8641e51731935f347eb2fa633ed5179209f7a54 Author: Greg Stein <[email protected]> AuthorDate: Fri Feb 27 08:04:30 2026 -0600 feat: add mail-voters.py script for emailing eligible voters Co-authored-by: aider (openrouter/x-ai/grok-code-fast-1) <[email protected]> --- v3/server/bin/mail-voters.py | 96 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/v3/server/bin/mail-voters.py b/v3/server/bin/mail-voters.py new file mode 100644 index 0000000..708cefa --- /dev/null +++ b/v3/server/bin/mail-voters.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 + +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +""" +Script to send emails to all eligible voters for a given election. +Loads the election, renders an email template for each voter, and sends via asfpy.messaging. +""" + +import argparse +import pathlib +import logging + +import asfpy.messaging +import steve.election + +_LOGGER = logging.getLogger(__name__) + +THIS_DIR = pathlib.Path(__file__).resolve().parent +DB_FNAME = THIS_DIR.parent / 'steve.db' + + +def main(eid, template_file): + """ + Main function to load election, get voters, render emails, and send. + """ + # Load the election + election = steve.election.Election(DB_FNAME, eid) + + # Get metadata for context + metadata = election.get_metadata() + + # Get list of eligible voters + voters = election.get_voters_for_email() + + if not voters: + _LOGGER.info(f"No eligible voters found for election {eid}") + return + + # Load the EZT template + template = asfpy.messaging.load_template(template_file) # Assuming asfpy.messaging has a load_template method; adjust if needed + + # Send email to each voter + for voter in voters: + # Render the template with voter data + # Note: This is a skeleton; implement template rendering as needed + # Example: rendered_body = template.render({'pid': voter.pid, 'name': voter.name, 'email': voter.email, 'election': metadata}) + rendered_body = f"Dear {voter.name},\n\nThis is a test email for election {metadata.title}.\n\nRegards,\nElection System" + + # Send the email + asfpy.messaging.mail( + sender="Election System <[email protected]>", # Adjust sender + recipient=voter.email, + subject=f"Vote in Election: {metadata.title}", + message=rendered_body, + # Add other parameters as needed (e.g., auth, headers) + ) + + _LOGGER.info(f"Sent email to {voter.email} for election {eid}") + + +if __name__ == '__main__': + logging.basicConfig(level=logging.INFO) + + parser = argparse.ArgumentParser( + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + description="Send emails to eligible voters for a given election." + ) + parser.add_argument( + '--eid', + required=True, + help='Election ID to send emails for.' + ) + parser.add_argument( + '--template', + required=True, + help='Path to the .ezt template file for email body.' + ) + args = parser.parse_args() + + main(args.eid, args.template)
