115 lines
3.2 KiB
Python
115 lines
3.2 KiB
Python
|
import logging
|
||
|
|
||
|
from tsstats.exceptions import InvalidLog
|
||
|
|
||
|
|
||
|
class Clients:
|
||
|
|
||
|
def __init__(self, ident_map={}):
|
||
|
self.clients_by_id = {}
|
||
|
self.clients_by_uid = {}
|
||
|
self.ident_map = ident_map
|
||
|
|
||
|
def is_id(self, id_or_uid):
|
||
|
try:
|
||
|
int(id_or_uid)
|
||
|
return True
|
||
|
except ValueError:
|
||
|
return False
|
||
|
|
||
|
def __add__(self, id_or_uid):
|
||
|
if self.is_id(id_or_uid):
|
||
|
if id_or_uid not in self.clients_by_id:
|
||
|
self.clients_by_id[id_or_uid] = Client(id_or_uid)
|
||
|
else:
|
||
|
if id_or_uid not in self.clients_by_uid:
|
||
|
self.clients_by_uid[id_or_uid] = Client(id_or_uid)
|
||
|
return self
|
||
|
|
||
|
def __getitem__(self, id_or_uid):
|
||
|
if id_or_uid in self.ident_map:
|
||
|
id_or_uid = self.ident_map[id_or_uid]
|
||
|
if self.is_id(id_or_uid):
|
||
|
if id_or_uid not in self.clients_by_id:
|
||
|
self += id_or_uid
|
||
|
return self.clients_by_id[id_or_uid]
|
||
|
else:
|
||
|
if id_or_uid not in self.clients_by_uid:
|
||
|
self += id_or_uid
|
||
|
return self.clients_by_uid[id_or_uid]
|
||
|
|
||
|
def __iter__(self):
|
||
|
for id_client in self.clients_by_id.values():
|
||
|
yield id_client
|
||
|
for uid_client in self.clients_by_uid.values():
|
||
|
yield uid_client
|
||
|
|
||
|
|
||
|
class Client:
|
||
|
|
||
|
def __init__(self, identifier):
|
||
|
# public
|
||
|
self.identifier = identifier
|
||
|
self.nick = None
|
||
|
self.connected = 0
|
||
|
self.onlinetime = 0
|
||
|
self.kicks = 0
|
||
|
self.pkicks = 0
|
||
|
self.bans = 0
|
||
|
self.pbans = 0
|
||
|
self.last_seen = 0
|
||
|
# private
|
||
|
self._last_connect = 0
|
||
|
|
||
|
def connect(self, timestamp):
|
||
|
'''
|
||
|
client connects at "timestamp"
|
||
|
'''
|
||
|
logging.debug('CONNECT {}'.format(str(self)))
|
||
|
self.connected += 1
|
||
|
self._last_connect = timestamp
|
||
|
|
||
|
def disconnect(self, timestamp):
|
||
|
'''
|
||
|
client disconnects at "timestamp"
|
||
|
'''
|
||
|
logging.debug('DISCONNECT {}'.format(str(self)))
|
||
|
if not self.connected:
|
||
|
logging.debug('^ disconnect before connect')
|
||
|
raise InvalidLog('disconnect before connect!')
|
||
|
self.connected -= 1
|
||
|
session_time = timestamp - self._last_connect
|
||
|
self.onlinetime += session_time
|
||
|
self.last_seen = timestamp
|
||
|
|
||
|
def kick(self, target):
|
||
|
'''
|
||
|
client kicks "target" (Client-obj)
|
||
|
'''
|
||
|
logging.debug('KICK {} -> {}'.format(str(self), str(target)))
|
||
|
target.pkicks += 1
|
||
|
self.kicks += 1
|
||
|
|
||
|
def ban(self, target):
|
||
|
'''
|
||
|
client bans "target" (Client-obj)
|
||
|
'''
|
||
|
logging.debug('BAN {} -> {}'.format(str(self), str(target)))
|
||
|
target.pbans += 1
|
||
|
self.bans += 1
|
||
|
|
||
|
def __str__(self):
|
||
|
return '<{},{}>'.format(self.identifier, self.nick)
|
||
|
|
||
|
def __getitem__(self, item):
|
||
|
return {
|
||
|
'identifier': self.identifier,
|
||
|
'nick': self.nick,
|
||
|
'connected': self.connected,
|
||
|
'onlinetime': self.onlinetime,
|
||
|
'kicks': self.kicks,
|
||
|
'pkicks': self.pkicks,
|
||
|
'bans': self.bans,
|
||
|
'pbans': self.pbans,
|
||
|
}[item]
|