diff --git a/ereuse_devicehub/resources/documents/device_row.py b/ereuse_devicehub/resources/documents/device_row.py index 91c96000..fedef026 100644 --- a/ereuse_devicehub/resources/documents/device_row.py +++ b/ereuse_devicehub/resources/documents/device_row.py @@ -379,3 +379,74 @@ class ActionRow(OrderedDict): self['Type'] = allocate['type'] self['LiveCreate'] = allocate['liveCreate'] self['UsageTimeHdd'] = allocate['usageTimeHdd'] + + +class InternalStatsRow(OrderedDict): + + def __init__(self, user, create, actions): + super().__init__() + # General information about all internal stats + # user, quart, month, year: + # Snapshot (Registers) + # Snapshots (Update) + # Snapshots (All) + # Allocate + # Deallocate + # Live + self.actions = actions + year, month = create.split('-') + + self['User'] = user + self['Year'] = year + self['Quarter'] = self.quarter(month) + self['Month'] = month + self['Snapshot (Registers)'] = 0 + self['Snapshot (Update)'] = 0 + self['Snapshot (All)'] = 0 + self['Allocates'] = 0 + self['Deallocates'] = 0 + self['Lives'] = 0 + + self.count_actions() + + def count_actions(self): + for ac in self.actions: + self.is_snapshot( + self.is_deallocate( + self.is_allocate(ac) + ) + ) + + def is_allocate(self, ac): + if ac.type == 'Allocate': + self['Allocates'] += 1 + return ac + + def is_deallocate(self, ac): + if ac.type == 'Deallocate': + self['Deallocates'] += 1 + return ac + + def is_snapshot(self, ac): + if not ac.type == 'Snapshot': + return + self['Snapshot (All)'] += 1 + + canary = False + for _ac in ac.device.actions: + if _ac.created < ac.created: + canary = True + break + + if canary: + self['Snapshot (Update)'] += 1 + else: + self['Snapshot (Registers)'] += 1 + + def quarter(self, month): + q = {1: 'Q1', 2: 'Q1', 3: 'Q1', + 4: 'Q2', 5: 'Q2', 6: 'Q2', + 7: 'Q3', 8: 'Q3', 9: 'Q3', + 10: 'Q4', 11: 'Q4', 12: 'Q4', + } + return q[int(month)] diff --git a/ereuse_devicehub/resources/documents/documents.py b/ereuse_devicehub/resources/documents/documents.py index cd1d5254..d84021d2 100644 --- a/ereuse_devicehub/resources/documents/documents.py +++ b/ereuse_devicehub/resources/documents/documents.py @@ -21,7 +21,8 @@ from ereuse_devicehub.resources.action import models as evs from ereuse_devicehub.resources.device import models as devs from ereuse_devicehub.resources.deliverynote.models import Deliverynote from ereuse_devicehub.resources.device.views import DeviceView -from ereuse_devicehub.resources.documents.device_row import DeviceRow, StockRow, ActionRow +from ereuse_devicehub.resources.documents.device_row import (DeviceRow, StockRow, ActionRow, + InternalStatsRow) from ereuse_devicehub.resources.lot import LotView from ereuse_devicehub.resources.lot.models import Lot from ereuse_devicehub.resources.hash_reports import insert_hash, ReportHash @@ -212,7 +213,7 @@ class StockDocumentView(DeviceView): def generate_post_csv(self, query): """Get device query and put information in csv format.""" data = StringIO() - cw = csv.writer(data) + cw = csv.writer(data, delimiter=';', lineterminator="\n", quotechar='"') first = True for device in query: d = StockRow(device) @@ -255,8 +256,38 @@ class StampsView(View): class InternalStatsView(View): def get(self): - result = '' - return jsonify(result) + return self.get_datas() + + def get_datas(self): + actions = evs.Action.query.filter( + evs.Action.type.in_(('Snapshot', 'Live', 'Allocate', 'Deallocate'))) + d = {} + for ac in actions: + create = '{}-{}'.format(ac.created.year, ac.created.month) + user = ac.author.email + + if not user in d: + d[user] = {} + + if not create in d[user]: + d[user][create] = [] + + d[user][create].append(ac) + + + data = StringIO() + cw = csv.writer(data, delimiter=';', lineterminator="\n", quotechar='"') + cw.writerow(InternalStatsRow('', "2000-1", []).keys()) + for user, createds in d.items(): + for create, actions in createds.items(): + cw.writerow(InternalStatsRow(user, create, actions).values()) + + bfile = data.getvalue().encode('utf-8') + output = make_response(bfile) + insert_hash(bfile) + output.headers['Content-Disposition'] = 'attachment; filename=internal-stats.csv' + output.headers['Content-type'] = 'text/csv' + return output class DocumentDef(Resource):