From 216bedc38f6e17b4f64ce55406ca3962bab9a30b Mon Sep 17 00:00:00 2001 From: Thor77 Date: Wed, 18 May 2016 22:42:42 +0200 Subject: [PATCH] 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 --- tsstats/client.py | 74 +++++++++++++++++---------------------------- tsstats/log.py | 9 +++--- tsstats/template.py | 10 +++--- tsstats/utils.py | 3 +- 4 files changed, 38 insertions(+), 58 deletions(-) diff --git a/tsstats/client.py b/tsstats/client.py index 9d91350..e8f49bf 100644 --- a/tsstats/client.py +++ b/tsstats/client.py @@ -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, diff --git a/tsstats/log.py b/tsstats/log.py index 3a52d82..fa56516 100644 --- a/tsstats/log.py +++ b/tsstats/log.py @@ -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) diff --git a/tsstats/template.py b/tsstats/template.py index 9b93e47..2dc7b42 100644 --- a/tsstats/template.py +++ b/tsstats/template.py @@ -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)] diff --git a/tsstats/utils.py b/tsstats/utils.py index 67cd0cb..c3fecab 100644 --- a/tsstats/utils.py +++ b/tsstats/utils.py @@ -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)