You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
66 lines
2.5 KiB
66 lines
2.5 KiB
import requests
|
|
from requests.auth import HTTPBasicAuth
|
|
from zope import component
|
|
from zope.interface import implementer
|
|
|
|
from ceo_common.errors import UserAlreadySubscribedError, UserNotSubscribedError, \
|
|
NoSuchListError
|
|
from ceo_common.interfaces import IMailmanService, IConfig
|
|
|
|
|
|
@implementer(IMailmanService)
|
|
class MailmanService:
|
|
def __init__(self):
|
|
cfg = component.getUtility(IConfig)
|
|
self.base_domain = cfg.get('base_domain')
|
|
self.api_base_url = cfg.get('mailman3_api_base_url').rstrip('/')
|
|
api_username = cfg.get('mailman3_api_username')
|
|
api_password = cfg.get('mailman3_api_password')
|
|
self.basic_auth = HTTPBasicAuth(api_username, api_password)
|
|
|
|
def subscribe(self, address: str, mailing_list: str):
|
|
if '@' in mailing_list:
|
|
mailing_list = mailing_list[:mailing_list.index('@')]
|
|
if '@' not in address:
|
|
address = f'{address}@{self.base_domain}'
|
|
url = f'{self.api_base_url}/members'
|
|
resp = requests.post(
|
|
url,
|
|
data={
|
|
'list_id': f'{mailing_list}.{self.base_domain}',
|
|
'subscriber': address,
|
|
'pre_verified': 'True',
|
|
'pre_confirmed': 'True',
|
|
'pre_approved': 'True',
|
|
},
|
|
auth=self.basic_auth,
|
|
)
|
|
if not resp.ok:
|
|
desc = resp.json().get('description')
|
|
if resp.status_code == 409:
|
|
raise UserAlreadySubscribedError()
|
|
elif resp.status_code == 400 and desc == 'No such list':
|
|
raise NoSuchListError()
|
|
raise Exception(desc)
|
|
|
|
def unsubscribe(self, address: str, mailing_list: str):
|
|
if '@' not in mailing_list:
|
|
mailing_list = f'{mailing_list}@{self.base_domain}'
|
|
if '@' not in address:
|
|
address = f'{address}@{self.base_domain}'
|
|
url = f'{self.api_base_url}/lists/{mailing_list}/member/{address}'
|
|
resp = requests.delete(
|
|
url,
|
|
data={
|
|
'pre_approved': 'True',
|
|
'pre_confirmed': 'True',
|
|
},
|
|
auth=self.basic_auth,
|
|
)
|
|
if not resp.ok:
|
|
desc = resp.json().get('description')
|
|
if resp.status_code == 404:
|
|
# Unfortunately, a 404 here could mean either the list doesn't
|
|
# exist, or the member isn't subscribed
|
|
raise UserNotSubscribedError()
|
|
raise Exception(desc)
|
|
|