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

Wireless service maintenance 08:00–09:00 Tuesday 9 March

Mar 04, 2021

The University Wireless Service will be undergoing maintenance between 08:00 and 09.00 on Tuesday 9 March. During this period, users may experience interrupted service to eduroam, the UniOfCam guest system, the UniOfCam-IoT system and local SSIDs.

CHRIS, ESS and UPS unavailable all day on Thursday 4 March

Feb 25, 2021

CHRIS, Employee Self-Service (ESS) and the University Payment System (UPS) will be unavailable all day on Thursday 4 March while we install the latest upgrade to the CHRIS system.

View all news