Fixes to reports

This commit is contained in:
Adolfo Gómez García 2022-06-07 15:38:57 +02:00
parent 364ebd6f3a
commit 4c66401e4f
4 changed files with 113 additions and 56 deletions

View File

@ -518,7 +518,7 @@ class gui:
def date(self, min: bool = True) -> datetime.date:
"""
Returns the date tis objecct represents
Returns the date this object represents
Args:
min (bool, optional): If true, in case of invalid date will return "min" date, else "max". Defaults to True.
@ -533,6 +533,23 @@ class gui:
except Exception:
return datetime.date.min if min else datetime.date.max
def datetime(self, min: bool) -> datetime.datetime:
"""
Returns the date this object represents
Args:
min (bool, optional): If true, in case of invalid date will return "min" date, else "max". Defaults to True.
Returns:
datetime.date: the date that this object holds, or "min" | "max" on error
"""
try:
return datetime.datetime.strptime(
self.value, '%Y-%m-%d'
) # ISO Format
except Exception:
return datetime.datetime.min if min else datetime.datetime.max
def stamp(self) -> int:
return int(
time.mktime(

View File

@ -58,6 +58,7 @@ reportAutoModelDct: typing.Mapping[str, typing.Type[ReportAutoModel]] = { # typ
'Provider': models.Provider,
}
class ReportAutoType(UserInterfaceType):
def __new__(cls, name, bases, attrs) -> 'ReportAutoType':
# Add gui for elements...
@ -115,7 +116,7 @@ class ReportAuto(Report, metaclass=ReportAutoType):
def getModel(self) -> typing.Type[ReportAutoModel]: # type: ignore
data_source = self.data_source.split('.')[0]
return reportAutoModelDct[data_source]
def initGui(self):
@ -142,3 +143,56 @@ class ReportAuto(Report, metaclass=ReportAutoType):
return {'hour': 1, 'day': 24, 'week': 24 * 7, 'month': 24 * 30}[
self.interval.value
]
def getIntervalsList(self) -> typing.List[typing.Tuple[datetime.datetime, datetime.datetime]]:
intervals: typing.List[typing.Tuple[datetime.datetime, datetime.datetime]] = []
# Convert start and end dates to datetime objects from date objects
start = datetime.datetime.combine(self.startingDate(), datetime.time.min)
to = datetime.datetime.combine(self.endingDate(), datetime.time.max)
while start < to:
if self.interval.value == 'hour':
intervals.append((start, start + datetime.timedelta(hours=1)))
start += datetime.timedelta(hours=1)
elif self.interval.value == 'day':
intervals.append((start, start + datetime.timedelta(days=1)))
start += datetime.timedelta(days=1)
elif self.interval.value == 'week':
intervals.append((start, start + datetime.timedelta(days=7)))
start += datetime.timedelta(days=7)
elif self.interval.value == 'month':
next = (start + datetime.timedelta(days=32)).replace(day=1)
intervals.append((start, next))
start = next
logger.info('Intervals: {0}'.format(intervals))
return intervals
def adjustDate(self, d: datetime.date, isEndingDate: bool) -> datetime.date:
if self.interval.value in ('hour', 'day'):
return d
elif self.interval.value == 'week':
return (d - datetime.timedelta(days=d.weekday())).replace()
elif self.interval.value == 'month':
if not isEndingDate:
return d.replace(day=1)
else:
return (d + datetime.timedelta(days=32)).replace(day=1) - datetime.timedelta(days=1)
else:
return d
def formatDatetimeAsString(self, d: datetime.date) -> str:
if self.interval.value in ('hour', 'day'):
return d.strftime('%Y-%b-%d %H:%M:%S')
elif self.interval.value == 'week':
return d.strftime('%Y-%b-%d')
elif self.interval.value == 'month':
return d.strftime('%Y-%b')
else:
return d.strftime('%Y-%b-%d %H:%M:%S')
def startingDate(self) -> datetime.date:
return self.adjustDate(self.date_start.date(), False)
def endingDate(self) -> datetime.date:
return self.adjustDate(self.date_end.date(), True)

View File

@ -30,6 +30,7 @@
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
"""
import logging
import datetime
import typing
from django.utils.translation import ugettext, ugettext_lazy as _
@ -46,7 +47,7 @@ if typing.TYPE_CHECKING:
logger = logging.getLogger(__name__)
MAX_ELEMENTS = 10000
BIG_INTERVAL = 3600 * 24 * 30 * 12 # 12 months
class AuthenticatorsStats(StatsReportAuto):
dates = 'range'
@ -62,9 +63,6 @@ class AuthenticatorsStats(StatsReportAuto):
uuid = 'a5a43bc0-d543-11ea-af8f-af01fa65994e'
def generate(self) -> typing.Any:
since = self.date_start.date()
to = self.date_end.date()
interval = self.getIntervalInHours() * 3600
stats = []
for a in self.getModelItems():
@ -73,60 +71,49 @@ class AuthenticatorsStats(StatsReportAuto):
services = 0
userServices = 0
servicesCounterIter = iter(
counters.getCounters(
typing.cast('models.Authenticator', a),
counters.CT_AUTH_SERVICES,
since=since,
interval=interval,
limit=MAX_ELEMENTS,
use_max=True,
)
)
usersWithServicesCounterIter = iter(
counters.getCounters(
for i in self.getIntervalsList():
start = i[0]
end = i[1]
data = [0, 0, 0]
# Get stats for interval
for counter in counters.getCounters(
typing.cast('models.Authenticator', a),
counters.CT_AUTH_SERVICES,
since=start,
to=end,
interval=BIG_INTERVAL,
limit=MAX_ELEMENTS,
use_max=True,
):
data[0] += counter[1]
for counter in counters.getCounters(
typing.cast('models.Authenticator', a),
counters.CT_AUTH_USERS_WITH_SERVICES,
since=since,
interval=interval,
since=start,
to=end,
interval=BIG_INTERVAL,
limit=MAX_ELEMENTS,
use_max=True,
)
)
for userCounter in counters.getCounters(
typing.cast('models.Authenticator', a),
counters.CT_AUTH_USERS,
since=since,
interval=interval,
limit=MAX_ELEMENTS,
use_max=True,
):
try:
while True:
servicesCounter = next(servicesCounterIter)
if servicesCounter[0] >= userCounter[0]:
break
if userCounter[0] == servicesCounter[0]:
services = servicesCounter[1]
except StopIteration:
pass
try:
while True:
uservicesCounter = next(usersWithServicesCounterIter)
if uservicesCounter[0] >= userCounter[0]:
break
if userCounter[0] == uservicesCounter[0]:
userServices = uservicesCounter[1]
except StopIteration:
pass
):
data[1] += counter[1]
for counter in counters.getCounters(
typing.cast('models.Authenticator', a),
counters.CT_AUTH_USERS,
since=start,
to=end,
interval=BIG_INTERVAL,
limit=MAX_ELEMENTS,
use_max=True,
):
data[2] += counter[1]
stats.append(
{
'date': userCounter[0],
'users': userCounter[1] or 0,
'services': services,
'user_services': userServices,
'date': self.formatDatetimeAsString(start),
'users': data[0],
'services': data[1],
'user_services': data[2],
}
)
logger.debug('Report Data Done')

View File

@ -85,7 +85,6 @@ class CountersPoolAssigned(StatsReport):
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 = []
@ -102,8 +101,8 @@ class CountersPoolAssigned(StatsReport):
pool,
counters.CT_ASSIGNED,
since=start,
to=end,
max_intervals=24,
to=start+datetime.timedelta(days=1),
intervals=3600,
use_max=True,
all=False,
):