new metrics
This commit is contained in:
parent
aa7a3ffe12
commit
5e9b9bf08d
|
@ -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
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
Reference in New Issue