aboutsummaryrefslogtreecommitdiff
path: root/modules/ircv3_resume.py
blob: 6c36831676c77545cf39a6fcc3071d64ea57a533 (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
#--depends-on ircv3_server_time

from src import ModuleManager, utils

CAP = utils.irc.Capability(None, "draft/resume-0.5", alias="resume")

class Module(ModuleManager.BaseModule):
    def _setting(self, new):
        return "resume-token%s" % ("-new" if new else "")
    def _get_token(self, server, new=False):
        return server.get_setting(self._setting(new), None)
    def _set_token(self, server, token, new=False):
        server.set_setting(self._setting(new), token)
    def _del_token(self, server, new=False):
        server.del_setting(self._setting(new))


    @utils.hook("new.server")
    def new_server(self, event):
        # we need to pull this before any data has been exchanged - to make sure
        # it's not overwritten from the last connection
        event["server"]._resume_timestamp = event["server"].get_setting(
            "last-server-time", None)

    @utils.hook("received.cap.ls")
    def on_cap_ls(self, event):
        cap = CAP.copy()
        cap.on_ack(lambda: self._cap_ack(event["server"]))
        return cap

    def _cap_ack(self, server):
        server.wait_for_capability("resume")

    @utils.hook("received.resume")
    def on_resume(self, event):
        cap_done = True

        if event["line"].args[0] == "SUCCESS":
            resume_channels = event["server"].get_setting("resume-channels", [])
            self.log.info("Successfully resumed session")
            event["server"].clear_waiting_capabilities()

        elif event["line"].args[0] == "TOKEN":
            token = self._get_token(event["server"])
            self._set_token(event["server"], event["line"].args[1], new=True)

            if token:
                timestamp = event["server"]._resume_timestamp

                event["server"].send_raw("RESUME %s%s" %
                    (token, " %s" % timestamp if timestamp else ""))
                cap_done = False

        if cap_done:
            event["server"].capability_done("resume")


    @utils.hook("received.001")
    def on_connect(self, event):
        event["server"].del_setting("resume-channels")

        new_token = self._get_token(event["server"], new=True)
        if new_token:
            self._set_token(event["server"], new_token)
            self._del_token(event["server"], new=True)

    @utils.hook("self.join")
    def on_join(self, event):
        resume_channels = event["server"].get_setting("resume-channels", [])
        channel_name = event["server"].irc_lower(event["channel"].name)
        if not channel_name in resume_channels:
            resume_channels.append(channel_name)
            event["server"].set_setting("resume-channels", resume_channels)

    @utils.hook("preprocess.send.quit")
    def preprocess_send(self, event):
        if event["line"].command == "QUIT" and event["server"].has_capability(
                CAP):
            event["line"].command = "BRB"

    @utils.hook("received.fail.resume")
    def fail_resume(self, event):
        event["server"].capability_done("resume")