import copy class MetricsMix: """we want get the data metrics of one device""" def __init__(self, *args, **kwargs): # 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 = '' self.status_supplier = '' self.act = None self.end_users = 0 self.final_user_code = '' self.trades = {} def get_template_row(self): """ This is a template of a row. """ return {'type': '', 'action_type': 'Status', 'document_name': '', 'status_receiver': self.status_receiver, 'status_supplier': self.status_supplier, 'status_receiver_created': '', 'status_supplier_created': '', 'trade_supplier': '', 'trade_receiver': self.act.author.email, 'trade_confirmed': '', 'trade_weight': 0, 'action_create_by': self.action_create_by, 'devicehubID': self.devicehub_id, 'hid': self.hid, 'finalUserCode': '', 'numEndUsers': 0, 'liveCreate': 0, 'usageTimeHdd': self.lifetime, 'created': self.act.created, 'start': '', 'usageTimeAllocate': 0} def get_metrics(self): """ This method get a list of values for calculate a metrics from a spreadsheet """ return self.rows class Metrics(MetricsMix): """we want get the data metrics of one device""" def __init__(self, *args, **kwargs): self.device = kwargs.pop('device') self.actions = copy.copy(self.device.actions) super().__init__(*args, **kwargs) self.hid = self.device.hid self.devicehub_id = self.device.devicehub_id 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 new row. """ if self.act.trade not in self.trades: # If not exist one trade, the status is of the Receive self.action_create_by = 'Receiver' self.status_receiver = self.act.type self.status_supplier = '' row = self.get_template_row() row['status_supplier_created'] = '' row['status_receiver_created'] = self.act.created self.rows.append(row) return trade = self.trades[self.act.trade] if trade['trade_supplier'] == self.act.author.email: trade['status_supplier'] = self.act.type trade['status_supplier_created'] = self.act.created return if trade['trade_receiver'] == self.act.author.email: trade['status_receiver'] = self.act.type trade['status_receiver_created'] = self.act.created return # necesitamos poder poner un cambio de estado de un trade mas antiguo que last_trade # lo mismo con confirm 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.action_create_by = 'Receiver' 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. """ self.action_create_by = 'Receiver' 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. """ self.action_create_by = 'Receiver' 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. """ return self.device.trading(self.act.lot, simple=True) 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' self.status_receiver = '' row = self.get_template_row() self.last_trade = row row['type'] = 'Trade' row['action_type'] = 'Trade' row['trade_supplier'] = self.act.user_from.email row['trade_receiver'] = self.act.user_to.email row['status_receiver'] = self.status_receiver row['status_supplier'] = '' row['trade_confirmed'] = self.get_confirms() self.trades[self.act] = row 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 class TradeMetrics(MetricsMix): """we want get the data metrics of one device""" def __init__(self, *args, **kwargs): self.document = kwargs.pop('document') self.actions = copy.copy(self.document.actions) self.reversed_actions = copy.copy(self.document.actions) self.hid = self.document.file_hash self.devicehub_id = '' super().__init__(*args, **kwargs) self.reversed_actions.reverse() def get_metrics(self): self.last_trade = next(x for x in self.actions if x.t == 'Trade') self.act = self.last_trade row = self.get_template_row() row['type'] = 'Trade-Document' row['action_type'] = 'Trade-Document' if self.document.total_weight or self.document.weight: row['type'] = 'Trade-Container' row['action_type'] = 'Trade-Container' row['document_name'] = self.document.file_name row['trade_supplier'] = self.last_trade.user_from.email row['trade_receiver'] = self.last_trade.user_to.email row['trade_confirmed'] = self.get_confirms() row['status_receiver'] = '' row['status_supplier'] = '' row['trade_weight'] = self.document.total_weight if self.document.owner == self.last_trade.user_from: row['action_create_by'] = 'Supplier' elif self.document.owner == self.last_trade.user_to: row['action_create_by'] = 'Receiver' self.get_status(row) self.rows.append(row) return self.rows def get_status(self, row): """ We want to know if receiver or supplier do some action that change the status of the container. """ if not (self.document.total_weight and self.document.weight): return '' for ac in self.reversed_actions: if ac.type not in ['Use', 'Refurbish', 'Recycling', 'Management']: continue if ac.author == self.last_trade.user_from: row['status_supplier'] = ac.type row['status_supplier_created'] = ac.created if ac.author == self.last_trade.user_to: row['status_receiver'] = ac.type row['status_receiver_created'] = ac.created return '' 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. """ trade = None confirmations = [] confirms = [] for ac in self.document.actions: if ac.t == 'Trade': trade = ac elif ac.t == 'ConfirmDocument': confirms.append(ac.author) confirmations.append(ac) elif ac.t in ['RevokeDocument', 'ConfirmDocumentRevoke']: confirmations.append(ac) if confirmations and confirmations[-1].t == 'ConfirmDocument': if trade.user_from in confirms and trade.user_to in confirms: return True return False