61 lines
2.2 KiB
Python
61 lines
2.2 KiB
Python
import csv
|
|
import io
|
|
|
|
|
|
# Maps our field names to possible CSV column header aliases (case-insensitive)
|
|
FIELD_ALIASES = {
|
|
'windows_id': ['windows_id', 'employeeid', 'employee_id', 'wid', 'id', 'user_id', 'samaccountname'],
|
|
'first_name': ['first_name', 'firstname', 'givenname', 'given_name', 'prenom'],
|
|
'last_name': ['last_name', 'lastname', 'surname', 'sn', 'family_name', 'nom'],
|
|
'email': ['email', 'mail', 'email_address', 'emailaddress'],
|
|
'department': ['department', 'dept', 'division'],
|
|
'job_title': ['job_title', 'title', 'position', 'jobtitle', 'job_position'],
|
|
'phone': ['phone', 'telephone', 'mobile', 'phonenumber', 'telephonenumber'],
|
|
'location': ['location', 'office', 'site', 'physicaldeliveryofficename'],
|
|
}
|
|
|
|
|
|
def parse_users_csv(file_stream):
|
|
"""
|
|
Parse a CSV file stream and return (users_list, errors_list).
|
|
|
|
Accepts BOM-prefixed UTF-8 or plain UTF-8. Column headers are
|
|
matched case-insensitively against FIELD_ALIASES.
|
|
"""
|
|
try:
|
|
content = file_stream.read().decode('utf-8-sig')
|
|
except (UnicodeDecodeError, AttributeError):
|
|
return [], ['Could not decode file. Please use UTF-8 encoding.']
|
|
|
|
reader = csv.DictReader(io.StringIO(content))
|
|
|
|
if not reader.fieldnames:
|
|
return [], ['CSV file is empty or has no header row.']
|
|
|
|
# Build a lookup: normalised header -> our field name
|
|
norm_headers = {h.lower().strip().replace(' ', '_'): h for h in reader.fieldnames}
|
|
col_map = {} # our_field -> actual_csv_header
|
|
for field, aliases in FIELD_ALIASES.items():
|
|
for alias in aliases:
|
|
if alias in norm_headers:
|
|
col_map[field] = norm_headers[alias]
|
|
break
|
|
|
|
errors = []
|
|
users = []
|
|
|
|
for row_num, row in enumerate(reader, start=2):
|
|
user = {}
|
|
for field in FIELD_ALIASES:
|
|
csv_col = col_map.get(field)
|
|
user[field] = (row.get(csv_col, '') or '').strip() if csv_col else ''
|
|
|
|
wid = user.get('windows_id', '').strip()
|
|
if not wid:
|
|
errors.append(f'Row {row_num}: missing windows_id — skipped.')
|
|
continue
|
|
|
|
users.append(user)
|
|
|
|
return users, errors
|