forked from shaba/openuds
Adding report to see user access time/duration
This commit is contained in:
parent
e2e0f96d3e
commit
f1cbcf86e1
@ -102,8 +102,8 @@ def getEvents(obj, eventType, **kwargs):
|
|||||||
else:
|
else:
|
||||||
owner_id = obj.pk
|
owner_id = obj.pk
|
||||||
|
|
||||||
for i in statsManager().getEvents(__transDict[type(obj)], eventType, owner_id, since, to):
|
for i in statsManager().getEvents(__transDict[type(obj)], eventType, owner_id=owner_id, since=since, to=to):
|
||||||
val = (datetime.datetime.fromtimestamp(i.stamp), i.fld1, i.fld2, i.fld3)
|
val = (datetime.datetime.fromtimestamp(i.stamp), i.fld1, i.fld2, i.fld3, i.fld4, i.event_type)
|
||||||
yield val
|
yield val
|
||||||
|
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ from uds.models.Util import getSqlDatetime
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
__updated__ = '2015-07-02'
|
__updated__ = '2016-01-19'
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -76,6 +76,9 @@ class StatsEvents(models.Model):
|
|||||||
|
|
||||||
Note: if someone cant get this more optimized, please, contribute it!
|
Note: if someone cant get this more optimized, please, contribute it!
|
||||||
'''
|
'''
|
||||||
|
if isinstance(event_type, (list, tuple)):
|
||||||
|
fltr = StatsEvents.objects.filter(event_type__in=event_type)
|
||||||
|
else:
|
||||||
fltr = StatsEvents.objects.filter(event_type=event_type)
|
fltr = StatsEvents.objects.filter(event_type=event_type)
|
||||||
|
|
||||||
if type(owner_type) in (list, tuple):
|
if type(owner_type) in (list, tuple):
|
||||||
|
@ -44,7 +44,7 @@ import logging
|
|||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
__updated__ = '2015-05-25'
|
__updated__ = '2016-01-14'
|
||||||
|
|
||||||
|
|
||||||
class TicketStore(UUIDModel):
|
class TicketStore(UUIDModel):
|
||||||
@ -83,12 +83,19 @@ class TicketStore(UUIDModel):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create(data, validator=None, validity=DEFAULT_VALIDITY):
|
def create(data, validator=None, validity=DEFAULT_VALIDITY):
|
||||||
|
'''
|
||||||
|
validity is in seconds
|
||||||
|
'''
|
||||||
if validator is not None:
|
if validator is not None:
|
||||||
validator = pickle.dumps(validator)
|
validator = pickle.dumps(validator)
|
||||||
return TicketStore.objects.create(stamp=getSqlDatetime(), data=pickle.dumps(data), validator=validator, validity=validity).uuid
|
return TicketStore.objects.create(stamp=getSqlDatetime(), data=pickle.dumps(data), validator=validator, validity=validity).uuid
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def store(uuid, data, validator=None, validity=DEFAULT_VALIDITY):
|
def store(uuid, data, validator=None, validity=DEFAULT_VALIDITY):
|
||||||
|
'''
|
||||||
|
Stores an ticketstore. If one with this uuid already exists, replaces it. Else, creates a new one
|
||||||
|
validity is in seconds
|
||||||
|
'''
|
||||||
if validator is not None:
|
if validator is not None:
|
||||||
validator = pickle.dumps(validator)
|
validator = pickle.dumps(validator)
|
||||||
try:
|
try:
|
||||||
|
@ -34,3 +34,4 @@
|
|||||||
from .usage import StatsReportUsage
|
from .usage import StatsReportUsage
|
||||||
from .login import StatsReportLogin, StatsReportLoginCSV
|
from .login import StatsReportLogin, StatsReportLoginCSV
|
||||||
from .pool_performance import PoolPerformanceReport
|
from .pool_performance import PoolPerformanceReport
|
||||||
|
from .usage_by_pool import UsageByPool
|
||||||
|
185
server/src/uds/reports/stats/usage_by_pool.py
Normal file
185
server/src/uds/reports/stats/usage_by_pool.py
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2015 Virtual Cable S.L.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
# are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer in the documentation
|
||||||
|
# and/or other materials provided with the distribution.
|
||||||
|
# * Neither the name of Virtual Cable S.L. nor the names of its contributors
|
||||||
|
# may be used to endorse or promote products derived from this software
|
||||||
|
# without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
'''
|
||||||
|
.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com
|
||||||
|
'''
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.utils.translation import ugettext, ugettext_lazy as _
|
||||||
|
|
||||||
|
from uds.core.ui.UserInterface import gui
|
||||||
|
from uds.core.reports.tools import UDSGeraldoReport
|
||||||
|
from uds.core.util.stats import events
|
||||||
|
|
||||||
|
|
||||||
|
import StringIO
|
||||||
|
import csv
|
||||||
|
|
||||||
|
|
||||||
|
from .base import StatsReport
|
||||||
|
|
||||||
|
from uds.core.util import tools
|
||||||
|
from uds.models import ServicePool
|
||||||
|
from geraldo.generators.pdf import PDFGenerator
|
||||||
|
from geraldo import ReportBand, ObjectValue
|
||||||
|
from reportlab.lib.units import cm, mm
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
__updated__ = '2016-01-19'
|
||||||
|
|
||||||
|
# several constants as Width height, margins, ..
|
||||||
|
WIDTH, HEIGHT = 1800, 1000
|
||||||
|
GERALDO_WIDTH = 120 * mm
|
||||||
|
GERALDO_HEIGHT = GERALDO_WIDTH * HEIGHT / WIDTH
|
||||||
|
|
||||||
|
|
||||||
|
class UsersReport(UDSGeraldoReport):
|
||||||
|
title = ''
|
||||||
|
author = 'UDS'
|
||||||
|
|
||||||
|
class band_detail(ReportBand):
|
||||||
|
height = 0.5 * cm
|
||||||
|
elements = (
|
||||||
|
ObjectValue(attribute_name='date', left=0.5 * cm, style={'fontName': 'Helvetica', 'fontSize': 8}),
|
||||||
|
ObjectValue(attribute_name='name', left=5.5 * cm, style={'fontName': 'Helvetica', 'fontSize': 8}),
|
||||||
|
ObjectValue(attribute_name='time', left=12 * cm, style={'fontName': 'Helvetica', 'fontSize': 8}),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class UsageByPool(StatsReport):
|
||||||
|
filename = 'pools_usage.pdf'
|
||||||
|
name = _('Pools usage by users') # Report name
|
||||||
|
description = _('Pools usage by user report') # Report description
|
||||||
|
uuid = '38ec12dc-beaf-11e5-bd0a-10feed05884b'
|
||||||
|
|
||||||
|
# Input fields
|
||||||
|
pool = gui.ChoiceField(
|
||||||
|
order=1,
|
||||||
|
label=_('Pool'),
|
||||||
|
tooltip=_('Pool for report'),
|
||||||
|
required=True
|
||||||
|
)
|
||||||
|
|
||||||
|
startDate = gui.DateField(
|
||||||
|
order=2,
|
||||||
|
label=_('Starting date'),
|
||||||
|
tooltip=_('starting date for report'),
|
||||||
|
defvalue=datetime.date.min,
|
||||||
|
required=True
|
||||||
|
)
|
||||||
|
|
||||||
|
endDate = gui.DateField(
|
||||||
|
order=3,
|
||||||
|
label=_('Finish date'),
|
||||||
|
tooltip=_('finish date for report'),
|
||||||
|
defvalue=datetime.date.max,
|
||||||
|
required=True
|
||||||
|
)
|
||||||
|
|
||||||
|
def initialize(self, values):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def initGui(self):
|
||||||
|
logger.debug('Initializing gui')
|
||||||
|
vals = [
|
||||||
|
gui.choiceItem(v.uuid, v.name) for v in ServicePool.objects.all()
|
||||||
|
]
|
||||||
|
self.pool.setValues(vals)
|
||||||
|
|
||||||
|
def getData(self):
|
||||||
|
# Generate the sampling intervals and get dataUsers from db
|
||||||
|
start = self.startDate.stamp()
|
||||||
|
end = self.endDate.stamp()
|
||||||
|
logger.debug(self.pool.value)
|
||||||
|
pool = ServicePool.objects.get(uuid=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 = {}
|
||||||
|
data = []
|
||||||
|
for i in items:
|
||||||
|
if '\\' in i.fld1:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if i.event_type == events.ET_LOGIN:
|
||||||
|
logins[i.fld4] = i.stamp
|
||||||
|
else:
|
||||||
|
if i.fld4 in logins:
|
||||||
|
stamp = logins[i.fld4]
|
||||||
|
del logins[i.fld4]
|
||||||
|
total = i.stamp - stamp
|
||||||
|
data.append({
|
||||||
|
'name': i.fld4,
|
||||||
|
'date': datetime.datetime.fromtimestamp(stamp),
|
||||||
|
'time': total
|
||||||
|
})
|
||||||
|
|
||||||
|
logger.debug('data')
|
||||||
|
|
||||||
|
return data, pool.name
|
||||||
|
|
||||||
|
def generate(self):
|
||||||
|
items, poolName = self.getData()
|
||||||
|
|
||||||
|
output = StringIO.StringIO()
|
||||||
|
|
||||||
|
report = UsersReport(queryset=items)
|
||||||
|
report.title = _('Users usage list for {}').format(poolName)
|
||||||
|
report.generate_by(PDFGenerator, filename=output)
|
||||||
|
return output.getvalue()
|
||||||
|
|
||||||
|
|
||||||
|
class UsageByPoolCSV(UsageByPool):
|
||||||
|
filename = 'usage.csv'
|
||||||
|
mime_type = 'text/csv' # Report returns pdfs by default, but could be anything else
|
||||||
|
uuid = '5f7f0844-beb1-11e5-9a96-10feed05884b'
|
||||||
|
encoded = False
|
||||||
|
|
||||||
|
# Input fields
|
||||||
|
pool = UsageByPool.pool
|
||||||
|
startDate = UsageByPool.startDate
|
||||||
|
endDate = UsageByPool.endDate
|
||||||
|
|
||||||
|
def generate(self):
|
||||||
|
output = StringIO.StringIO()
|
||||||
|
writer = csv.writer(output)
|
||||||
|
|
||||||
|
reportData = self.getRangeData()[2]
|
||||||
|
|
||||||
|
writer.writerow([ugettext('Pool'), ugettext('Date range'), ugettext('Users'), ugettext('Accesses')])
|
||||||
|
|
||||||
|
for v in reportData:
|
||||||
|
writer.writerow([v['name'], v['date'], v['users'], v['accesses']])
|
||||||
|
|
||||||
|
return output.getvalue()
|
Loading…
Reference in New Issue
Block a user