aboutsummaryrefslogtreecommitdiff
path: root/modules/auto_mode.py
blob: fd01f78748b2dae323b7e8b325fdcf7a1cc53a86 (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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
from src import ModuleManager, utils

@utils.export("channelset", {"setting": "automode",
    "help": "Disable/Enable automode", "validate": utils.bool_or_none,
    "example": "on"})
class Module(ModuleManager.BaseModule):
    _name = "AutoMode"

    def _get_modes(self, channel, user):
        identified_account = user.get_identified_account()
        if identified_account and channel.get_setting("automode", False):
            modes = channel.get_user_setting(user.get_id(), "automodes", [])
            return modes
        return []
    def _check_modes(self, channel, user):
        modes = self._get_modes(channel, user)
        if modes:
            current_modes = channel.get_user_status(user)
            new_modes = set(modes)-current_modes
            channel.send_mode("+%s" % "".join(new_modes),
                [user.nickname for mode in new_modes])

    @utils.hook("received.join")
    def on_join(self, event):
        self._check_modes(event["channel"], event["user"])
    @utils.hook("received.account.login")
    @utils.hook("internal.identified")
    def on_account(self, event):
        for channel in event["user"].channels:
            self._check_modes(channel, event["user"])

    def _check_channel(self, channel):
        modes = []
        for user in channel.users:
            user_modes = self._get_modes(channel, user)
            for user_mode in user_modes:
                if not channel.has_mode(user, user_mode):
                    modes.append([user_mode, user.nickname])

        # break up in to chunks of (maximum) 3
        # https://tools.ietf.org/html/rfc2812.html#section-3.2.3
        mode_chunks = [modes[i:i+3] for i in range(0, len(modes), 3)]
        for chunk in mode_chunks:
            modes = [item[0] for item in chunk]
            nicknames = [item[1] for item in chunk]
            channel.send_mode(
                "+%s" % "".join(modes), nicknames)
    @utils.hook("received.command.syncmodes", channel_only=True)
    def sync_modes(self, event):
        """
        :help: Check/sync user modes
        :require_mode: o
        :require_access: syncmodes
        """
        self._check_channel(event["target"])

    @utils.hook("set.channelset.automode")
    def on_automode_set(self, event):
        if event["value"]:
            self._check_channel(event["target"])

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

    def _add_mode(self, event, mode, mode_name):
        target_user = event["server"].get_user(event["args_split"][0])
        automodes = event["target"].get_user_setting(target_user.get_id(),
            "automodes", [])
        if mode in automodes:
            event["stderr"].write("'%s' already has automode %s" % (
                target_user.nickname, mode_name))
        else:
            automodes.append(mode)
            event["target"].set_user_setting(target_user.get_id(), "automodes",
                automodes)
            if event["target"] in target_user.channels:
                self._check_modes(event["target"], target_user)

            event["stdout"].write("Added automode %s for '%s'" % (
                mode_name, target_user.nickname))
    def _remove_mode(self, event, mode, mode_name):
        target_user = event["server"].get_user(event["args_split"][0])
        automodes = event["target"].get_user_setting(target_user.get_id(),
            "automodes", [])
        if not mode in automodes:
            event["stderr"].write("'%s' doesn't have automode %s" % (
                target_user.nickname, mode_name))
        else:
            automodes.remove(mode)
            if automodes:
                event["target"].set_user_setting(target_user.get_id(),
                    "automodes", automodes)
            else:
                event["target"].del_user_setting(target_user.get_id(),
                    "automodes")
            event["stdout"].write("Removed automode %s from '%s'" % (
                mode_name, target_user.nickname))

    @utils.hook("received.command.addop", min_args=1, channel_only=True)
    def add_op(self, event):
        """
        :help: Add a user to the auto-mode list as an op
        :usage: <nickname>
        :require_mode: o
        :require_access: autoop
        """
        self._add_mode(event, "o", "op")
    @utils.hook("received.command.removeop", min_args=1, channel_only=True)
    def remove_op(self, event):
        """
        :help: Remove a user from the auto-mode list as an op
        :usage: <nickname>
        :require_mode: o
        :require_access: autoop
        """
        self._remove_mode(event, "o", "op")

    @utils.hook("received.command.addvoice", min_args=1, channel_only=True)
    def add_voice(self, event):
        """
        :help: Add a user to the auto-mode list as a voice
        :usage: <nickname>
        :require_mode: o
        :require_access: autovoice
        """
        self._add_mode(event, "v", "voice")
    @utils.hook("received.command.removevoice", min_args=1, channel_only=True)
    def remove_voice(self, event):
        """
        :help: Remove a user from the auto-mode list as a voice
        :usage: <nickname>
        :require_mode: o
        :require_access: autovoice
        """
        self._remove_mode(event, "v", "voice")