From 5804995376c85ce0ce846f770a50d298303d123a Mon Sep 17 00:00:00 2001 From: Tanner Collin Date: Tue, 25 Jan 2022 00:27:55 +0000 Subject: [PATCH 1/4] Implement basic usage tracking --- apiserver/apiserver/api/models.py | 19 +++---- apiserver/apiserver/api/views.py | 84 ++++++++++++++++++++++--------- 2 files changed, 71 insertions(+), 32 deletions(-) diff --git a/apiserver/apiserver/api/models.py b/apiserver/apiserver/api/models.py index 7b9b20e..fe473b6 100644 --- a/apiserver/apiserver/api/models.py +++ b/apiserver/apiserver/api/models.py @@ -164,15 +164,16 @@ class StatsSpaceActivity(models.Model): date = models.DateField(default=today_alberta_tz) card_scans = models.IntegerField() -#class UsageTrack(models.Model): -# user = models.ForeignKey(User, related_name='usages', blank=True, null=True, on_delete=models.SET_NULL) -# -# # member_id = models.IntegerField(blank=True, null=True) # restrict to current users for now -# username = models.CharField(max_length=64) # allows us to match non-Spaceport users later -# -# devicename = models.CharField(max_length=64) -# start_time = models.DateTimeField(auto_now_add=True) -# num_seconds = models.IntegerField() +class Usage(models.Model): + user = models.ForeignKey(User, related_name='usages', blank=True, null=True, on_delete=models.SET_NULL) + + username = models.CharField(max_length=64, blank=True) # incase of LDAP-Spaceport mismatch + + device = models.CharField(max_length=64) + start_time = models.DateTimeField(auto_now_add=True) + num_seconds = models.IntegerField() + + history = HistoricalRecords(excluded_fields=['num_seconds']) class HistoryIndex(models.Model): content_type = models.ForeignKey(ContentType, null=True, on_delete=models.SET_NULL) diff --git a/apiserver/apiserver/api/views.py b/apiserver/apiserver/api/views.py index 5afeb2c..7a77fe2 100644 --- a/apiserver/apiserver/api/views.py +++ b/apiserver/apiserver/api/views.py @@ -598,32 +598,70 @@ class StatsViewSet(viewsets.ViewSet, List): username = request.data['username'] first_name = username.split('.')[0].title() - track[devicename] = dict(time=time.time(), username=first_name) + track[devicename] = dict( + time=time.time(), + username=username, + first_name=first_name, + ) cache.set('track', track) - ## update device usage - ## issue: sometimes two sessions are created - ## issue: sometimes two /track/ requests are sent and double time is counted - #last_session = models.UsageTrack.objects.filter(devicename=devicename).last() - #if not last_session or last_session.username != username: - # try: - # user = User.objects.get(username__iexact=username) - # except User.DoesNotExist: - # msg = 'Device tracker problem finding username: ' + username - # utils.alert_tanner(msg) - # logger.error(msg) - # user = None + return Response(200) - # models.UsageTrack.objects.create( - # user=user, - # username=username, - # devicename=devicename, - # num_seconds=0, - # ) - # logging.info('New ' + devicename + ' session created for: ' + username) - #else: - # last_session.num_seconds = F('num_seconds') + 10 - # last_session.save(update_fields=['num_seconds']) + @action(detail=False, methods=['post']) + def usage(self, request): + #if 'seconds' not in request.data: + # raise exceptions.ValidationError(dict(seconds='This field is required.')) + + if 'device' not in request.data: + raise exceptions.ValidationError(dict(device='This field is required.')) + + device = request.data['device'] + data = request.data.get('data', None) + seconds = request.data.get('seconds', 20) + + if 'username' in request.data: + username = request.data['username'] + else: + track = cache.get('track', {}) + try: + username = track['device']['username'] + except KeyError: + msg = 'Usage tracker problem finding username for device: {}'.format(device) + #utils.alert_tanner(msg) + logger.error(msg) + username = '' + + + last_session = models.Usage.objects.filter(device=device).last() + if not last_session or last_session.username != username: + try: + user = User.objects.get(username__iexact=username) + except User.DoesNotExist: + msg = 'Usage trackerproblem finding user for username: {}'.format(username or '[no username]') + #utils.alert_tanner(msg) + logger.error(msg) + user = None + + last_session = models.Usage.objects.create( + user=user, + username=username, + device=device, + num_seconds=0, + ) + logging.info('New %s session created for: %s', device, username or '[no username]') + + + logging.debug('Device %s data: %s', device, data) + + if device == 'TROTECS300' and data and int(data) > 3: + should_count = True + else: + should_count = False + + if should_count: + logging.debug('Counting %s seconds.', seconds) + last_session.num_seconds = F('num_seconds') + seconds + last_session.save(update_fields=['num_seconds']) return Response(200) From 8b3fe7434e1ef6d94cd1ab8e69d454d3efca676c Mon Sep 17 00:00:00 2001 From: Tanner Collin Date: Wed, 26 Jan 2022 02:01:46 +0000 Subject: [PATCH 2/4] Fix username bug --- apiserver/apiserver/api/views.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apiserver/apiserver/api/views.py b/apiserver/apiserver/api/views.py index 7a77fe2..0e331f3 100644 --- a/apiserver/apiserver/api/views.py +++ b/apiserver/apiserver/api/views.py @@ -624,7 +624,7 @@ class StatsViewSet(viewsets.ViewSet, List): else: track = cache.get('track', {}) try: - username = track['device']['username'] + username = track[device]['username'] except KeyError: msg = 'Usage tracker problem finding username for device: {}'.format(device) #utils.alert_tanner(msg) From 14577146428a7fa65fa7b46fa4cbef9c6864f4d0 Mon Sep 17 00:00:00 2001 From: Tanner Collin Date: Thu, 3 Feb 2022 06:31:41 +0000 Subject: [PATCH 3/4] Add last_update to Usage table --- apiserver/apiserver/api/models.py | 1 + 1 file changed, 1 insertion(+) diff --git a/apiserver/apiserver/api/models.py b/apiserver/apiserver/api/models.py index 316053c..6fe3a47 100644 --- a/apiserver/apiserver/api/models.py +++ b/apiserver/apiserver/api/models.py @@ -172,6 +172,7 @@ class Usage(models.Model): device = models.CharField(max_length=64) start_time = models.DateTimeField(auto_now_add=True) + last_update = models.DateTimeField(auto_now=True) num_seconds = models.IntegerField() history = HistoricalRecords(excluded_fields=['num_seconds']) From 2cbb872248a66fc1eb457b32bf267d470cc2f9d3 Mon Sep 17 00:00:00 2001 From: Tanner Collin Date: Thu, 3 Feb 2022 23:37:26 +0000 Subject: [PATCH 4/4] Add memo, should_bill fields to Usage table --- apiserver/apiserver/api/models.py | 6 ++++-- apiserver/apiserver/api/views.py | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/apiserver/apiserver/api/models.py b/apiserver/apiserver/api/models.py index 6fe3a47..134214e 100644 --- a/apiserver/apiserver/api/models.py +++ b/apiserver/apiserver/api/models.py @@ -172,10 +172,12 @@ class Usage(models.Model): device = models.CharField(max_length=64) start_time = models.DateTimeField(auto_now_add=True) - last_update = models.DateTimeField(auto_now=True) + updated_at = models.DateTimeField(auto_now=True) num_seconds = models.IntegerField() + memo = models.TextField(blank=True) + should_bill = models.BooleanField(default=True) - history = HistoricalRecords(excluded_fields=['num_seconds']) + history = HistoricalRecords(excluded_fields=['num_seconds', 'updated_at']) class HistoryIndex(models.Model): content_type = models.ForeignKey(ContentType, null=True, on_delete=models.SET_NULL) diff --git a/apiserver/apiserver/api/views.py b/apiserver/apiserver/api/views.py index d6e17cb..e12284f 100644 --- a/apiserver/apiserver/api/views.py +++ b/apiserver/apiserver/api/views.py @@ -663,6 +663,7 @@ class StatsViewSet(viewsets.ViewSet, List): username=username, device=device, num_seconds=0, + memo='', ) logging.info('New %s session created for: %s', device, username or '[no username]')