add nick
[laas.git] / src / booking / stats.py
1 ##############################################################################
2 # Copyright (c) 2020 Parker Berberian, Sawyer Bergeron, Sean Smith and others.
3 #
4 # All rights reserved. This program and the accompanying materials
5 # are made available under the terms of the Apache License, Version 2.0
6 # which accompanies this distribution, and is available at
7 # http://www.apache.org/licenses/LICENSE-2.0
8 ##############################################################################
9 import os
10 from booking.models import Booking
11 from resource_inventory.models import ResourceQuery, ResourceProfile
12 from datetime import datetime, timedelta
13 from collections import Counter
14 import pytz
15
16
17 class StatisticsManager(object):
18
19     @staticmethod
20     def getContinuousBookingTimeSeries(span=28):
21         """
22         Calculate Booking usage data points.
23
24         Gathers all active bookings that fall in interval [(now - span), (now + 1 week)].
25         x data points are every 12 hours
26         y values are the integer number of bookings/users active at time
27         """
28
29         anuket_colors = [
30             '#6BDAD5',  # Turquoise
31             '#E36386',  # Pale Violet Red
32             '#F5B335',  # Sandy Brown
33             '#007473',  # Teal
34             '#BCE194',  # Gainsboro
35             '#00CE7C',  # Sea Green
36         ]
37
38         lfedge_colors = [
39             '#0049B0',
40             '#B481A5',
41             '#6CAFE4',
42             '#D33668',
43             '#28245A'
44         ]
45
46         x = []
47         y = []
48         users = []
49         projects = []
50         profiles = {str(profile): [] for profile in ResourceProfile.objects.all()}
51
52         now = datetime.now(pytz.utc)
53         delta = timedelta(days=span)
54         start = now - delta
55         end = now + timedelta(weeks=1)
56
57         bookings = Booking.objects.filter(
58             start__lte=end,
59             end__gte=start
60         ).prefetch_related("collaborators")
61
62         # get data
63         while start <= end:
64             active_users = 0
65
66             books = bookings.filter(
67                 start__lte=start,
68                 end__gte=start
69             ).prefetch_related("collaborators")
70
71             for booking in books:
72                 active_users += booking.collaborators.all().count() + 1
73
74             x.append(str(start.month) + '-' + str(start.day))
75             y.append(books.count())
76
77             step_profiles = Counter([
78                 str(config.profile)
79                 for book in books
80                 for config in book.resource.template.getConfigs()
81             ])
82
83             for profile in ResourceProfile.objects.all():
84                 profiles[str(profile)].append(step_profiles[str(profile)])
85             users.append(active_users)
86
87             start += timedelta(hours=12)
88
89         in_use = len(ResourceQuery.filter(working=True, booked=True))
90         not_in_use = len(ResourceQuery.filter(working=True, booked=False))
91         maintenance = len(ResourceQuery.filter(working=False))
92
93         projects = [x.project for x in bookings]
94         proj_count = sorted(Counter(projects).items(), key=lambda x: x[1])
95
96         project_keys = [proj[0] for proj in proj_count[-5:]]
97         project_keys = ['None' if x is None else x for x in project_keys]
98         project_counts = [proj[1] for proj in proj_count[-5:]]
99
100         resources = {key: [x, value] for key, value in profiles.items()}
101
102         return {
103             "resources": resources,
104             "booking": [x, y],
105             "user": [x, users],
106             "utils": [in_use, not_in_use, maintenance],
107             "projects": [project_keys, project_counts],
108             "colors": anuket_colors if os.environ.get('TEMPLATE_OVERRIDE_DIR') == 'laas' else lfedge_colors
109         }