aboutsummaryrefslogtreecommitdiff
path: root/src/Timers.py
blob: 57bcc6fe1a1cd4619f72862558a960030d15eca6 (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
import time, uuid

class Timer(object):
    def __init__(self, id, context, name, delay, next_due, kwargs):
        self.id = id
        self.context = context
        self.name = name
        self.delay = delay
        if next_due:
            self.next_due = next_due
        else:
            self.set_next_due()
        self.kwargs = kwargs
        self._done = False

    def set_next_due(self):
        self.next_due = time.time()+self.delay
    def due(self):
        return self.time_left() <= 0
    def time_left(self):
        return self.next_due-time.time()

    def redo(self):
        self._done = False
        self.set_next_due()
    def finish(self):
        self._done = True
    def done(self):
        return self._done

class TimersContext(object):
    def __init__(self, parent, context):
        self._parent = parent
        self.context = context
    def add(self, name, delay, next_due=None, **kwargs):
        self._parent._add(self.context, name, delay, next_due, None, False,
            kwargs)
    def add_persistent(self, name, delay, next_due=None, **kwargs):
        self._parent._add(None, name, delay, next_due, None, True,
            kwargs)

class Timers(object):
    def __init__(self, database, events, log):
        self.database = database
        self.events = events
        self.log = log
        self.timers = []
        self.context_timers = {}

    def new_context(self, context):
        return TimersContext(self, context)

    def setup(self, timers):
        for name, timer in timers:
            id = name.split("timer-", 1)[1]
            self._add(timer["name"], None, timer["delay"], timer[
                "next-due"], id, False, timer["kwargs"])

    def _persist(self, timer):
        self.database.bot_settings.set("timer-%s" % timer.id, {
            "name": timer.name, "delay": timer.delay,
            "next-due": timer.next_due, "kwargs": timer.kwargs})
    def _remove(self, timer):
        if timer.context:
            self.context_timers[timer.context].remove(timer)
            if not self.context_timers[timer.context]:
                del self.context_timers[timer.conteext]
        else:
            self.timers.remove(timer)
        self.database.bot_settings.delete("timer-%s" % timer.id)

    def add(self, name, delay, next_due=None, **kwargs):
        self._add(None, name, delay, next_due, None, False, kwargs)
    def add_persistent(self, name, delay, next_due=None, **kwargs):
        self._add(None, name, delay, next_due, None, True, kwargs)
    def _add(self, context, name, delay, next_due, id, persist, kwargs):
        id = id or uuid.uuid4().hex
        timer = Timer(id, context, name, delay, next_due, kwargs)
        if persist:
            self._persist(timer)

        if context and not persist:
            if not context in self.context_timers:
                self.context_timers[context] = []
            self.context_timers[context].append(timer)
        else:
            self.timers.append(timer)

    def next(self):
        times = filter(None, [timer.time_left() for timer in self.get_timers()])
        if not times:
            return None
        return max(min(times), 0)

    def get_timers(self):
        return self.timers + sum(self.context_timers.values(), [])

    def call(self):
        for timer in self.get_timers():
            if timer.due():
                timer.finish()
                self.events.on("timer.%s" % timer.name).call(timer=timer,
                    **timer.kwargs)
                if timer.done():
                    self._remove(timer)

    def purge_context(self, context):
        if context in self.context_timers:
            del self.context_timers[context]