aboutsummaryrefslogtreecommitdiff
path: root/src/core_modules/mode_lists.py
blob: 3791860896284fc6146de920b9876b94466b7eba (about) (plain) (blame)
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
from src import ModuleManager, utils

class Module(ModuleManager.BaseModule):
    # RPL_BANLIST
    @utils.hook("received.367")
    def on_367(self, event):
        self._mode_list_mask(event, "b", event["line"].args[2])
    @utils.hook("received.368")
    def on_368(self, event):
        self._mode_list_end(event, "b")

    # RPL_QUIETLIST
    @utils.hook("received.728")
    def on_728(self, event):
        mode = event["line"].args[2]
        self._mode_list_mask(event, mode, event["line"].args[3])
    @utils.hook("received.729")
    def on_729(self, event):
        self._mode_list_end(event, event["line"].args[2])

    def _excepts(self, server):
        return server.isupport.get("EXCEPTS", None) or "e"
    # RPL_EXCEPTLIST
    @utils.hook("received.348")
    def on_348(self, event):
        mode = self._excepts(event["server"])
        self._mode_list_mask(event, mode, event["line"].args[2])
    @utils.hook("received.349")
    def on_349(self, event):
        self._mode_list_end(event, self._excepts(event["server"]))

    def _invex(self, server):
        return server.isupport.get("INVEX", None) or "I"
    # RPL_INVITELIST
    @utils.hook("received.346")
    def on_346(self, event):
        mode = self._invex(event["server"])
        self._mode_list_mask(event, mode, event["line"].args[2])
    @utils.hook("received.347")
    def on_347(self, event):
        self._mode_list_end(event, self._invex(event["server"]))

    def _channel(self, event):
        target = event["line"].args[1]
        if target in event["server"].channels:
            return event["server"].channels.get(target)
        return None

    def _mode_list_mask(self, event, mode, mask):
        channel = self._channel(event)
        if channel:
            self._mask_add(channel, "~%s" % mode, mask)
    def _mode_list_end(self, event, mode):
        channel = self._channel(event)
        if channel:
            temp_key = "~%s" % mode
            if temp_key in channel.mode_lists:
                channel.mode_lists[mode] = channel.mode_lists.pop(temp_key)
            else:
                channel.mode_lists[mode] = set([])

    def _mask_add(self, channel, mode, mask):
        if not mode in channel.mode_lists:
            channel.mode_lists[mode] = set([])
        channel.mode_lists[mode].add(mask)
    def _mask_remove(self, channel, mode, mask):
        if mode in channel.mode_lists:
            channel.mode_lists[mode].discard(mask)

    @utils.hook("received.mode.channel")
    def channel_mode_lists(self, event):
        for mode, arg in event["modes"]:
            if mode[1] in event["server"].channel_list_modes:
                if mode[0] == "+":
                    self._mask_add(event["channel"], mode[1], arg)
                else:
                    self._mask_remove(event["channel"], mode[1], arg)
            elif mode[1] in dict(event["server"].prefix_modes):
                if (event["server"].irc_equals(event["server"].nickname, arg)
                        and event["channel"].seen_modes):
                    self._query_lists(event["server"], event["channel"])


    def _query_lists(self, server, channel):
        seen = set(k.lstrip("~") for k in channel.mode_lists.keys())
        missing = set(server.channel_list_modes)-seen
        if missing:
            channel.send_mode("+%s" % "".join(missing))

    @utils.hook("self.join")
    def self_join(self, event):
        self._query_lists(event["server"], event["channel"])