diff --git a/apiserver/apiserver/api/serializers.py b/apiserver/apiserver/api/serializers.py index 82948f7..0cc8702 100644 --- a/apiserver/apiserver/api/serializers.py +++ b/apiserver/apiserver/api/serializers.py @@ -11,7 +11,7 @@ from rest_auth.serializers import PasswordChangeSerializer, PasswordResetSeriali from rest_auth.serializers import UserDetailsSerializer import re -from . import models, fields, utils, utils_ldap, utils_auth +from . import models, fields, utils, utils_ldap, utils_auth, utils_stats from .. import settings, secrets #class UsageSerializer(serializers.ModelSerializer): @@ -515,6 +515,7 @@ class MyRegisterSerializer(RegisterSerializer): first_name = serializers.CharField(max_length=32) last_name = serializers.CharField(max_length=32) existing_member = serializers.ChoiceField(['true', 'false']) + request_id = serializers.CharField(required=False) def validate_username(self, username): if re.search(r'[^a-z.]', username): @@ -539,6 +540,8 @@ class MyRegisterSerializer(RegisterSerializer): user.delete() raise ValidationError(dict(non_field_errors='Can only register from Protospace.')) + if data['request_id']: utils_stats.set_progress(data['request_id'], 'Registering...') + utils.register_user(data, user) class MyPasswordChangeSerializer(PasswordChangeSerializer): diff --git a/apiserver/apiserver/api/utils.py b/apiserver/apiserver/api/utils.py index 01c6bf6..93aab74 100644 --- a/apiserver/apiserver/api/utils.py +++ b/apiserver/apiserver/api/utils.py @@ -18,7 +18,7 @@ from django.db.models import Sum from django.core.cache import cache from django.utils.timezone import now, pytz -from . import models, serializers, utils_ldap +from . import models, serializers, utils_ldap, utils_stats STATIC_FOLDER = 'data/static/' @@ -311,6 +311,7 @@ def link_old_member(data, user): raise ValidationError(dict(email=msg)) if utils_ldap.is_configured(): + if data['request_id']: utils_stats.set_progress(data['request_id'], 'Finding LDAP account...') result = utils_ldap.find_user(user.username) if result == 200: if utils_ldap.set_password(data) != 200: @@ -331,6 +332,8 @@ def link_old_member(data, user): raise ValidationError(dict(non_field_errors=msg)) + if data['request_id']: utils_stats.set_progress(data['request_id'], 'Linking old member data...') + member.user = user member.first_name = data['first_name'].title() member.last_name = data['last_name'].title() @@ -349,6 +352,7 @@ def create_new_member(data, user): raise ValidationError(dict(email=msg)) if utils_ldap.is_configured(): + if data['request_id']: utils_stats.set_progress(data['request_id'], 'Creating LDAP account...') result = utils_ldap.find_user(user.username) if result == 200: msg = 'Username was found in old portal.' @@ -368,6 +372,8 @@ def create_new_member(data, user): logger.info(msg) raise ValidationError(dict(non_field_errors=msg)) + if data['request_id']: utils_stats.set_progress(data['request_id'], 'Creating new member...') + models.Member.objects.create( user=user, first_name=data['first_name'].title(), @@ -387,6 +393,9 @@ def register_user(data, user): user.delete() raise + if data['request_id']: utils_stats.set_progress(data['request_id'], 'Done!') + + BLANK_FORM = 'misc/blank_member_form.pdf' def gen_member_forms(member): serializer = serializers.MemberSerializer(member) diff --git a/apiserver/apiserver/api/utils_stats.py b/apiserver/apiserver/api/utils_stats.py index 0ff93db..0a6b938 100644 --- a/apiserver/apiserver/api/utils_stats.py +++ b/apiserver/apiserver/api/utils_stats.py @@ -149,3 +149,12 @@ def calc_card_scans(): date=today_alberta_tz(), defaults=dict(card_scans=count), ) + +def get_progress(request_id): + return cache.get('request-progress-' + request_id, []) + +def set_progress(request_id, data): + logger.info('Request %s progress: %s', request_id, data) + progress = get_progress(request_id) + progress.append(data) + cache.set('request-progress-' + request_id, progress) diff --git a/apiserver/apiserver/api/views.py b/apiserver/apiserver/api/views.py index d583b95..bfceb5a 100644 --- a/apiserver/apiserver/api/views.py +++ b/apiserver/apiserver/api/views.py @@ -506,6 +506,14 @@ class StatsViewSet(viewsets.ViewSet, List): return Response(stats) + @action(detail=False, methods=['get']) + def progress(self, request): + try: + request_id = request.query_params['request_id'] + return Response(utils_stats.get_progress(request_id)) + except KeyError: + raise exceptions.ValidationError(dict(request_id='This field is required.')) + @action(detail=False, methods=['post']) def bay_108_temp(self, request): try: diff --git a/webclient/src/LoginSignup.js b/webclient/src/LoginSignup.js index 7950bff..73baec9 100644 --- a/webclient/src/LoginSignup.js +++ b/webclient/src/LoginSignup.js @@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react'; import { BrowserRouter as Router, Switch, Route, Link, useParams, useLocation } from 'react-router-dom'; import './light.css'; import { Container, Divider, Dropdown, Form, Grid, Header, Icon, Image, Menu, Message, Segment, Table } from 'semantic-ui-react'; -import { requester } from './utils.js'; +import { requester, randomString } from './utils.js'; export function LoginForm(props) { const [input, setInput] = useState({ username: '' }); @@ -75,6 +75,7 @@ export function LoginForm(props) { export function SignupForm(props) { const [input, setInput] = useState({ email: '' }); const [error, setError] = useState({}); + const [progress, setProgress] = useState([]); const [loading, setLoading] = useState(false); const location = useLocation(); @@ -94,14 +95,29 @@ export function SignupForm(props) { if (loading) return; setLoading(true); input.username = genUsername(); - const data = { ...input, email: input.email.toLowerCase(), bypass_code: bypass_code }; + + const request_id = randomString(); + const getStatus = () => { + requester('/stats/progress/?request_id='+request_id, 'GET') + .then(res => { + setProgress(res); + }) + .catch(err => { + console.log(err); + }); + }; + const interval = setInterval(getStatus, 500); + + const data = { ...input, email: input.email.toLowerCase(), bypass_code: bypass_code, request_id: request_id }; requester('/registration/', 'POST', '', data) .then(res => { + clearInterval(interval); setError({}); props.setTokenCache(res.key); window.scrollTo(0, 0); }) .catch(err => { + clearInterval(interval); setLoading(false); console.log(err); setError(err.data); @@ -179,6 +195,10 @@ export function SignupForm(props) { error={error.password2} /> +
+ {progress.map(x => <>{x}
>)}
+