Merge branch 'preferred_name'

This commit is contained in:
Tanner Collin 2022-08-31 00:12:56 +00:00
commit 0a6e9a6449
10 changed files with 47 additions and 37 deletions

View File

@ -299,7 +299,7 @@ class MemberSerializer(serializers.ModelSerializer):
index__owner_id=instance.id, index__owner_id=instance.id,
index__history_date__gte=ONE_WEEK, index__history_date__gte=ONE_WEEK,
).count() >= 6: ).count() >= 6:
msg = 'Member allow_last_scanned rate limit exceeded by: ' + instance.first_name + ' ' + instance.last_name msg = 'Member allow_last_scanned rate limit exceeded by: ' + instance.preferred_name + ' ' + instance.last_name
utils.alert_tanner(msg) utils.alert_tanner(msg)
logger.info(msg) logger.info(msg)
raise ValidationError(dict(allow_last_scanned='You\'re doing that too often.')) raise ValidationError(dict(allow_last_scanned='You\'re doing that too often.'))
@ -729,6 +729,7 @@ class UserSerializer(serializers.ModelSerializer):
class MyRegisterSerializer(RegisterSerializer): 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)
preferred_name = serializers.CharField(max_length=32)
request_id = serializers.CharField(required=False) request_id = serializers.CharField(required=False)
def validate_username(self, username): def validate_username(self, username):
@ -773,7 +774,7 @@ class MyPasswordChangeSerializer(PasswordChangeSerializer):
username=self.user.username, username=self.user.username,
password=self.data['new_password1'], password=self.data['new_password1'],
email=self.user.email, email=self.user.email,
first_name=self.user.member.first_name, first_name=self.user.member.preferred_name,
) )
data['username'] = self.user.member.mediawiki_username or self.user.username data['username'] = self.user.member.mediawiki_username or self.user.username
@ -814,7 +815,7 @@ class MyPasswordResetSerializer(PasswordResetSerializer):
def save(self): def save(self):
email = self.data['email'] email = self.data['email']
member = User.objects.get(email__iexact=email).member member = User.objects.get(email__iexact=email).member
logging.info('Password reset requested for: {} - {} {} ({})'.format(email, member.first_name, member.last_name, member.id)) logging.info('Password reset requested for: {} - {} {} ({})'.format(email, member.preferred_name, member.last_name, member.id))
super().save() super().save()
class MyPasswordResetConfirmSerializer(PasswordResetConfirmSerializer): class MyPasswordResetConfirmSerializer(PasswordResetConfirmSerializer):
@ -838,7 +839,7 @@ class MyPasswordResetConfirmSerializer(PasswordResetConfirmSerializer):
username=self.user.username, username=self.user.username,
password=self.data['new_password1'], password=self.data['new_password1'],
email=self.user.email, email=self.user.email,
first_name=self.user.member.first_name, first_name=self.user.member.preferred_name,
) )
data['username'] = self.user.member.mediawiki_username or self.user.username data['username'] = self.user.member.mediawiki_username or self.user.username
@ -865,7 +866,7 @@ class MyPasswordResetConfirmSerializer(PasswordResetConfirmSerializer):
self.user.member.save() self.user.member.save()
member = self.user.member member = self.user.member
logging.info('Password reset completed for: {} {} ({})'.format(member.first_name, member.last_name, member.id)) logging.info('Password reset completed for: {} {} ({})'.format(member.preferred_name, member.last_name, member.id))
if request_id: utils_stats.set_progress(request_id, 'Success! You can now log in as: ' + self.user.username) if request_id: utils_stats.set_progress(request_id, 'Success! You can now log in as: ' + self.user.username)
@ -915,7 +916,7 @@ class SpaceportAuthSerializer(LoginSerializer):
if user: if user:
data = self.context['request'].data.copy() data = self.context['request'].data.copy()
data['email'] = user.email data['email'] = user.email
data['first_name'] = user.member.first_name data['first_name'] = user.member.preferred_name
data['username'] = user.member.mediawiki_username or user.username data['username'] = user.member.mediawiki_username or user.username
utils_auth.set_wiki_password(data) utils_auth.set_wiki_password(data)

View File

@ -11,7 +11,7 @@ from . import models
from .permissions import is_admin_director from .permissions import is_admin_director
def get_object_owner(obj): def get_object_owner(obj):
full_name = lambda member: member.first_name + ' ' + member.last_name full_name = lambda member: member.preferred_name + ' ' + member.last_name
if obj.__class__.__name__ == 'Member': if obj.__class__.__name__ == 'Member':
return full_name(obj), obj.id return full_name(obj), obj.id

