]> jfr.im git - irc/rizon/acid.git/blob - pyva/src/main/python/limitserv/limitmanager.py
.gitignore: Ignore all pyva logs
[irc/rizon/acid.git] / pyva / src / main / python / limitserv / limitmanager.py
1 import task
2 import time
3 from datetime import datetime
4 from collections import deque
5
6 class LimitManager(object):
7 def __init__(self, module):
8 self.module = module
9 self._queue = deque()
10 self._delay = self.module.options.get('delay', int, 60)
11 self._monitor = None
12
13 def insert(self, channel):
14 """Someone joined or left a channel, wait DELAY seconds then fix the limit.
15 """
16 self.module.elog.debug('Added: %s' % channel)
17 self._queue.append({'channel': channel, 'time': datetime.now()})
18
19 def queue_monitor(self):
20 """Loops over the queue every second to check for channels to be updated.
21 """
22 while self._queue and (datetime.now() - self._queue[0]['time']).seconds >= self._delay:
23 element = self._queue.popleft()
24 self.update_channel(element['channel'])
25
26 def start(self):
27 """Starts the queue monitor.
28 """
29 self._monitor = task.LoopingCall(self.queue_monitor)
30 self._monitor.start(1, True)
31
32 def stop(self):
33 """Stops the queue monitor.
34 """
35 self._monitor.stop()
36
37 def set_delay(self, new_delay):
38 """Changes interval between channel checks.
39 """
40 if self._delay == new_delay:
41 return
42
43 self.stop()
44 self._delay = new_delay
45 self.module.options.set('delay', new_delay)
46 self.start()
47
48 def update_channel(self, channel):
49 """Updates the limit for a channel,
50 the new limit depends on the amount of users.
51 """
52 chan = self.module.inter.findChannel(channel)
53 if not chan:
54 return
55 cname = chan.getName()
56
57 if not self.module.channels.is_valid(cname):
58 return
59
60 old_limit = chan.getLimit()
61 users = chan.getUsers().size()
62
63 if users < 100:
64 new_limit = users + 5
65 elif users < 300:
66 new_limit = users + 8
67 elif users < 500:
68 new_limit = users + 10
69 else:
70 new_limit = users + 12
71
72 if new_limit == old_limit or abs(new_limit - old_limit) < 2: #change mode only if the difference is >= 2
73 return
74
75 self.module.inter.mode(self.module.nick, cname, "+l %d" % new_limit)
76 self.module.elog.command('%(chan)s [%(users)d users] Changed limit %(old_limit)d => %(new_limit)d' % {
77 'chan': cname,
78 'users': users,
79 'old_limit': old_limit,
80 'new_limit': new_limit})
81
82 def resync(self):
83 """"Sets correct limits for all channels we joined,
84 only used when the bot is loaded.
85 """
86 for channel in self.module.channels.list_valid():
87 self.update_channel(channel.name)
88
89 def __contains__(self, channel):
90 """Checks if the channel is already queued for updating.
91 """
92 for element in self._queue:
93 if element['channel'].lower() == channel.lower():
94 return True
95
96 return False
97
98 def __len__(self):
99 return len(self._queue)