refactor tsstats.client.Clients

* use collections.MutableMapping as base
* use one dict to store all types of Clients
* don't use implicit += but explicit .setdefault in tsstats.log for client-adding
* give all clients to sort_clients in tsstats.template
* remove now unneccessary clients-assignment in tsstats.utils.sort_clients
This commit is contained in:
Thor77 2016-05-18 22:42:42 +02:00
parent 89dc96dc99
commit 216bedc38f
4 changed files with 38 additions and 58 deletions

View File

@ -1,76 +1,53 @@
import logging
from tsstats.exceptions import InvalidLog
from collections import MutableMapping
logger = logging.getLogger('tsstats')
class Clients(object):
class Clients(MutableMapping):
'''
Clients provides high-level-access to multiple Client-objects
A high-level-interface to multiple Client-objects
'''
def __init__(self, ident_map={}):
def __init__(self, ident_map=None, *args, **kwargs):
'''
Initialize a new Client-collection
:param ident_map: Identity-map (see :ref:`IdentMap`)
:type ident_map: dict
'''
self.clients_by_id = {}
self.clients_by_uid = {}
self.ident_map = ident_map
self.ident_map = ident_map or {}
def is_id(self, id_or_uid):
try:
int(id_or_uid)
return True
except ValueError:
return False
self.store = dict()
self.update(dict(*args, **kwargs))
def __add__(self, id_or_uid):
def __add__(self, client):
'''
Add a Client to the collection
:param id_or_uid: id or uid of the Client
:type id_or_uid: int or str
:param client: Client to add to the collection
:type id_or_uid: Client
'''
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):
'''
Get a Client from the collection
:param id_or_uid: id or uid of the Client
:type id_or_uid: int or str
'''
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]
self.store[client.identifier] = client
def __iter__(self):
'''
Yield all Client-objects from the collection
clients by uid following clients by id
'''
for id_client in self.clients_by_id.values():
yield id_client
for uid_client in self.clients_by_uid.values():
yield uid_client
return iter(self.store.values())
def __getitem__(self, key):
return self.store[key]
def __delitem__(self, key):
del self.store[key]
def __len__(self):
return len(self.store)
def __setitem__(self, key, value):
self.store[key] = value
class Client(object):
@ -151,6 +128,9 @@ class Client(object):
return '<{},{}>'.format(self.identifier, self.nick)
def __getitem__(self, item):
'''
DEPRECATED
'''
return {
'identifier': self.identifier,
'nick': self.nick,

View File

@ -3,7 +3,7 @@ import re
from datetime import datetime
from glob import glob
from tsstats.client import Clients
from tsstats.client import Client, Clients
re_dis_connect = re.compile(r"'(.*)'\(id:(\d*)\)")
re_disconnect_invoker = re.compile(
@ -34,18 +34,19 @@ def parse_logs(log_path, ident_map={}):
if data.startswith('client'):
nick, clid = re_dis_connect.findall(data)[0]
if data.startswith('client connected'):
client = clients[clid]
client = clients.setdefault(clid, Client(clid))
client.nick = nick
client.connect(logdatetime)
elif data.startswith('client disconnected'):
client = clients[clid]
client = clients.setdefault(clid, Client(clid))
client.nick = nick
client.disconnect(logdatetime)
if 'invokeruid' in data:
re_disconnect_data = re_disconnect_invoker.findall(
data)
invokernick, invokeruid = re_disconnect_data[0]
invoker = clients[invokeruid]
invoker = clients.setdefault(invokeruid,
Client(invokeruid))
invoker.nick = invokernick
if 'bantime' in data:
invoker.ban(client)

View File

@ -12,16 +12,16 @@ logger = logging.getLogger('tsstats')
def render_template(clients, output, template_name='tsstats/template.html',
title='TeamspeakStats'):
# prepare clients
clients_onlinetime_ = sort_clients(clients.clients_by_id, 'onlinetime')
clients_onlinetime_ = sort_clients(clients, 'onlinetime')
clients_onlinetime = [
(client, seconds_to_text(onlinetime))
for client, onlinetime in clients_onlinetime_
]
clients_kicks = sort_clients(clients.clients_by_uid, 'kicks')
clients_pkicks = sort_clients(clients.clients_by_id, 'pkicks')
clients_bans = sort_clients(clients.clients_by_uid, 'bans')
clients_pbans = sort_clients(clients.clients_by_id, 'pbans')
clients_kicks = sort_clients(clients, 'kicks')
clients_pkicks = sort_clients(clients, 'pkicks')
clients_bans = sort_clients(clients, 'bans')
clients_pbans = sort_clients(clients, 'pbans')
objs = [('Onlinetime', clients_onlinetime), ('Kicks', clients_kicks),
('passive Kicks', clients_pkicks),
('Bans', clients_bans), ('passive Bans', clients_pbans)]

View File

@ -1,5 +1,4 @@
def sort_clients(stor, key):
clients = stor.values()
def sort_clients(clients, key):
cl_data = [(client, client[key]) for client in clients if client[key] > 0]
return sorted(cl_data, key=lambda data: data[1], reverse=True)