From 42ad1ac3274f42399fc39b2c03d23cd283b2d5cf Mon Sep 17 00:00:00 2001 From: Tanner Collin Date: Sun, 14 Nov 2021 03:49:18 +0000 Subject: [PATCH] Convert Card last_seen_at Date to last_seen DateTime --- apiserver/apiserver/api/models.py | 3 ++- apiserver/apiserver/api/serializers.py | 5 ++--- apiserver/apiserver/api/utils_stats.py | 10 +++++++--- apiserver/apiserver/api/views.py | 4 ++-- apiserver/convert_card_seen.py | 24 ++++++++++++++++++++++++ webclient/src/AdminMembers.js | 12 ++++++++++-- webclient/src/Cards.js | 23 +++++++++++++++++++++-- webclient/src/Home.js | 2 +- 8 files changed, 69 insertions(+), 14 deletions(-) create mode 100755 apiserver/convert_card_seen.py diff --git a/apiserver/apiserver/api/models.py b/apiserver/apiserver/api/models.py index a6ddcda..dd01cab 100644 --- a/apiserver/apiserver/api/models.py +++ b/apiserver/apiserver/api/models.py @@ -105,9 +105,10 @@ class Card(models.Model): card_number = models.CharField(unique=True, max_length=16, blank=True, null=True) notes = models.TextField(blank=True, null=True) last_seen_at = models.DateField(blank=True, null=True) + last_seen = models.DateTimeField(blank=True, null=True) active_status = models.CharField(max_length=32, blank=True, null=True) - history = HistoricalRecords(excluded_fields=['last_seen_at']) + history = HistoricalRecords(excluded_fields=['last_seen_at', 'last_seen']) class Course(models.Model): name = models.TextField(blank=True, null=True) diff --git a/apiserver/apiserver/api/serializers.py b/apiserver/apiserver/api/serializers.py index ce74f76..81af3cd 100644 --- a/apiserver/apiserver/api/serializers.py +++ b/apiserver/apiserver/api/serializers.py @@ -73,7 +73,6 @@ class TransactionSerializer(serializers.ModelSerializer): fields = '__all__' read_only_fields = [ 'id', - 'last_seen_at', 'user', 'recorder', 'paypal_txn_id', @@ -354,7 +353,7 @@ class AdminSearchSerializer(serializers.Serializer): queryset = obj.user.cards else: queryset = models.Card.objects.filter(member_id=obj.id) - queryset = queryset.order_by('-last_seen_at') + queryset = queryset.order_by('-last_seen') serializer = CardSerializer(data=queryset, many=True) serializer.is_valid() return serializer.data @@ -406,7 +405,7 @@ class CardSerializer(serializers.ModelSerializer): fields = '__all__' read_only_fields = [ 'id', - 'last_seen_at', + 'last_seen', 'user', ] diff --git a/apiserver/apiserver/api/utils_stats.py b/apiserver/apiserver/api/utils_stats.py index 0a6b938..54fc990 100644 --- a/apiserver/apiserver/api/utils_stats.py +++ b/apiserver/apiserver/api/utils_stats.py @@ -9,8 +9,9 @@ from django.utils.timezone import now, pytz from apiserver.api import models from apiserver import secrets +tz = pytz.timezone('America/Edmonton') def today_alberta_tz(): - return datetime.now(pytz.timezone('America/Edmonton')).date() + return datetime.now(tz).date() DEFAULTS = { 'last_card_change': time.time(), @@ -140,13 +141,16 @@ def check_mumble_server(): def calc_card_scans(): date = today_alberta_tz() + dt = datetime.combine(date, datetime.min.time()) + midnight = tz.localize(dt) + cards = models.Card.objects - count = cards.filter(last_seen_at=date).count() + count = cards.filter(last_seen__gte=midnight).count() cache.set('card_scans', count) models.StatsSpaceActivity.objects.update_or_create( - date=today_alberta_tz(), + date=date, defaults=dict(card_scans=count), ) diff --git a/apiserver/apiserver/api/views.py b/apiserver/apiserver/api/views.py index 9c1d9f7..13c0d79 100644 --- a/apiserver/apiserver/api/views.py +++ b/apiserver/apiserver/api/views.py @@ -122,7 +122,7 @@ class SearchViewSet(Base, Retrieve): elif self.action == 'create' and sort == 'last_scanned': if self.request.user.member.allow_last_scanned: queryset = queryset.filter(allow_last_scanned=True) - queryset = queryset.order_by('-user__cards__last_seen_at') + queryset = queryset.order_by('-user__cards__last_seen') else: queryset = [] elif self.action == 'create' and sort == 'best_looking': @@ -465,7 +465,7 @@ class DoorViewSet(viewsets.ViewSet, List): @action(detail=True, methods=['post']) def seen(self, request, pk=None): card = get_object_or_404(models.Card, card_number=pk) - card.last_seen_at = utils.today_alberta_tz() + card.last_seen = now() card.save() try: diff --git a/apiserver/convert_card_seen.py b/apiserver/convert_card_seen.py new file mode 100755 index 0000000..8977d0f --- /dev/null +++ b/apiserver/convert_card_seen.py @@ -0,0 +1,24 @@ +import django, sys, os +os.environ['DJANGO_SETTINGS_MODULE'] = 'apiserver.settings' +django.setup() + +from datetime import datetime +import json +import pytz + +from apiserver.api import models, utils + +tz = pytz.timezone('America/Edmonton') + +cards = models.Card.objects.order_by('last_seen_at') + +for card in cards: + seen = card.last_seen_at + if seen: + t = datetime.combine(seen, datetime.min.time()) + card.last_seen = tz.localize(t) + card.save() + + print('card', card.card_number, 'date', seen, '-->', card.last_seen) + +print('Done.') diff --git a/webclient/src/AdminMembers.js b/webclient/src/AdminMembers.js index 0981ba2..231066a 100644 --- a/webclient/src/AdminMembers.js +++ b/webclient/src/AdminMembers.js @@ -103,8 +103,16 @@ function AdminCardDetail(props) { - Notes: {input.notes || 'None'}, - Last Seen: {input.last_seen_at || 'Unknown'} + Notes: {input.notes || 'None'}
+ Last Seen:{' '} + {input.last_seen ? + input.last_seen > '2021-11-14T02:01:35.415685Z' ? + moment.utc(input.last_seen).tz('America/Edmonton').format('lll') + : + moment.utc(input.last_seen).tz('America/Edmonton').format('ll') + : + 'Unknown' + } : diff --git a/webclient/src/Cards.js b/webclient/src/Cards.js index e73b3e2..10eb768 100644 --- a/webclient/src/Cards.js +++ b/webclient/src/Cards.js @@ -1,6 +1,7 @@ import React, { useState, useEffect } from 'react'; import { BrowserRouter as Router, Switch, Route, Link, useParams } from 'react-router-dom'; import './light.css'; +import moment from 'moment-timezone'; import { Button, Container, Divider, Dropdown, Form, Grid, Header, Icon, Image, Menu, Message, Segment, Table } from 'semantic-ui-react'; import { BasicTable, requester, staticUrl } from './utils.js'; import { NotFound, PleaseLogin } from './Misc.js'; @@ -45,7 +46,16 @@ export function Cards(props) { {x.card_number} {x.notes} - {x.last_seen_at} + + {x.last_seen ? + x.last_seen > '2021-11-14T02:01:35.415685Z' ? + moment.utc(x.last_seen).tz('America/Edmonton').format('lll') + : + moment.utc(x.last_seen).tz('America/Edmonton').format('ll') + : + 'Unknown' + } + {cardStatus(x)} )} @@ -64,7 +74,16 @@ export function Cards(props) { Last Seen: - {card.last_seen_at} + + {card.last_seen ? + card.last_seen > '2021-11-14T02:01:35.415685Z' ? + moment.utc(card.last_seen).tz('America/Edmonton').format('lll') + : + moment.utc(card.last_seen).tz('America/Edmonton').format('ll') + : + 'Unknown' + } + Active: diff --git a/webclient/src/Home.js b/webclient/src/Home.js index 7b8a685..caa2e93 100644 --- a/webclient/src/Home.js +++ b/webclient/src/Home.js @@ -14,7 +14,7 @@ function MemberInfo(props) { const member = user.member; const lastTrans = user.transactions && user.transactions.slice(0,3); - const lastCard = user.cards && user.cards.sort((a, b) => a.last_seen_at < b.last_seen_at)[0]; + const lastCard = user.cards && user.cards.sort((a, b) => a.last_seen < b.last_seen)[0]; return (