Display progress updates during registration

This commit is contained in:
Tanner Collin 2021-09-04 22:28:12 +00:00
parent 1f5f99c971
commit 77653e9eb9
6 changed files with 55 additions and 4 deletions

View File

@ -11,7 +11,7 @@ from rest_auth.serializers import PasswordChangeSerializer, PasswordResetSeriali
from rest_auth.serializers import UserDetailsSerializer from rest_auth.serializers import UserDetailsSerializer
import re 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 from .. import settings, secrets
#class UsageSerializer(serializers.ModelSerializer): #class UsageSerializer(serializers.ModelSerializer):
@ -515,6 +515,7 @@ class MyRegisterSerializer(RegisterSerializer):
first_name = serializers.CharField(max_length=32) first_name = serializers.CharField(max_length=32)
last_name = serializers.CharField(max_length=32) last_name = serializers.CharField(max_length=32)
existing_member = serializers.ChoiceField(['true', 'false']) existing_member = serializers.ChoiceField(['true', 'false'])
request_id = serializers.CharField(required=False)
def validate_username(self, username): def validate_username(self, username):
if re.search(r'[^a-z.]', username): if re.search(r'[^a-z.]', username):
@ -539,6 +540,8 @@ class MyRegisterSerializer(RegisterSerializer):
user.delete() user.delete()
raise ValidationError(dict(non_field_errors='Can only register from Protospace.')) 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) utils.register_user(data, user)
class MyPasswordChangeSerializer(PasswordChangeSerializer): class MyPasswordChangeSerializer(PasswordChangeSerializer):

View File

@ -18,7 +18,7 @@ from django.db.models import Sum
from django.core.cache import cache from django.core.cache import cache
from django.utils.timezone import now, pytz 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/' STATIC_FOLDER = 'data/static/'
@ -311,6 +311,7 @@ def link_old_member(data, user):
raise ValidationError(dict(email=msg)) raise ValidationError(dict(email=msg))
if utils_ldap.is_configured(): 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) result = utils_ldap.find_user(user.username)
if result == 200: if result == 200:
if utils_ldap.set_password(data) != 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)) 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.user = user
member.first_name = data['first_name'].title() member.first_name = data['first_name'].title()
member.last_name = data['last_name'].title() member.last_name = data['last_name'].title()
@ -349,6 +352,7 @@ def create_new_member(data, user):
raise ValidationError(dict(email=msg)) raise ValidationError(dict(email=msg))
if utils_ldap.is_configured(): 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) result = utils_ldap.find_user(user.username)
if result == 200: if result == 200:
msg = 'Username was found in old portal.' msg = 'Username was found in old portal.'
@ -368,6 +372,8 @@ def create_new_member(data, user):
logger.info(msg) logger.info(msg)
raise ValidationError(dict(non_field_errors=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( models.Member.objects.create(
user=user, user=user,
first_name=data['first_name'].title(), first_name=data['first_name'].title(),
@ -387,6 +393,9 @@ def register_user(data, user):
user.delete() user.delete()
raise raise
if data['request_id']: utils_stats.set_progress(data['request_id'], 'Done!')
BLANK_FORM = 'misc/blank_member_form.pdf' BLANK_FORM = 'misc/blank_member_form.pdf'
def gen_member_forms(member): def gen_member_forms(member):
serializer = serializers.MemberSerializer(member) serializer = serializers.MemberSerializer(member)

View File

@ -149,3 +149,12 @@ def calc_card_scans():
date=today_alberta_tz(), date=today_alberta_tz(),
defaults=dict(card_scans=count), 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)

View File

@ -506,6 +506,14 @@ class StatsViewSet(viewsets.ViewSet, List):
return Response(stats) 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']) @action(detail=False, methods=['post'])
def bay_108_temp(self, request): def bay_108_temp(self, request):
try: try:

View File

@ -2,7 +2,7 @@ import React, { useState, useEffect } from 'react';
import { BrowserRouter as Router, Switch, Route, Link, useParams, useLocation } from 'react-router-dom'; import { BrowserRouter as Router, Switch, Route, Link, useParams, useLocation } from 'react-router-dom';
import './light.css'; import './light.css';
import { Container, Divider, Dropdown, Form, Grid, Header, Icon, Image, Menu, Message, Segment, Table } from 'semantic-ui-react'; 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) { export function LoginForm(props) {
const [input, setInput] = useState({ username: '' }); const [input, setInput] = useState({ username: '' });
@ -75,6 +75,7 @@ export function LoginForm(props) {
export function SignupForm(props) { export function SignupForm(props) {
const [input, setInput] = useState({ email: '' }); const [input, setInput] = useState({ email: '' });
const [error, setError] = useState({}); const [error, setError] = useState({});
const [progress, setProgress] = useState([]);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const location = useLocation(); const location = useLocation();
@ -94,14 +95,29 @@ export function SignupForm(props) {
if (loading) return; if (loading) return;
setLoading(true); setLoading(true);
input.username = genUsername(); 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) requester('/registration/', 'POST', '', data)
.then(res => { .then(res => {
clearInterval(interval);
setError({}); setError({});
props.setTokenCache(res.key); props.setTokenCache(res.key);
window.scrollTo(0, 0); window.scrollTo(0, 0);
}) })
.catch(err => { .catch(err => {
clearInterval(interval);
setLoading(false); setLoading(false);
console.log(err); console.log(err);
setError(err.data); setError(err.data);
@ -179,6 +195,10 @@ export function SignupForm(props) {
error={error.password2} error={error.password2}
/> />
<p>
{progress.map(x => <>{x}<br /></>)}
</p>
<Form.Button loading={loading} error={error.non_field_errors}> <Form.Button loading={loading} error={error.non_field_errors}>
Sign Up Sign Up
</Form.Button> </Form.Button>

View File

@ -1,6 +1,8 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { Table } from 'semantic-ui-react'; import { Table } from 'semantic-ui-react';
export const randomString = () => Math.random().toString(36).substr(2, 10);
export const siteUrl = window.location.protocol + '//' + window.location.hostname; export const siteUrl = window.location.protocol + '//' + window.location.hostname;
export const apiUrl = window.location.protocol + '//api.' + window.location.hostname; export const apiUrl = window.location.protocol + '//api.' + window.location.hostname;
export const staticUrl = window.location.protocol + '//static.' + window.location.hostname; export const staticUrl = window.location.protocol + '//static.' + window.location.hostname;