aboutsummaryrefslogtreecommitdiffstats
path: root/cleanup.py
blob: 60eb6ad6d346dc167afff43266192b9276f584d2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#!/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()