View File

@ -258,7 +258,7 @@ def gen_card_photo(member):
font = ImageFont.truetype('DejaVuSans.ttf', font_sizes[0]) font = ImageFont.truetype('DejaVuSans.ttf', font_sizes[0])
x = CARD_PHOTO_MARGIN_SIDE x = CARD_PHOTO_MARGIN_SIDE
y = my + CARD_PHOTO_MARGIN_TOP + CARD_PHOTO_MARGIN_SIDE y = my + CARD_PHOTO_MARGIN_TOP + CARD_PHOTO_MARGIN_SIDE
draw.text((x, y), str(member.first_name), (0,0,0), font=font) draw.text((x, y), str(member.preferred_name), (0,0,0), font=font)
font = ImageFont.truetype('DejaVuSans-Bold.ttf', font_sizes[1]) font = ImageFont.truetype('DejaVuSans-Bold.ttf', font_sizes[1])
y = my + CARD_PHOTO_MARGIN_TOP + CARD_PHOTO_MARGIN_SIDE + font_sizes[1] y = my + CARD_PHOTO_MARGIN_TOP + CARD_PHOTO_MARGIN_SIDE + font_sizes[1]
@ -339,13 +339,14 @@ def create_new_member(data, user):
user=user, user=user,
first_name=data['first_name'], first_name=data['first_name'],
last_name=data['last_name'], last_name=data['last_name'],
preferred_name=data['first_name'], preferred_name=data['preferred_name'],
) )
def register_user(data, user): def register_user(data, user):
data = data.copy() data = data.copy()
data['first_name'] = data['first_name'].title().strip() data['first_name'] = data['first_name'].title().strip()
data['last_name'] = data['last_name'].title().strip() data['last_name'] = data['last_name'].title().strip()
data['preferred_name'] = data['preferred_name'].title().strip()
# Sometimes during demos, a user makes a fake account then then has to be cleaned out # Sometimes during demos, a user makes a fake account then then has to be cleaned out
# Notify me that this has happened so I can go clean out the database # Notify me that this has happened so I can go clean out the database
@ -370,7 +371,7 @@ def register_user(data, user):
username=data['username'], username=data['username'],
password=data['password1'], password=data['password1'],
email=data['email'], email=data['email'],
first_name=data['first_name'], first_name=data['preferred_name'],
) )
if utils_auth.wiki_is_configured(): if utils_auth.wiki_is_configured():
@ -410,7 +411,7 @@ def register_user(data, user):
gen_search_strings() gen_search_strings()
cache.set('sign', 'Welcome to Protospace, {}!'.format(data['first_name'])) cache.set('sign', 'Welcome to Protospace, {}!'.format(data['preferred_name']))
BLANK_FORM = 'misc/blank_member_form.pdf' BLANK_FORM = 'misc/blank_member_form.pdf'
@ -434,7 +435,7 @@ def gen_member_forms(member):
packet = io.BytesIO() packet = io.BytesIO()
can = canvas.Canvas(packet, pagesize=letter) can = canvas.Canvas(packet, pagesize=letter)
can.drawRightString(600, 770, '{} {} ({})'.format( can.drawRightString(600, 770, '{} {} ({})'.format(
data['first_name'], data['preferred_name'],
data['last_name'], data['last_name'],
data['id'], data['id'],
)) ))

View File

