new metrics

This commit is contained in:
Cayo Puigdefabregas 2021-10-14 12:56:33 +02:00
parent aa7a3ffe12
commit 5e9b9bf08d
3 changed files with 237 additions and 93 deletions

View file

@ -0,0 +1,174 @@
import copy
class Metrics:
"""we want get the data metrics of one device"""
def __init__(self, device):
self.hid = device.hid
self.devicehub_id = device.devicehub_id
self.actions = copy.copy(device.actions)
self.actions.sort(key=lambda x: x.created)
self.rows = []
self.lifetime = 0
self.last_trade = None
self.action_create_by = 'Receiver'
self.status_receiver = 'Use'
self.status_supplier = ''
self.act = None
self.end_users = 0
self.final_user_code = ''
def get_template_row(self):
"""
This is a template of a row.
"""
return {'type': '',
'action_type': 'Status',
'status_receiver': self.status_receiver,
'status_supplier': self.status_supplier,
'trade_supplier': '',
'trade_receiver': self.act.author,
'trade_confirmed': '',
'action_create_by': self.action_create_by,
'devicehubID': self.devicehub_id,
'hid': self.hid,
'finalUserCode': '',
'numEndUsers': 0,
'liveCreate': 0,
'usageTimeHdd': self.lifetime,
'start': self.act.created,
'usageTimeAllocate': 0}
def get_action_status(self):
"""
Mark the status of one device.
If exist one trade before this action, then modify the trade action
else, create one row new.
"""
self.status_receiver = self.act.type
self.status_supplier = ''
if self.act.author != self.act.rol_user:
# It is neccesary exist one trade action before
self.last_trade['status_supplier'] = self.act.type
self.last_trade['status_supplier_created'] = self.act.created
return
if self.last_trade:
# if exist one trade action before
self.last_trade['status_receiver'] = self.act.type
self.last_trade['status_receiver_created'] = self.act.created
return
# If not exist any trade action for this device
self.action_create_by = 'Receiver'
row = self.get_template_row()
row['type'] = 'Status'
self.rows.append(row)
def get_snapshot(self):
"""
If there are one snapshot get the last lifetime for to do a calcul of time of use.
"""
lifestimes = self.act.get_last_lifetimes()
if lifestimes:
self.lifetime = lifestimes[0]['lifetime']
def get_allocate(self):
"""
If the action is one Allocate, need modify the row base.
"""
self.end_users = self.act.end_users
self.final_user_code = self.act.final_user_code
row = self.get_template_row()
row['type'] = 'Allocate'
row['trade_supplier'] = ''
row['finalUserCode'] = self.final_user_code
row['numEndUsers'] = self.end_users
row['start'] = self.act.start_time
row['usageTimeAllocate'] = self.lifetime
self.rows.append(row)
def get_live(self):
"""
If the action is one Live, need modify the row base.
"""
row = self.get_template_row()
row['type'] = 'Live'
row['finalUserCode'] = self.final_user_code
row['numEndUsers'] = self.end_users
row['start'] = self.act.start_time
row['usageTimeAllocate'] = self.lifetime
row['liveCreate'] = self.act.created
if self.act.usage_time_hdd:
row['usageTimeHdd'] = self.act.usage_time_hdd.total_seconds() / 3600
self.rows.append(row)
def get_deallocate(self):
"""
If the action is one Dellocate, need modify the row base.
"""
row = self.get_template_row()
row['type'] = 'Deallocate'
row['start'] = self.act.start_time
self.rows.append(row)
def get_confirms(self):
"""
if the action is one trade action, is possible than have a list of confirmations.
Get the doble confirm for to know if this trade is confirmed or not.
"""
if hasattr(self.act, 'acceptances'):
accept = self.act.acceptances[-1]
if accept.t == 'Confirm' and accept.user == self.act.user_to:
return True
return False
def get_trade(self):
"""
If this action is a trade action modify the base row.
"""
if self.act.author == self.act.user_from:
self.action_create_by = 'Supplier'
row = self.get_template_row()
self.last_trade = row
row['type'] = 'Trade'
row['action_type'] = 'Trade'
row['trade_supplier'] = self.act.user_from
row['trade_receiver'] = self.act.user_to
row['self.status_receiver'] = self.status_receiver
row['self.status_supplier'] = self.status_supplier
row['trade_confirmed'] = self.get_confirms()
self.rows.append(row)
def get_metrics(self):
"""
This method get a list of values for calculate a metrics from a spreadsheet
"""
for act in self.actions:
self.act = act
if act.type in ['Use', 'Refurbish', 'Recycling', 'Management']:
self.get_action_status()
continue
if act.type == 'Snapshot':
self.get_snapshot()
continue
if act.type == 'Allocate':
self.get_allocate()
continue
if act.type == 'Live':
self.get_live()
continue
if act.type == 'Deallocate':
self.get_deallocate()
continue
if act.type == 'Trade':
self.get_trade()
continue
return self.rows

