aboutsummaryrefslogtreecommitdiff
path: root/modules/relay.py
blob: 71a45e42f353c72af82c0fc23626d4d4f9562138 (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
137
138
139
140
141
142
143
144
145
146
147
148
#--depends-on commands
#--depends-on format_activity
#--depends-on permissions

from src import EventManager, ModuleManager, utils

@utils.export("channelset", utils.BoolSetting("relay-extras",
    "Whether or not to relay joins/parts/quits/modes/etc"))
class Module(ModuleManager.BaseModule):
    @utils.hook("new.server")
    def new_server(self, event):
        event["server"]._relay_ignore = []

    def _get_relays(self, channel):
        return channel.get_setting("channel-relays", [])

    def _relay(self, event, channel):
        if ("parsed_line" in event and
                event["parsed_line"].id in event["server"]._relay_ignore):
            event["server"]._relay_ignore.remove(event["parsed_line"].id)
            return

        relays = {}
        for relay_group in channel.get_setting("relay-groups", []):
            targets = self.bot.get_setting("relay-group-%s" % relay_group, [])
            for server_id, channel_name in targets:
                server = self.bot.get_server_by_id(server_id)
                if server and channel_name in server.channels:
                    relay_channel = server.channels.get(channel_name)
                    if (not server.id == event["server"].id and
                            not channel.id == relay_channel.id):
                        if not server in relays:
                            relays[server] = []
                        if not relay_channel in relays[server]:
                            relays[server].append(relay_channel)

        for server in relays.keys():
            for relay_channel in relays[server]:
                relay_prefix_channel = ""
                if not relay_channel.name == channel.name:
                    relay_prefix_channel = channel.name

                server_name = utils.irc.color(str(event["server"]),
                    utils.consts.LIGHTBLUE)
                server_name = "%s%s" % (server_name, utils.consts.RESET)
                relay_message = "[%s%s] %s" % (server_name,
                    relay_prefix_channel, event["line"])

                message = utils.irc.protocol.privmsg(relay_channel.name,
                    relay_message)
                server._relay_ignore.append(message.id)
                self.bot.trigger(self._send_factory(server, message))

    def _send_factory(self, server, message):
        return lambda: server.send(message)

    @utils.hook("formatted.message.channel")
    @utils.hook("formatted.notice.channel")
    @utils.kwarg("priority", EventManager.PRIORITY_LOW)
    def formatted(self, event):
        self._relay(event, event["channel"])

    @utils.hook("formatted.join")
    @utils.hook("formatted.part")
    @utils.hook("formatted.nick")
    @utils.hook("formatted.mode.channel")
    @utils.hook("formatted.kick")
    @utils.hook("formatted.quit")
    @utils.hook("formatted.rename")
    @utils.kwarg("priority", EventManager.PRIORITY_LOW)
    def formatted_extra(self, event):
        if event["channel"]:
            if event["channel"].get_setting("relay-extras", False):
                self._relay(event, event["channel"])
        elif event["user"]:
            for channel in event["user"].channels:
                if channel.get_setting("relay-extras", False):
                    self._relay(event, channel)

    @utils.hook("received.command.relaygroup")
    @utils.kwarg("min_args", 1)
    @utils.kwarg("help", "Edit configured relay groups")
    @utils.kwarg("usage", "list")
    @utils.kwarg("usage", "add <name>")
    @utils.kwarg("usage", "remove <name>")
    @utils.kwarg("usage", "join <name>")
    @utils.kwarg("usage", "leave <name>")
    @utils.kwarg("permission", "relay")
    def relay_group(self, event):
        subcommand = event["args_split"][0].lower()

        group_settings = self.bot.find_settings_prefix("relay-group-")
        groups = {}
        for setting, value in group_settings:
            name = setting.replace("relay-group-", "", 1)
            groups[name] = value

        if subcommand == "list":
            event["stdout"].write("Relay groups: %s" % ", ".join(groups.keys()))
            return

        if not len(event["args_split"]) > 1:
            raise utils.EventError("Please provide a group name")

        name = event["args_split"][1].lower()

        event["check_assert"](utils.Check("is-channel"))
        current_channel = [event["server"].id, event["target"].name]
        channel_groups = event["target"].get_setting("relay-groups", [])

        message = None
        remove = False

        if subcommand == "join":
            if not name in groups:
                groups[name] = []

            if current_channel in groups[name] or name in channel_groups:
                raise utils.EventError("Already joined group '%s'" % name)

            groups[name].append(current_channel)
            channel_groups.append(name)
            message = "Joined"

        elif subcommand == "leave":
            if (not name in groups or
                    not current_channel in groups[name] or
                    not name in channel_groups):
                raise utils.EventError("Not in group '%s'" % name)

            groups[name].remove(current_channel)
            channel_groups.remove(name)
            message = "Left"
        else:
            raise utils.EventError("Unknown subcommand '%s'" % subcommand)

        if not message == None:
            if not groups[name]:
                self.bot.del_setting("relay-group-%s" % name)
            else:
                self.bot.set_setting("relay-group-%s" % name, groups[name])

            if channel_groups:
                event["target"].set_setting("relay-groups", channel_groups)
            else:
                event["target"].del_setting("relay-groups")

            event["stdout"].write("%s group '%s'" % (message, name))