180 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			180 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from zeep.client import Client as ZeepClient, Settings as ZeepSettings
 | |
| 
 | |
| from sympasoap.lists import MailingList, MLUser
 | |
| 
 | |
| TOPICS = [
 | |
|     "art",
 | |
|     "business",
 | |
|     "computers",
 | |
|     "education",
 | |
|     "entertainment",
 | |
|     "government",
 | |
|     "health",
 | |
|     "news",
 | |
|     "recreation",
 | |
|     "science",
 | |
|     "social",
 | |
|     "society",
 | |
| ]
 | |
| 
 | |
| SUBTOPICS = [
 | |
|     "art/finearts",
 | |
|     "art/history",
 | |
|     "art/literature",
 | |
|     "art/photography",
 | |
|     "business/b2b",
 | |
|     "business/finance",
 | |
|     "business/jobs",
 | |
|     "business/shopping",
 | |
|     "computers/games",
 | |
|     "computers/hardware",
 | |
|     "computers/internet",
 | |
|     "computers/software",
 | |
|     "education/college",
 | |
|     "education/k12",
 | |
|     "entertainment/humour",
 | |
|     "entertainment/movies",
 | |
|     "entertainment/music",
 | |
|     "government/elections",
 | |
|     "government/law",
 | |
|     "government/military",
 | |
|     "government/taxes",
 | |
|     "health/diseases",
 | |
|     "health/drugs",
 | |
|     "health/fitness",
 | |
|     "health/medicine",
 | |
|     "news/multimedia",
 | |
|     "news/newspapers",
 | |
|     "news/radio",
 | |
|     "news/tv",
 | |
|     "recreation/autos",
 | |
|     "recreation/outdoors",
 | |
|     "recreation/sports",
 | |
|     "recreation/travel",
 | |
|     "science/animals",
 | |
|     "science/astronomy",
 | |
|     "science/engineering",
 | |
|     "social/archaeology",
 | |
|     "social/economics",
 | |
|     "social/languages",
 | |
|     "society/environment",
 | |
|     "society/people",
 | |
|     "society/religion",
 | |
| ]
 | |
| 
 | |
| 
 | |
| class Client:
 | |
|     def __init__(self, sympa_url: str):
 | |
|         self.sympa_url = sympa_url
 | |
|         self.zeep = ZeepClient(sympa_url + "/wsdl", settings=ZeepSettings(strict=False))
 | |
| 
 | |
|     def login(self, email: str, password: str) -> None:
 | |
|         """
 | |
|         Login into the API. Set a cookie for future connexions.
 | |
|         """
 | |
|         result = self.zeep.service.login(email, password)
 | |
|         element = result._raw_elements[0]
 | |
|         self.cookie = element.text
 | |
|         self.zeep.settings.extra_http_headers = [("Cookie", f"sympa_session={element.text}")]
 | |
|         if self.check_cookie() != email:
 | |
|             # FIXME Better exception
 | |
|             raise Exception("Unknown error: given cookie is invalid")
 | |
|         print("Successfully authenticated!")
 | |
| 
 | |
|     def check_cookie(self) -> str:
 | |
|         """
 | |
|         From the current cookie, retrieve the email address.
 | |
|         """
 | |
|         result = self.zeep.service.checkCookie()
 | |
|         element = result._raw_elements[0]
 | |
|         return element.text
 | |
| 
 | |
|     def is_subscriber(self, email: str, mailing_list: str, function: str = "subscriber") -> bool:
 | |
|         """
 | |
|         Check if the given `email` is a member of type `function` in the `mailing_list`.
 | |
|         The function parameter is one between subscriber, editor or owner.
 | |
|         """
 | |
|         if function not in ["subscriber", "editor", "owner"]:
 | |
|             raise ValueError("function of a mailing list member must be subscriber, editor or owner.")
 | |
|         result = self.zeep.service.amI(mailing_list, function, email)
 | |
|         element = result._raw_elements[0]
 | |
|         return element.text == "true"
 | |
| 
 | |
|     def get_subscribers(self, mailing_list: str, emails_only: bool = True) -> list:
 | |
|         """
 | |
|         Get the list of all subscribers of a list, including the administrators and the editors.
 | |
|         If emails_only == True, retrieve the list of email addresses only.
 | |
|         Else, retrieve MLUser object, with the name of the user and the role.
 | |
|         """
 | |
|         if not emails_only:
 | |
|             users = list()
 | |
|             elements = self.zeep.service.fullReview(mailing_list)
 | |
|             for element in elements:
 | |
|                 children = element.getchildren()
 | |
|                 kwargs = dict(mailing_list=mailing_list)
 | |
|                 for child in children:
 | |
|                     tag = child.tag
 | |
|                     if "gecos" in tag:
 | |
|                         kwargs["name"] = child.text
 | |
|                     elif "email" in tag:
 | |
|                         kwargs["email"] = child.text
 | |
|                     elif "isSubscriber" in tag:
 | |
|                         kwargs["subscriber"] = child.text == "true"
 | |
|                     elif "isEditor" in tag:
 | |
|                         kwargs["editor"] = child.text == "true"
 | |
|                     elif "isOwner" in tag:
 | |
|                         kwargs["owner"] = child.text == "true"
 | |
|                     else:
 | |
|                         print("Unknown child tag:", tag)
 | |
|                 user = MLUser(**kwargs)
 | |
|                 users.append(user)
 | |
|             return users
 | |
|         return self.zeep.service.review(mailing_list)
 | |
| 
 | |
|     def lists(self, topic: str, subtopic: str) -> list:
 | |
|         """
 | |
|         Get all the (visible) lists that match the given topic and the given subtopic.
 | |
|         See TOPICS and SUBTOPICS for valid topics and subtopics.
 | |
|         """
 | |
|         if topic not in TOPICS:
 | |
|             raise ValueError(f"'{topic}' is not a valid topic.")
 | |
|         if subtopic and f"{topic}/{subtopic}" not in SUBTOPICS:
 | |
|             raise ValueError(f"'{topic}/{subtopic}' is not a valid subtopic.")
 | |
|         result = self.zeep.service.lists(topic, subtopic)._value_1
 | |
|         if result is None:
 | |
|             return list()
 | |
|         lists = list()
 | |
|         for list_info in result:
 | |
|             split = list_info.split(';')
 | |
|             kwargs = dict()
 | |
|             for data in split:
 | |
|                 key, value = data.split("=", 2)
 | |
|                 if key == "listAddress":
 | |
|                     key = "list_address"
 | |
|                 kwargs[key] = value
 | |
|             ml = MailingList(**kwargs)
 | |
|             lists.append(ml)
 | |
|         return lists
 | |
| 
 | |
|     def all_lists(self) -> list:
 | |
|         """
 | |
|         Retrieve all lists.
 | |
|         """
 | |
|         elem = self.zeep.service.complexLists()._raw_elements[0]
 | |
|         lists = list()
 | |
|         for list_info in elem.getchildren():
 | |
|             kwargs = dict()
 | |
|             for child in list_info.getchildren():
 | |
|                 if "listAddress" in child.tag:
 | |
|                     key = "list_address"
 | |
|                 elif "subject" in child.tag:
 | |
|                     key = "subject"
 | |
|                 elif "homepage" in child.tag:
 | |
|                     key = "homepage"
 | |
|                 else:
 | |
|                     raise ValueError(f"Tag {child.tag} is unknown")
 | |
|                 kwargs[key] = child.text
 | |
|             ml = MailingList(**kwargs)
 | |
|             lists.append(ml)
 | |
|         return lists
 |