@ -17,7 +17,7 @@ def send_welcome_email(member):
def replace_fields(text): def replace_fields(text):
return text.replace( return text.replace(
'[name]', member.first_name, '[name]', member.preferred_name,
).replace( ).replace(
'[username]', member.user.username, '[username]', member.user.username,
).replace( ).replace(
@ -45,7 +45,7 @@ def send_ical_email(member, session, ical_file):
date = session.datetime.astimezone(utils.TIMEZONE_CALGARY).strftime('%A, %B %d') date = session.datetime.astimezone(utils.TIMEZONE_CALGARY).strftime('%A, %B %d')
return text.replace( return text.replace(
'[name]', member.first_name, '[name]', member.preferred_name,
).replace( ).replace(
'[class]', session.course.name, '[class]', session.course.name,
).replace( ).replace(
@ -71,7 +71,7 @@ def send_ical_email(member, session, ical_file):
def send_interest_email(interest): def send_interest_email(interest):
def replace_fields(text): def replace_fields(text):
return text.replace( return text.replace(
'[name]', interest.user.member.first_name, '[name]', interest.user.member.preferred_name,
).replace( ).replace(
'[course]', interest.course.name, '[course]', interest.course.name,
).replace( ).replace(

View File

@ -28,7 +28,7 @@ def find_user(username):
def create_user(data): def create_user(data):
ldap_data = dict( ldap_data = dict(
first=data['first_name'], first=data['preferred_name'],
last=data['last_name'], last=data['last_name'],
username=data['username'], username=data['username'],
email=data['email'], email=data['email'],
@ -52,7 +52,7 @@ def add_to_group(member, group):
if ldap_api('add-to-group', ldap_data) != 200: raise if ldap_api('add-to-group', ldap_data) != 200: raise
except BaseException as e: except BaseException as e:
logger.error('LDAP Group - {} - {}'.format(e.__class__.__name__, str(e))) logger.error('LDAP Group - {} - {}'.format(e.__class__.__name__, str(e)))
m = '{} {} ({})'.format(member.first_name, member.last_name, member.id) m = '{} {} ({})'.format(member.preferred_name, member.last_name, member.id)
msg = 'Problem adding {} to group {}!'.format(m, group) msg = 'Problem adding {} to group {}!'.format(m, group)
utils.alert_tanner(msg) utils.alert_tanner(msg)
logger.info(msg) logger.info(msg)
@ -66,7 +66,7 @@ def remove_from_group(member, group):
if ldap_api('remove-from-group', ldap_data) != 200: raise if ldap_api('remove-from-group', ldap_data) != 200: raise
except BaseException as e: except BaseException as e:
logger.error('LDAP Group - {} - {}'.format(e.__class__.__name__, str(e))) logger.error('LDAP Group - {} - {}'.format(e.__class__.__name__, str(e)))
m = '{} {} ({})'.format(member.first_name, member.last_name, member.id) m = '{} {} ({})'.format(member.preferred_name, member.last_name, member.id)
msg = 'Problem removing {} from group {}!'.format(m, group) msg = 'Problem removing {} from group {}!'.format(m, group)
utils.alert_tanner(msg) utils.alert_tanner(msg)
logger.info(msg) logger.info(msg)

View File

@ -533,7 +533,7 @@ class DoorViewSet(viewsets.ViewSet, List):
if not member.is_allowed_entry: continue if not member.is_allowed_entry: continue
active_member_cards[card.card_number] = '{} ({})'.format( active_member_cards[card.card_number] = '{} ({})'.format(
member.first_name + ' ' + member.last_name[0], member.preferred_name + ' ' + member.last_name[0],
member.id, member.id,
) )
@ -547,7 +547,7 @@ class DoorViewSet(viewsets.ViewSet, List):
member = card.user.member member = card.user.member
t = utils.now_alberta_tz().strftime('%Y-%m-%d %H:%M:%S, %a %I:%M %p') t = utils.now_alberta_tz().strftime('%Y-%m-%d %H:%M:%S, %a %I:%M %p')
logger.info('Scan - Time: {} | Name: {} {} ({})'.format(t, member.first_name, member.last_name, member.id)) logger.info('Scan - Time: {} | Name: {} {} ({})'.format(t, member.preferred_name, member.last_name, member.id))
utils_stats.calc_card_scans() utils_stats.calc_card_scans()
@ -570,7 +570,7 @@ class LockoutViewSet(viewsets.ViewSet, List):
authorization = {} authorization = {}
authorization['id'] = member.id authorization['id'] = member.id
authorization['name'] = member.first_name + ' ' + member.last_name authorization['name'] = member.preferred_name + ' ' + member.last_name
authorization['common'] = bool(member.orientation_date or member.vetted_date) authorization['common'] = bool(member.orientation_date or member.vetted_date)
authorization['lathe'] = bool(member.lathe_cert_date) and authorization['common'] authorization['lathe'] = bool(member.lathe_cert_date) and authorization['common']
authorization['mill'] = bool(member.mill_cert_date) and authorization['common'] authorization['mill'] = bool(member.mill_cert_date) and authorization['common']
@ -1096,10 +1096,10 @@ class ProtocoinViewSet(Base):
destination_delta = amount destination_delta = amount
memo = 'Protocoin - Transaction {} ({}) sent ₱ {} to {} ({})'.format( memo = 'Protocoin - Transaction {} ({}) sent ₱ {} to {} ({})'.format(
source_member.first_name + ' ' + source_member.last_name, source_member.preferred_name + ' ' + source_member.last_name,
source_member.id, source_member.id,
amount, amount,
destination_member.first_name + ' ' + destination_member.last_name, destination_member.preferred_name + ' ' + destination_member.last_name,
destination_member.id, destination_member.id,
) )
@ -1145,7 +1145,7 @@ class ProtocoinViewSet(Base):
res = dict( res = dict(
balance=user_balance, balance=user_balance,
first_name=source_user.member.first_name, first_name=source_user.member.preferred_name,
) )
return Response(res) return Response(res)

View File

@ -212,7 +212,7 @@ export function AccountForm(props) {
<Header size='medium'>Member Details</Header> <Header size='medium'>Member Details</Header>
<div className='field'> <div className='field'>
<label>Username</label> <label>Spaceport Username</label>
<p>{user.username}</p> <p>{user.username}</p>
</div> </div>

View File

@ -42,7 +42,7 @@ export function AdminVet(props) {
onClick={handleVet} onClick={handleVet}
loading={loading} loading={loading}
> >
{yousure ? 'You Sure?' : 'Vet ' + member.first_name} {yousure ? 'You Sure?' : 'Vet ' + member.preferred_name}
</Button> </Button>
); );
} }
@ -87,7 +87,7 @@ export function AdminVetting(props) {
<Table.Body> <Table.Body>
{(displayAll ? vetting : vetting.slice(0,5)).map(x => {(displayAll ? vetting : vetting.slice(0,5)).map(x =>
<Table.Row key={x.id}> <Table.Row key={x.id}>
<Table.Cell><Link to={'/members/'+x.id}>{x.first_name} {x.last_name}</Link></Table.Cell> <Table.Cell><Link to={'/members/'+x.id}>{x.preferred_name} {x.last_name}</Link></Table.Cell>
<Table.Cell><a href={'mailto:'+x.email}>Email</a></Table.Cell> <Table.Cell><a href={'mailto:'+x.email}>Email</a></Table.Cell>
<Table.Cell> <Table.Cell>
<Icon name='circle' color={statusColor[x.status]} /> <Icon name='circle' color={statusColor[x.status]} />

View File

@ -527,10 +527,6 @@ export function AdminMemberInfo(props) {
<BasicTable> <BasicTable>
<Table.Body> <Table.Body>
<Table.Row>
<Table.Cell>Name:</Table.Cell>
<Table.Cell>{member.first_name} {member.last_name}</Table.Cell>
</Table.Row>
<Table.Row> <Table.Row>
<Table.Cell>Status:</Table.Cell> <Table.Cell>Status:</Table.Cell>
<Table.Cell> <Table.Cell>

View File

@ -75,14 +75,14 @@ export function SignupForm(props) {
const handleCheck = (e, v) => setInput({ ...input, [v.name]: v.checked }); const handleCheck = (e, v) => setInput({ ...input, [v.name]: v.checked });
const genUsername = () => { const genUsername = () => {
if (input.first_name && input.last_name) { if (input.preferred_name && input.last_name) {
let first_name = input.first_name.trim().toLowerCase(); let preferred_name = input.preferred_name.trim().toLowerCase();
let last_name = input.last_name.trim().toLowerCase(); let last_name = input.last_name.trim().toLowerCase();
first_name = first_name.replace(/[^a-z- ]+/g, ''); preferred_name = preferred_name.replace(/[^a-z- ]+/g, '');
last_name = last_name.replace(/[^a-z- ]+/g, ''); last_name = last_name.replace(/[^a-z- ]+/g, '');
first_name = first_name.replace(/[ -]/g, '.'); preferred_name = preferred_name.replace(/[ -]/g, '.');
last_name = last_name.replace(/[ -]/g, '.'); last_name = last_name.replace(/[ -]/g, '.');
return first_name + '.' + last_name; return preferred_name + '.' + last_name;
} else { } else {
return ''; return '';
} }
@ -147,6 +147,18 @@ export function SignupForm(props) {
/> />
</Form.Group> </Form.Group>
<Form.Group widths='equal'>
<Form.Input
label='Preferred First Name'
name='preferred_name'
autoComplete='off'
fluid
onChange={handleChange}
error={error.preferred_name}
/>
<Form.Field/>
</Form.Group>
<Form.Input <Form.Input
label='Email' label='Email'
autoComplete='off' autoComplete='off'
@ -181,7 +193,7 @@ export function SignupForm(props) {
{!!genUsername() && {!!genUsername() &&
<Form.Input <Form.Input
label='Username' label='Spaceport Username'
name='username' name='username'
value={genUsername()} value={genUsername()}
error={error.username} error={error.username}