View file

@ -34,6 +34,7 @@ from ereuse_devicehub.resources.enums import BatteryTechnology, CameraFacing, Co
DataStorageInterface, DisplayTech, PrinterTechnology, RamFormat, RamInterface, Severity, TransferState
from ereuse_devicehub.resources.models import STR_SM_SIZE, Thing, listener_reset_field_updated_in_actual_time
from ereuse_devicehub.resources.user.models import User
from ereuse_devicehub.resources.device.metrics import Metrics
def create_code(context):
@ -206,10 +207,10 @@ class Device(Thing):
if isinstance(c, ColumnProperty)
and not getattr(c, 'foreign_keys', None)
and c.key not in self._NON_PHYSICAL_PROPS}
@property
def public_properties(self) -> Dict[str, object or None]:
"""Fields that describe the properties of a device than next show
"""Fields that describe the properties of a device than next show
in the public page.
:return A dictionary:
@ -341,7 +342,7 @@ class Device(Thing):
ac = self.last_action_trading
if not ac:
return
return
first_owner = self.which_user_put_this_device_in_trace()
@ -349,7 +350,7 @@ class Device(Thing):
# can to do revoke_confirmed
return confirm_revoke
if ac.type == revoke:
if ac.type == revoke:
if ac.user == g.user:
# can todo revoke_pending
return revoke_pending
@ -505,93 +506,8 @@ class Device(Thing):
"""
This method get a list of values for calculate a metrics from a spreadsheet
"""
actions = copy.copy(self.actions)
actions.sort(key=lambda x: x.created)
allocates = []
lifetime = 0
for act in actions:
if act.type == 'Snapshot':
snapshot = act
lifestimes = snapshot.get_last_lifetimes()
lifetime = 0
if lifestimes:
lifetime = lifestimes[0]['lifetime']
if act.type == 'Allocate':
allo = {'type': 'Allocate',
'action_type': 'Status',
'status_receiver': 'Use',
'trade_supplier': '',
'trade_receiver': '',
'trade_confirmed': '',
'action_create_by': 'Receiver',
'devicehubID': self.devicehub_id,
'finalUserCode': act.final_user_code,
'numEndUsers': act.end_users,
'hid': self.hid,
'liveCreate': 0,
'usageTimeHdd': 0,
'start': act.start_time,
'usageTimeAllocate': lifetime}
allocates.append(allo)
if act.type == 'Live':
allocate = copy.copy(allo)
allocate['type'] = 'Live'
allocate['liveCreate'] = act.created
allocate['usageTimeHdd'] = 0
if act.usage_time_hdd:
allocate['usageTimeHdd'] = act.usage_time_hdd.total_seconds()/3600
allocates.append(allocate)
if act.type == 'Deallocate':
deallo = {'type': 'Deallocate',
'devicehubID': self.devicehub_id,
'action_type': 'Status',
'status_receiver': 'Use',
'trade_supplier': '',
'trade_receiver': '',
'trade_confirmed': '',
'action_create_by': 'Receiver',
'finalUserCode': '',
'numEndUsers': '',
'hid': self.hid,
'liveCreate': 0,
'usageTimeHdd': lifetime,
'start': act.start_time,
'usageTimeAllocate': 0}
allocates.append(deallo)
if act.type == 'Trade':
confirm = False
if hasattr(act, 'acceptances'):
accept = act.acceptances[-1]
if accept.t == 'Confirm' and accept.user == act.user_to:
confirm = True
action_create_by = 'Receiver'
if act.author == act.user_from:
action_create_by = 'Supplier'
trade = {'type': 'Trade',
'action_type': 'Trade',
'trade_supplier': act.user_from,
'trade_receiver': act.user_to,
'trade_confirmed': confirm,
'action_create_by': action_create_by,
'trade_confirmed': confirm,
'devicehubID': self.devicehub_id,
'finalUserCode': '',
'numEndUsers': '',
'hid': self.hid,
'liveCreate': 0,
'usageTimeHdd': lifetime,
'start': act.start_time,
'status_receiver': 'Use',
'usageTimeAllocate': 0
}
allocates.append(trade)
return allocates
metrics = Metrics(self)
return metrics.get_metrics()
def __lt__(self, other):
return self.id < other.id
@ -790,7 +706,7 @@ class Computer(Device):
return urls
def add_mac_to_hid(self, components_snap=None):
"""Returns the Naming.hid with the first mac of network adapter,
"""Returns the Naming.hid with the first mac of network adapter,
following an alphabetical order.
"""
self.set_hid()
@ -923,7 +839,7 @@ class Component(Device):
"""
assert self.hid is None, 'Don\'t use this method with a component that has HID'
component = self.__class__.query \
.filter_by(parent=parent, hid=None, owner_id=self.owner_id,
.filter_by(parent=parent, hid=None, owner_id=self.owner_id,
**self.physical_properties) \
.filter(~Component.id.in_(blacklist)) \
.first()

View file

@ -2,6 +2,7 @@ import pytest
from ereuse_devicehub.client import UserClient
from ereuse_devicehub.resources.action import models as ma
from ereuse_devicehub.resources.documents import documents
from tests import conftest
from tests.conftest import file, yaml2json, json_encode
@ -120,3 +121,56 @@ def test_metrics_with_live_null(user: UserClient):
res, _ = user.get("/metrics/")
assert res == metrics
@pytest.mark.mvp
@pytest.mark.usefixtures(conftest.app_context.__name__)
def test_metrics_action_status(user: UserClient, user2: UserClient):
""" Checks one standard query of metrics """
# Insert computer
lenovo = yaml2json('desktop-9644w8n-lenovo-0169622.snapshot')
snap, _ = user.post(json_encode(lenovo), res=ma.Snapshot)
action = {'type': ma.Use.t, 'devices': [snap['device']['id']]}
action_use, _ = user.post(action, res=ma.Action)
# res, _ = user.get("/metrics/")
csv_str, _ = user.get(res=documents.DocumentDef.t,
item='actions/',
accept='text/csv',
query=[('filter', {'type': ['Computer']})])
import pdb; pdb.set_trace()
@pytest.mark.mvp
@pytest.mark.usefixtures(conftest.app_context.__name__)
def test_complet_metrics(user: UserClient, user2: UserClient):
""" Checks one standard query of metrics """
# Insert computer
lenovo = yaml2json('desktop-9644w8n-lenovo-0169622.snapshot')
acer = yaml2json('acer.happy.battery.snapshot')
snap1, _ = user.post(json_encode(lenovo), res=ma.Snapshot)
snap2, _ = user.post(json_encode(acer), res=ma.Snapshot)
lot, _ = user.post({'name': 'MyLot'}, res=Lot)
devices = [('id', snap1['device']['id']),
('id', snap2['device']['id'])
]
lot, _ = user.post({},
res=Lot,
item='{}/devices'.format(lot['id']),
query=devices)
# request_post = {
# 'type': 'Trade',
# 'devices': [span1['device']['id'], snap2['device']['id']],
# 'userFromEmail': user2.email,
# 'userToEmail': user.email,
# 'price': 10,
# 'date': "2020-12-01T02:00:00+00:00",
# 'lot': lot['id'],
# 'confirms': True,
# }
# user.post(res=models.Action, data=request_post)
# ==============================
# Check metrics
metrics = {'allocateds': 1, 'live': 1}
res, _ = user.get("/metrics/")
assert res == metrics