100 lines
3.8 KiB
Python
Executable File
100 lines
3.8 KiB
Python
Executable File
#!/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()
|