Skip to content

Commit

Permalink
OTP-888 Mobility profile additions.
Browse files Browse the repository at this point in the history
  • Loading branch information
JymDyerIBI committed Nov 30, 2023
1 parent 282223d commit 08d9695
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
import spark.Request;
import spark.Response;

import java.util.Collections;
import java.util.Date;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Expand All @@ -37,6 +39,8 @@ public class OtpUserController extends AbstractUserController<OtpUser> {
private static final String VERIFY_ROUTE_TEMPLATE = "/:%s/%s/:%s";
/** Regex to check E.164 phone number format per https://www.twilio.com/docs/glossary/what-e164 */
private static final Pattern PHONE_E164_PATTERN = Pattern.compile("^\\+[1-9]\\d{1,14}$");
/** Mobility devices used to calculate mobility mode. Keywords are taken from Georgia Tech document. */
private static final Set<String> MOBILITY_DEVICES = Set.of("Device", "MScooter", "WChairE", "WChairM", "Some");

public OtpUserController(String apiPrefix) {
super(apiPrefix, Persistence.otpUsers, OTP_USER_PATH);
Expand All @@ -51,9 +55,16 @@ OtpUser preCreateHook(OtpUser user, Request req) {
Auth0Connection.ensureApiUserHasApiKey(req);
user.applicationId = requestingUser.apiUser.id;
}
user.mobilityMode = calculateMobilityMode(user);
return super.preCreateHook(user, req);
}

@Override
OtpUser preUpdateHook(OtpUser user, OtpUser preExistingUser, Request req) {
user.mobilityMode = calculateMobilityMode(user);
return super.preUpdateHook(user, preExistingUser, req);
}

@Override
protected void buildEndpoint(ApiEndpoint baseEndpoint) {
LOG.info("Registering path {}/{}.", ROOT_ROUTE, VERIFY_PATH);
Expand Down Expand Up @@ -170,4 +181,68 @@ public static boolean isPhoneNumberValidE164(String phoneNumber) {
Matcher m = PHONE_E164_PATTERN.matcher(phoneNumber);
return m.matches();
}

/**
* Calculate and return the "mobility mode", a keyword or compound keyword specified by Georgia Tech,
* based on a number {@code OtpUser} fields related to mobility.
* @param user with fields that are consulted to calculate mobility mode
* @return mobility mode as a single string
*/
private static String calculateMobilityMode(OtpUser user) {
// Variable names and the strings we parse are from Georgia Tech document, to facilitate syncing changes.
// The testing for devices and vision in this order are from the same document; note that this means the
// devices tested for later will override the earlier "Temp"orary settings.
String mModeTemp = "None";
String visionTemp = "None";

if (user.mobilityDevices == null) {
user.mobilityDevices = Collections.EMPTY_LIST;
}
if (user.mobilityDevices.isEmpty() || user.mobilityDevices.contains("none")) {
user.mobilityDevices.clear();
} else {
if (user.mobilityDevices.contains("white cane")) {
visionTemp = "Blind";
}
if (user.mobilityDevices.contains("manual walker")
|| user.mobilityDevices.contains("wheeled walker")
|| user.mobilityDevices.contains("cane")
|| user.mobilityDevices.contains("crutches")
|| user.mobilityDevices.contains("stroller")
|| user.mobilityDevices.contains("service animal")) {
mModeTemp = "Device";
}
if (user.mobilityDevices.contains("mobility scooter")) {
mModeTemp = "MScooter";
}
if (user.mobilityDevices.contains("electric wheelchair")) {
mModeTemp = "WChairE";
}
if (user.mobilityDevices.contains("manual wheelchair")) {
mModeTemp = "WChairM";
}

if ("None".equals(mModeTemp) && user.isMobilityLimited) {
mModeTemp = "Some";
}
}

if (visionTemp.isEmpty() && "low-vision".equals(user.visionLimitation)) {
visionTemp = "LowVision";
} else if (visionTemp.isEmpty() && "legally blind".equals(user.visionLimitation)) {
visionTemp = "Blind";
}

// Create combinations for mobility mode and vision
if (Set.of("LowVision", "Blind").contains(visionTemp)) {
if ("None".equals(mModeTemp)) {
return visionTemp;
} else if (MOBILITY_DEVICES.contains(mModeTemp)) {
return mModeTemp + "-" + visionTemp;
}
} else if (MOBILITY_DEVICES.contains(mModeTemp)) {
return mModeTemp;
}
return "None";
}
}
13 changes: 13 additions & 0 deletions src/main/java/org/opentripplanner/middleware/models/OtpUser.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,22 @@ public enum Notification {
/** Whether the user has consented to terms of use. */
public boolean hasConsentedToTerms;

/** Whether the user has indicated that their mobility is limited (slower). */
public boolean isMobilityLimited;

/** Whether the phone number has been verified. */
public boolean isPhoneNumberVerified;

/** User may have indicated zero or more mobility devices. */
public Collection<String> mobilityDevices;

/** Compound keyword that controller calculates from mobility and vision values. */
@JsonIgnore
public String mobilityMode;

/** One of "low-vision" "legally blind" "none" */
public String visionLimitation;

/**
* Notification preferences for this user
* (EMAIL and/or SMS and/or PUSH).
Expand Down

0 comments on commit 08d9695

Please sign in to comment.