skip to primary navigationskip to content
 

sync.py

Python Source icon sync.py — Python Source, 2 KB (2701 bytes)

File contents

#!/usr/bin/python3
#
# Small script to synchronise Sympa list with local list of addresses.
# Demonstrates API defined at https://lists.cam.ac.uk/sympasoap/wsdl
#
# REVIEW : get list of emails on list
#    ADD : Add subscriber to list
#    DEL : Remove subscriber from list

# Ubuntu python3-zeep is "a fast and modern Python SOAP client"
from zeep.client     import Client, Settings
from zeep.exceptions import Fault
from getpass         import getpass
import sys
import os
import re

def die(str): print(str); sys.exit(1) # Nicer than raise Exception()
    

quiet = 'true'
listname_regexp = re.compile(r'^[\w\-]+$')
email_regexp    = re.compile(r'^(\S+\@\S+\.\S+[^\.])$')

if len(sys.argv) != 4:
    die("Args: listname owner datafile")

soap_url = "https://lists.cam.ac.uk/sympa/wsdl"
listname = sys.argv[1]
owner    = sys.argv[2]
datafile = sys.argv[3]

if not listname_regexp.match(listname):
    die("Invalid listname: "+ listname)
if not email_regexp.match(owner):
    die("Invalid onwer: "+ owner)
# Friendier than exception+stack backtrace on open()
if not os.path.isfile(datafile):
    die(datafile + " does not exist")    
    
required = {}
with open(datafile, 'r') as f:
    for email in f:
        email = email.strip()
        if (email == '') or (email[0] == '#'):
            continue
        if not email_regexp.match(email):
            die("Invalid email address in %s : %s"
                % (datafile, email))
        required[email] = 1
        
password = getpass(owner + " Password: ")

zeep = Client(soap_url, settings=Settings(strict=False))
try:
    result  = zeep.service.login(owner, password)
    element = result._raw_elements[0]
    cookie  = element.text
except Fault as err:
    die(err)   # Typically "Authentication failed"

# Add HTTP Cookie for session authentication    
zeep.settings.extra_http_headers = [("Cookie",
                                     f"sympa_session={cookie}")]

# existing list of members
existing = {}
for email in zeep.service.review(listname):
    if email == "no_subscribers": # Unhelpful quirk of REVIEW
        continue
    existing[email] = 1

for email in sorted(existing):
    if email in required:
        continue

    print("Removing: " + email)
    # "del" reserved word in Python, hence shenanigans with getattr()
    result = getattr(zeep.service, "del")(listname, email, quiet)
    if result._raw_elements[0].text != "true":
        die("Failed to remove: " + email)
     
for email in sorted(required):
    if email in existing:
        continue

    print("Adding: " + email)
    result = zeep.service.add(listname, email, '', quiet)
    if result._raw_elements[0].text != "true":
        die("Failed to add: " + email)

UIS Service Status

Phone padded  Service status line: (01223 7)67999
Website  Sign up for SMS/email status alerts
Website  Read major IT incident reports

UIS bITe-size bulletin


A regular newsletter aimed at the University's IT community, highlighting service and project news from UIS.

Sign up >

RSS Feed Latest news

Multi-factor authentication rollout on University Microsoft accounts

Apr 27, 2021

UIS is launching a project to roll out multi-factor authentication (MFA) on University Microsoft accounts.

University web search update on 30 April

Apr 22, 2021

We're updating the University web search engine to the latest version on Friday 30 April. Afterwards, it will look slightly different and some of the functionality will change.

View all news