#!/usr/bin/env python3 # -*- coding: utf-8 -*- import datetime import logging from calls import EjabberdApiCalls class EjabberdCleanup(EjabberdApiCalls): def __init__(self, url, login, api): super().__init__(url, login, api) self.ignore_hosts = [] self.ignore_usernames = [] self.dry = False self.skip_by_roster = True self.delete_not_login = True self.offline_since_days = None def calc_time_before(self): return datetime.datetime.now() - datetime.timedelta(days=self.offline_since_days); def delete_user(self, host, user, reason=""): if self.dry: logging.warning(f"{user}@{host}: dry delete : {reason}") else: self.cmd("unregister", {"host": host, "user": user}) logging.warning(f"{user}@{host}: deleted - {reason}") def run_user(self, host, user): if self.skip_by_roster: roster = self.cmd("get_roster", {"host": host, "user": user}) if len(roster) > 0: logging.debug(f"{user}@{host}: skipped it has a roster") return last = self.cmd("get_last", {"host": host, "user": user}) if self.delete_not_login and last["status"] == "Registered but didn't login": self.delete_user(host, user, "not login") return if self.offline_since_days is not None: last_stamp = last["timestamp"] lastdate = None try: lastdate = datetime.datetime.strptime(last_stamp, "%Y-%m-%dT%H:%M:%SZ") except ValueError: try: lastdate = datetime.datetime.strptime(last_stamp, "%Y-%m-%dT%H:%M:%S.%fZ") except ValueError as err: logging.error(f"{user}@{host}: not able to parse '{last_stamp}': {err}") return if lastdate is None: logging.error(f"{user}@{host}: not able to parse '{last_stamp}'") return elif lastdate < self.calc_time_before(): self.delete_user(host, user, f"last seen @ {lastdate}") return else: logging.debug(f"{user}@{host}: keep @ {lastdate}") return logging.debug(f"{user}@{host}: keep") def run(self): logging.debug("run with:") logging.debug(f"dry: {self.dry}") logging.debug(f"skip by roster: {self.skip_by_roster}") logging.debug(f"delete not login: {self.delete_not_login}") logging.debug(f"offline since days: {self.offline_since_days}") for host in self.fetch_vhosts(): if host in self.ignore_hosts: continue logging.info(f"run cleanup for host: {host}") for user in self.cmd("registered_users", {"host": host}): if user in self.ignore_usernames: continue self.run_user(host, user) if __name__ == "__main__": from config import Config # load config config = Config() if config.get("debug", default=False): logging.getLogger().setLevel(logging.DEBUG) # credentials and parameters url = config.get("url", default="http://localhost:5280/api") login = config.get("login", default=None) api = config.get("api", default="rest") # init handler cleaner = EjabberdCleanup(url, login, api) cleaner.dry = config.get("cleaner_dry", default=False) cleaner.ignore_hosts = config.get("cleaner_ignore_hosts", default=[]) cleaner.ignore_usernames = config.get("cleaner_ignore_usernames", default=[]) cleaner.skip_by_roster = config.get("cleaner_skip_by_roster", default=True) cleaner.delete_not_login = config.get("cleaner_delete_not_login", default=True) cleaner.offline_since_days = config.get("cleaner_offline_since_days", default=None) cleaner.run()