forked from shaba/openuds
fixed stats reports & related
This commit is contained in:
parent
6e7b5229d1
commit
f464d78f99
@ -45,7 +45,7 @@ import numpy as np
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def barChart(size: typing.Tuple[int, int, int], data: typing.Dict, output: typing.BinaryIO):
|
||||
def barChart(size: typing.Tuple[int, int, int], data: typing.Dict, output: typing.BinaryIO) -> None:
|
||||
d = data['x']
|
||||
ind = np.arange(len(d))
|
||||
ys = data['y']
|
||||
@ -77,7 +77,7 @@ def barChart(size: typing.Tuple[int, int, int], data: typing.Dict, output: typin
|
||||
fig.savefig(output, format='png', transparent=True)
|
||||
|
||||
|
||||
def lineChart(size: typing.Tuple[int, int, int], data: typing.Dict, output: typing.BinaryIO):
|
||||
def lineChart(size: typing.Tuple[int, int, int], data: typing.Dict, output: typing.BinaryIO) -> None:
|
||||
x = data['x']
|
||||
y = data['y']
|
||||
|
||||
@ -107,7 +107,7 @@ def lineChart(size: typing.Tuple[int, int, int], data: typing.Dict, output: typi
|
||||
fig.savefig(output, format='png', transparent=True)
|
||||
|
||||
|
||||
def surfaceChart(size: typing.Tuple[int, int, int], data: typing.Dict, output: typing.BinaryIO):
|
||||
def surfaceChart(size: typing.Tuple[int, int, int], data: typing.Dict, output: typing.BinaryIO) -> None:
|
||||
x = data['x']
|
||||
y = data['y']
|
||||
z = data['z']
|
||||
|
@ -48,13 +48,13 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Report(UserInterface):
|
||||
mime_type: str = 'application/pdf' # Report returns pdfs by default, but could be anything else
|
||||
name: str = _('Base Report') # Report name
|
||||
description: str = _('Base report') # Report description
|
||||
filename: str = 'file.pdf' # Filename that will be returned as 'hint' on rest report request
|
||||
group: str = '' # So we can "group" reports by kind?
|
||||
encoded: bool = True # If the report is mean to be encoded (binary reports as PDFs == True, text reports must be False so utf-8 is correctly threated
|
||||
uuid: str = ''
|
||||
mime_type: typing.ClassVar[str] = 'application/pdf' # Report returns pdfs by default, but could be anything else
|
||||
name: typing.ClassVar[str] = _('Base Report') # Report name
|
||||
description: typing.ClassVar[str] = _('Base report') # Report description
|
||||
filename: typing.ClassVar[str] = 'file.pdf' # Filename that will be returned as 'hint' on rest report request
|
||||
group: typing.ClassVar[str] = '' # So we can "group" reports by kind?
|
||||
encoded: typing.ClassVar[bool] = True # If the report is mean to be encoded (binary reports as PDFs == True, text reports must be False so utf-8 is correctly threated
|
||||
uuid: typing.ClassVar[str] = ''
|
||||
|
||||
@classmethod
|
||||
def translated_name(cls):
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2012 Virtual Cable S.L.
|
||||
# Copyright (c) 2012-2019 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -39,18 +39,12 @@ The registration of modules is done locating subclases of :py:class:`uds.core.au
|
||||
|
||||
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import six
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
__updated__ = '2018-02-07'
|
||||
|
||||
availableReports = []
|
||||
|
||||
|
||||
# noinspection PyTypeChecker
|
||||
def __init__():
|
||||
"""
|
||||
@ -62,25 +56,23 @@ def __init__():
|
||||
from uds.core import reports
|
||||
|
||||
def addReportCls(cls):
|
||||
logger.debug('Adding report {}'.format(cls))
|
||||
logger.debug('Adding report %s', cls)
|
||||
availableReports.append(cls)
|
||||
|
||||
def recursiveAdd(p):
|
||||
if p.uuid is not None:
|
||||
addReportCls(p)
|
||||
def recursiveAdd(reportClass):
|
||||
if reportClass.uuid:
|
||||
addReportCls(reportClass)
|
||||
else:
|
||||
logger.debug('Report class {} not added because it lacks of uuid (it is probably a base class)'.format(p))
|
||||
logger.debug('Report class %s not added because it lacks of uuid (it is probably a base class)', reportClass)
|
||||
|
||||
for c in p.__subclasses__():
|
||||
for c in reportClass.__subclasses__():
|
||||
recursiveAdd(c)
|
||||
|
||||
# Dinamycally import children of this package. The __init__.py files must import classes
|
||||
pkgpath = os.path.dirname(sys.modules[__name__].__file__)
|
||||
# TODO: Make this work with python3 also!!! (look for alternative, we have time...)
|
||||
for _, name, _ in pkgutil.iter_modules([pkgpath]):
|
||||
__import__(name, globals(), locals(), [], 1)
|
||||
|
||||
recursiveAdd(reports.Report)
|
||||
|
||||
|
||||
__init__()
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2015 Virtual Cable S.L.
|
||||
# Copyright (c) 2015-2019 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -31,4 +31,5 @@
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
|
||||
from .users import ListReportUsers, ListReportsUsersCSV
|
||||
# Make reports visible to autoloader
|
||||
from . import users
|
||||
|
@ -30,11 +30,14 @@
|
||||
"""
|
||||
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
import typing
|
||||
|
||||
from django.utils.translation import ugettext_noop as _
|
||||
from uds.core import reports
|
||||
|
||||
class ListReport(reports.Report):
|
||||
def generate(self):
|
||||
group = _('Lists') # So we can make submenus with reports
|
||||
|
||||
def generate(self) -> typing.Union[str, bytes]:
|
||||
raise NotImplementedError('ListReport generate invoked and not implemented')
|
||||
|
||||
group = _('Lists') # So we can make submenus with reports
|
||||
|
@ -31,16 +31,10 @@
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
|
||||
# We just need to import. Report loader will look for Report subclasses
|
||||
# Make reports visible to autoloader
|
||||
# from . import usage
|
||||
from uds.reports.stats import user_access
|
||||
from . import user_access
|
||||
from . import pools_performance
|
||||
from . import pools_usage_day
|
||||
from . import usage_by_pool
|
||||
from . import pool_usage_summary
|
||||
# from .user_access import StatsReportLogin, StatsReportLoginCSV
|
||||
# from .pools_performance import PoolPerformanceReport
|
||||
# from .pools_usage_day import CountersPoolAssigned
|
||||
# from .usage_by_pool import UsageByPool
|
||||
# from .pool_usage_summary import UsageSummaryByPool
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2015 Virtual Cable S.L.
|
||||
# Copyright (c) 2015-2019 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -30,16 +30,14 @@
|
||||
"""
|
||||
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
import typing
|
||||
|
||||
from django.utils.translation import ugettext_noop as _
|
||||
from uds.core import reports
|
||||
|
||||
__updated__ = '2018-02-07'
|
||||
|
||||
|
||||
class StatsReport(reports.Report):
|
||||
"""
|
||||
Base report for statistics reports
|
||||
"""
|
||||
group = _('Statistics') # So we can make submenus with reports
|
||||
|
||||
def generate(self) -> typing.Union[str, bytes]:
|
||||
raise NotImplementedError('StatsReport generate invoked and not implemented')
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2015 Virtual Cable S.L.
|
||||
# Copyright (c) 2015-2019 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -30,27 +30,22 @@
|
||||
"""
|
||||
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
import io
|
||||
import csv
|
||||
import datetime
|
||||
import logging
|
||||
import typing
|
||||
|
||||
from django.utils.translation import ugettext, ugettext_lazy as _
|
||||
|
||||
from uds.core.ui import gui
|
||||
from uds.core.util.stats import events
|
||||
|
||||
import io
|
||||
import csv
|
||||
from uds.models import ServicePool
|
||||
|
||||
from .base import StatsReport
|
||||
|
||||
from uds.models import ServicePool
|
||||
|
||||
import datetime
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
__updated__ = '2018-04-25'
|
||||
|
||||
|
||||
class UsageSummaryByPool(StatsReport):
|
||||
filename = 'pools_usage.pdf'
|
||||
@ -92,15 +87,15 @@ class UsageSummaryByPool(StatsReport):
|
||||
]
|
||||
self.pool.setValues(vals)
|
||||
|
||||
def getPoolData(self, pool):
|
||||
def getPoolData(self, pool) -> typing.Tuple[typing.List[typing.Dict[str, typing.Any]], str]:
|
||||
start = self.startDate.stamp()
|
||||
end = self.endDate.stamp()
|
||||
logger.debug(self.pool.value)
|
||||
|
||||
items = events.statsManager().getEvents(events.OT_DEPLOYED, (events.ET_LOGIN, events.ET_LOGOUT), owner_id=pool.id, since=start, to=end).order_by('stamp')
|
||||
|
||||
logins = {}
|
||||
users = {}
|
||||
logins: typing.Dict[str, int] = {}
|
||||
users: typing.Dict[str, typing.Dict] = {}
|
||||
for i in items:
|
||||
# if '\\' in i.fld1:
|
||||
# continue
|
||||
@ -113,7 +108,7 @@ class UsageSummaryByPool(StatsReport):
|
||||
del logins[username]
|
||||
total = i.stamp - stamp
|
||||
if username not in users:
|
||||
users[username] = { 'sessions': 0, 'time': 0 }
|
||||
users[username] = {'sessions': 0, 'time': 0}
|
||||
users[username]['sessions'] += 1
|
||||
users[username]['time'] += total
|
||||
# data.append({
|
||||
@ -123,18 +118,16 @@ class UsageSummaryByPool(StatsReport):
|
||||
# })
|
||||
|
||||
# Extract different number of users
|
||||
data = []
|
||||
for k, v in users.items():
|
||||
data.append({
|
||||
'user': k,
|
||||
'sessions': v['sessions'],
|
||||
'hours': '{:.2f}'.format(float(v['time']) / 3600),
|
||||
'average': '{:.2f}'.format(float(v['time']) / 3600 / v['sessions'])
|
||||
})
|
||||
data = [{
|
||||
'user': k,
|
||||
'sessions': v['sessions'],
|
||||
'hours': '{:.2f}'.format(float(v['time']) / 3600),
|
||||
'average': '{:.2f}'.format(float(v['time']) / 3600 / v['sessions'])
|
||||
} for k, v in users.items()]
|
||||
|
||||
return data, pool.name
|
||||
|
||||
def getData(self):
|
||||
def getData(self) -> typing.Tuple[typing.List[typing.Dict[str, typing.Any]], str]:
|
||||
return self.getPoolData(ServicePool.objects.get(uuid=self.pool.value))
|
||||
|
||||
def generate(self):
|
||||
@ -168,7 +161,7 @@ class UsageSummaryByPoolCSV(UsageSummaryByPool):
|
||||
output = io.StringIO()
|
||||
writer = csv.writer(output)
|
||||
|
||||
reportData, poolName = self.getData()
|
||||
reportData = self.getData()[0]
|
||||
|
||||
writer.writerow([ugettext('User'), ugettext('Sessions'), ugettext('Hours'), ugettext('Average')])
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2015-2018 Virtual Cable S.L.
|
||||
# Copyright (c) 2015-2019 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -34,6 +34,7 @@ import io
|
||||
import csv
|
||||
import datetime
|
||||
import logging
|
||||
import typing
|
||||
|
||||
from django.utils.translation import ugettext, ugettext_lazy as _
|
||||
from django.db.models import Count
|
||||
@ -41,18 +42,14 @@ import django.template.defaultfilters as filters
|
||||
|
||||
from uds.core.ui import gui
|
||||
from uds.core.util.stats import events
|
||||
|
||||
from uds.core.util import tools
|
||||
from uds.core.reports import graphs
|
||||
from uds.models import ServicePool
|
||||
|
||||
from .base import StatsReport
|
||||
|
||||
from uds.core.util import tools
|
||||
from uds.models import ServicePool
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
__updated__ = '2018-04-24'
|
||||
|
||||
# several constants as Width height, margins, ..
|
||||
WIDTH, HEIGHT, DPI = 19.2, 10.8, 100
|
||||
SIZE = (WIDTH, HEIGHT, DPI)
|
||||
@ -108,10 +105,10 @@ class PoolPerformanceReport(StatsReport):
|
||||
]
|
||||
self.pools.setValues(vals)
|
||||
|
||||
def getPools(self):
|
||||
def getPools(self) -> typing.List[typing.Tuple[str, str]]:
|
||||
return [(v.id, v.name) for v in ServicePool.objects.filter(uuid__in=self.pools.value)]
|
||||
|
||||
def getRangeData(self):
|
||||
def getRangeData(self) -> typing.Tuple[str, typing.List, typing.List]: # pylint: disable=too-many-locals
|
||||
start = self.startDate.stamp()
|
||||
end = self.endDate.stamp()
|
||||
|
||||
@ -126,10 +123,10 @@ class PoolPerformanceReport(StatsReport):
|
||||
|
||||
pools = self.getPools()
|
||||
|
||||
if len(pools) == 0:
|
||||
if pools:
|
||||
raise Exception(_('Select at least a service pool for the report'))
|
||||
|
||||
logger.debug('Pools: {}'.format(pools))
|
||||
logger.debug('Pools: %s', pools)
|
||||
|
||||
# x axis label format
|
||||
if end - start > 3600 * 24 * 2:
|
||||
@ -138,7 +135,7 @@ class PoolPerformanceReport(StatsReport):
|
||||
xLabelFormat = 'SHORT_DATETIME_FORMAT'
|
||||
|
||||
# Generate samplings interval
|
||||
samplingIntervals = []
|
||||
samplingIntervals: typing.List[typing.Tuple[int, int]] = []
|
||||
prevVal = None
|
||||
for val in range(start, end, int((end - start) / (samplingPoints + 1))):
|
||||
if prevVal is None:
|
||||
@ -199,12 +196,10 @@ class PoolPerformanceReport(StatsReport):
|
||||
'x': X,
|
||||
'xtickFnc': lambda l: filters.date(datetime.datetime.fromtimestamp(X[int(l)]), xLabelFormat) if int(l) >= 0 else '',
|
||||
'xlabel': _('Date'),
|
||||
'y': [
|
||||
{
|
||||
'label': p['name'],
|
||||
'data': [v[1] for v in p['dataUsers']]
|
||||
}
|
||||
for p in poolsData],
|
||||
'y': [{
|
||||
'label': p['name'],
|
||||
'data': [v[1] for v in p['dataUsers']]
|
||||
} for p in poolsData],
|
||||
'ylabel': _('Users')
|
||||
}
|
||||
|
||||
@ -216,12 +211,10 @@ class PoolPerformanceReport(StatsReport):
|
||||
'x': X,
|
||||
'xtickFnc': lambda l: filters.date(datetime.datetime.fromtimestamp(X[int(l)]), xLabelFormat) if int(l) >= 0 else '',
|
||||
'xlabel': _('Date'),
|
||||
'y': [
|
||||
{
|
||||
'label': p['name'],
|
||||
'data': [v[1] for v in p['dataAccesses']]
|
||||
}
|
||||
for p in poolsData],
|
||||
'y': [{
|
||||
'label': p['name'],
|
||||
'data': [v[1] for v in p['dataAccesses']]
|
||||
} for p in poolsData],
|
||||
'ylabel': _('Accesses')
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2015 Virtual Cable S.L.
|
||||
# Copyright (c) 2015-2019 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -30,25 +30,25 @@
|
||||
"""
|
||||
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
from django.utils.translation import ugettext, ugettext_lazy as _
|
||||
|
||||
from uds.core.ui import gui
|
||||
from uds.core.util.stats import counters
|
||||
|
||||
import csv
|
||||
import io
|
||||
import datetime
|
||||
import logging
|
||||
import typing
|
||||
|
||||
from django.utils.translation import ugettext, ugettext_lazy as _
|
||||
|
||||
from uds.core.ui import gui
|
||||
from uds.core.util.stats import counters
|
||||
from uds.core.reports import graphs
|
||||
from uds.models import ServicePool
|
||||
|
||||
|
||||
from .base import StatsReport
|
||||
|
||||
from uds.models import ServicePool
|
||||
from uds.core.reports import graphs
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
__updated__ = '2018-04-25'
|
||||
|
||||
# several constants as Width height, margins, ..
|
||||
WIDTH, HEIGHT, DPI = 19.2, 10.8, 100
|
||||
SIZE = (WIDTH, HEIGHT, DPI)
|
||||
@ -85,19 +85,19 @@ class CountersPoolAssigned(StatsReport):
|
||||
]
|
||||
self.pools.setValues(vals)
|
||||
|
||||
def getData(self):
|
||||
def getData(self) -> typing.List[typing.Dict[str, typing.Any]]:
|
||||
# Generate the sampling intervals and get dataUsers from db
|
||||
start = self.startDate.date()
|
||||
end = self.startDate.date() + datetime.timedelta(days=1)
|
||||
|
||||
data = []
|
||||
|
||||
pool = None
|
||||
pool: ServicePool
|
||||
for poolUuid in self.pools.value:
|
||||
try:
|
||||
pool = ServicePool.objects.get(uuid=poolUuid)
|
||||
except Exception:
|
||||
pass # Ignore pool
|
||||
continue
|
||||
|
||||
hours = {}
|
||||
for i in range(24):
|
||||
@ -111,7 +111,7 @@ class CountersPoolAssigned(StatsReport):
|
||||
|
||||
data.append({'uuid':pool.uuid, 'name': pool.name, 'hours': hours})
|
||||
|
||||
logger.debug('data: {}'.format(data))
|
||||
logger.debug('data: %s', data)
|
||||
|
||||
return data
|
||||
|
||||
@ -124,7 +124,7 @@ class CountersPoolAssigned(StatsReport):
|
||||
d = {
|
||||
'title': _('Services by hour'),
|
||||
'x': X,
|
||||
'xtickFnc': lambda l: '{:02d}'.format(l),
|
||||
'xtickFnc': lambda xx: '{:02d}'.format(xx), # pylint: disable=unnecessary-lambda
|
||||
'xlabel': _('Hour'),
|
||||
'y': [
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2015 Virtual Cable S.L.
|
||||
# Copyright (c) 2015-2019 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -30,18 +30,17 @@
|
||||
"""
|
||||
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.utils.translation import ugettext, ugettext_noop as _
|
||||
""" from django.utils.translation import ugettext_noop as _
|
||||
|
||||
from .base import StatsReport
|
||||
|
||||
|
||||
__updated__ = '2017-05-03'
|
||||
|
||||
|
||||
class StatsReportUsage(object): # Disabled from being used
|
||||
# class StatsReportUsage(StatsReport):
|
||||
class StatsReportUsage(StatsReport): # Disabled from being used
|
||||
name = _('Usage stats') # Report name
|
||||
description = _('Statistics of platform use') # Report description
|
||||
uuid = '9ae54172-ed48-11e4-b8e1-10feed05884b'
|
||||
|
||||
def generate(self):
|
||||
return ''
|
||||
"""
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2015 Virtual Cable S.L.
|
||||
# Copyright (c) 2015-2019 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -30,27 +30,23 @@
|
||||
"""
|
||||
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
import io
|
||||
import csv
|
||||
import datetime
|
||||
import logging
|
||||
import typing
|
||||
|
||||
from django.utils.translation import ugettext, ugettext_lazy as _
|
||||
|
||||
from uds.core.ui import gui
|
||||
from uds.core.util.stats import events
|
||||
|
||||
import six
|
||||
import csv
|
||||
from uds.models import ServicePool
|
||||
|
||||
from .base import StatsReport
|
||||
|
||||
from uds.models import ServicePool
|
||||
|
||||
import datetime
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
__updated__ = '2018-04-25'
|
||||
|
||||
|
||||
class UsageByPool(StatsReport):
|
||||
filename = 'pools_usage.pdf'
|
||||
@ -92,7 +88,7 @@ class UsageByPool(StatsReport):
|
||||
]
|
||||
self.pool.setValues(vals)
|
||||
|
||||
def getData(self):
|
||||
def getData(self) -> typing.Tuple[typing.List[typing.Dict[str, typing.Any]], str]:
|
||||
# Generate the sampling intervals and get dataUsers from db
|
||||
start = self.startDate.stamp()
|
||||
end = self.endDate.stamp()
|
||||
@ -120,7 +116,7 @@ class UsageByPool(StatsReport):
|
||||
'time': total
|
||||
})
|
||||
|
||||
logger.debug('data: {}'.format(data))
|
||||
logger.debug('data: %s', data)
|
||||
|
||||
return data, pool.name
|
||||
|
||||
@ -150,10 +146,10 @@ class UsageByPoolCSV(UsageByPool):
|
||||
endDate = UsageByPool.endDate
|
||||
|
||||
def generate(self):
|
||||
output = six.StringIO()
|
||||
output = io.StringIO()
|
||||
writer = csv.writer(output)
|
||||
|
||||
reportData, poolName = self.getData()
|
||||
reportData = self.getData()[0]
|
||||
|
||||
writer.writerow([ugettext('Date'), ugettext('User'), ugettext('Seconds')])
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
#
|
||||
# Copyright (c) 2015-2018 Virtual Cable S.L.
|
||||
# Copyright (c) 2015-2019 Virtual Cable S.L.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
@ -34,22 +34,21 @@ import csv
|
||||
import io
|
||||
import datetime
|
||||
import logging
|
||||
import typing
|
||||
|
||||
from django.utils.translation import ugettext, ugettext_lazy as _
|
||||
import django.template.defaultfilters as filters
|
||||
|
||||
from uds.core.ui import gui
|
||||
from uds.core.util.stats import events
|
||||
from uds.core.util import tools
|
||||
from uds.core.reports import graphs
|
||||
|
||||
from .base import StatsReport
|
||||
|
||||
from uds.core.util import tools
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
__updated__ = '2018-04-25'
|
||||
|
||||
# several constants as Width height
|
||||
WIDTH, HEIGHT, DPI = 19.2, 10.8, 100
|
||||
SIZE = (WIDTH, HEIGHT, DPI)
|
||||
@ -94,7 +93,7 @@ class StatsReportLogin(StatsReport):
|
||||
def initGui(self):
|
||||
pass
|
||||
|
||||
def getRangeData(self):
|
||||
def getRangeData(self) -> typing.Tuple[str, typing.List, typing.List]:
|
||||
start = self.startDate.stamp()
|
||||
end = self.endDate.stamp()
|
||||
if self.samplingPoints.num() < 8:
|
||||
@ -112,7 +111,7 @@ class StatsReportLogin(StatsReport):
|
||||
else:
|
||||
xLabelFormat = 'SHORT_DATETIME_FORMAT'
|
||||
|
||||
samplingIntervals = []
|
||||
samplingIntervals: typing.List[typing.Tuple[int, int]] = []
|
||||
prevVal = None
|
||||
for val in range(start, end, int((end - start) / (samplingPoints + 1))):
|
||||
if prevVal is None:
|
||||
@ -148,7 +147,7 @@ class StatsReportLogin(StatsReport):
|
||||
dataWeek[s.weekday()] += 1
|
||||
dataHour[s.hour] += 1
|
||||
dataWeekHour[s.weekday()][s.hour] += 1
|
||||
logger.debug('Data: {} {}'.format(s.weekday(), s.hour))
|
||||
logger.debug('Data: %s %s', s.weekday(), s.hour)
|
||||
|
||||
return dataWeek, dataHour, dataWeekHour
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user