pyceo/ceod/transactions/members/UpdateMemberPositionsTransa...

63 lines
2.4 KiB
Python

from typing import List, Dict
from zope import component
from ..AbstractTransaction import AbstractTransaction
from ceo_common.interfaces import ILDAPService, IConfig
from ceo_common.errors import UserAlreadySubscribedError, UserNotSubscribedError
from ceo_common.logger_factory import logger_factory
logger = logger_factory(__name__)
class UpdateMemberPositionsTransaction(AbstractTransaction):
"""
Transaction to update member's positions, and remove positions for anyone that's not in the list,
then subscribe new execs to mailing list and unsubscribe old execs from it.
"""
# Positions is a dict where keys are member names and values are the list of positions they have
def __init__(self, positions: Dict[str, List[str]]):
super().__init__()
self.positions = positions
self.old_positions = {} # For rollback
self.ldap_srv = component.getUtility(ILDAPService)
def child_execute_iter(self):
cfg = component.getUtility(IConfig)
mailing_lists = cfg.get('auxiliary mailing lists_exec')
subscribe_status: Dict[IUser, bool] = {}
# Remove positions for old users
for user in self.ldap_srv.get_users_with_positions():
if user.uid not in self.positions:
self.positions[user.uid] = []
# Update positions via ldap
for username, positions in self.positions.items():
user = self.ldap_srv.get_user(username)
self.old_positions[username] = user.positions[:]
user.set_positions(positions)
subscribe_status[user] = len(positions) > 0
yield f'update_positions_{username}'
# Update mailing list subscription
for user, subscribe in subscribe_status.items():
for mailing_list in mailing_lists:
try:
if subscribe:
user.subscribe_to_mailing_list(mailing_list)
else:
user.unsubscribe_from_mailing_list(mailing_list)
except (UserAlreadySubscribedError, UserNotSubscribedError):
pass
except Exception as e:
logger.warning(f'Failed to update mailing list for {user.uid}')
self.finish(None)
def rollback(self):
for username, positions in self.old_positions.items():
user = self.ldap_srv.get_user(username)
user.set_positions(positions)