From d8d8860357cbbce81c102e9619a1e9033fd7c5f4 Mon Sep 17 00:00:00 2001 From: CormacSharkey Date: Fri, 4 Apr 2025 11:34:17 +0100 Subject: [PATCH 1/3] adding in audio description on route instructions --- client/package-lock.json | 10 ++++++++++ client/package.json | 3 ++- client/src/DisplayRoute.js | 6 ++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/client/package-lock.json b/client/package-lock.json index 6d3dfbd..364665c 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -18,6 +18,7 @@ "deg2rad": "^1.0.0", "expo": "^52.0.7", "expo-location": "^18.0.2", + "expo-speech": "~13.0.1", "expo-status-bar": "~2.0.0", "react": "^18.3.1", "react-dom": "^18.3.1", @@ -9191,6 +9192,15 @@ "invariant": "^2.2.4" } }, + "node_modules/expo-speech": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/expo-speech/-/expo-speech-13.0.1.tgz", + "integrity": "sha512-J7tvFzORsFpIKihMnayeY5lCPc15giDrlN+ws2uUNo0MvLv1HCYEu/5p3+aMmZXXsY5I1QlconD4CwRWw3JFig==", + "license": "MIT", + "peerDependencies": { + "expo": "*" + } + }, "node_modules/expo-status-bar": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/expo-status-bar/-/expo-status-bar-2.0.0.tgz", diff --git a/client/package.json b/client/package.json index 3cb41ad..f4fb30d 100644 --- a/client/package.json +++ b/client/package.json @@ -39,7 +39,8 @@ "react-native-safe-area-context": "4.12.0", "react-native-screens": "~4.0.0", "react-native-svg": "15.8.0", - "react-native-websocket": "^1.0.2" + "react-native-websocket": "^1.0.2", + "expo-speech": "~13.0.1" }, "devDependencies": { "@babel/core": "^7.26.9", diff --git a/client/src/DisplayRoute.js b/client/src/DisplayRoute.js index ce9d897..19c80d4 100644 --- a/client/src/DisplayRoute.js +++ b/client/src/DisplayRoute.js @@ -8,6 +8,8 @@ import displayRouteStyles from './components/styles/DisplayRoute.styles'; import locationCircleIcon from './assets/location-circle.png'; +import * as Speech from 'expo-speech'; + export default function DisplayRouteScreen({ navigation, route }) { // route is a prop passed by the navigator, hence why that is used instead of other variable names const { origin, destination, routeData, polylineCoordinates } = route.params; @@ -53,6 +55,10 @@ export default function DisplayRouteScreen({ navigation, route }) { }; }, [devMode, checkProximityAndUpdate]); + useEffect(() => { + Speech.speak(currentInstruction); + }, [currentInstruction]) + function removeHtmlTags(instruction) { return instruction.replace(/<\/?[^>]+(>|$)/g, ''); } From adedc35818c0fb20ef1226a4041fd8eba6182a43 Mon Sep 17 00:00:00 2001 From: FEguare <123463013+FEguare@users.noreply.github.com> Date: Fri, 4 Apr 2025 12:09:29 +0100 Subject: [PATCH 2/3] linting fixes --- server/src/preferences.py | 39 ++++++++++++++++++++------------------- server/src/signup.py | 2 +- server/src/wayfinding.py | 14 +++++++++----- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/server/src/preferences.py b/server/src/preferences.py index cf687b6..9494afa 100644 --- a/server/src/preferences.py +++ b/server/src/preferences.py @@ -16,29 +16,29 @@ def __init__(self, api, logger: logging.Logger): def set_Preferences( self, - ): + ): @self.app.post("/setPreferences") async def set_Preferences(request: userPersonalizedSettings): self.logger.info("Received user personalized settings:") self.db_handle_preferences(request) - return {"message": "Successfully saved user preferences"} - + return {"message": "Successfully saved user preferences"} + def db_handle_preferences(self, request): db = DataBase() db.connect_db() dict = request.request_into_dictionary() - + for key, val in dict.items(): db.update_entry( - "user_personalized_settings", dict["username"], key, val + "user_personalized_settings", dict["username"], key, val ) self.logger.info("User preferences updated in the database") db.close_con() - + def db_initialise_preferences(self, username): db = DataBase() db.connect_db() - + dict = { "username": username, "bike": False, @@ -53,26 +53,27 @@ def db_initialise_preferences(self, username): "tram": False, "personal_bike": False, } - - db.add_entry( - "user_personalized_settings", dict - ) - self.logger.info("User has signed up and a preferences entry has been created for him with default values all set to false") - db.close_con() - + + db.add_entry("user_personalized_settings", dict) + self.logger.info("User has signed up and a preferences") + db.close_con() + def db_get_preferences(self, username): db = DataBase() db.connect_db() - motorwayPref = db.search_entry("user_personalized_settings", username, 'motorways') - tollsPref = db.search_entry("user_personalized_settings", username, 'tolls') + motorwayPref = db.search_entry( + "user_personalized_settings", username, "motorways" + ) + tollsPref = db.search_entry( + "user_personalized_settings", username, "tolls" + ) self.logger.info("User preferences retrieved from database") print("preferences retrieved from db", motorwayPref, tollsPref) db.close_con() - return { + return { "motorways": motorwayPref, "tolls": tollsPref, } - class userPersonalizedSettings(BaseModel): @@ -91,7 +92,7 @@ class userPersonalizedSettings(BaseModel): def request_into_dictionary(self): return { - "username": self.username, + "username": self.username, "bike": self.bike, "private_vehicle": self.privateVehicle, "accessibility": self.accessibility, diff --git a/server/src/signup.py b/server/src/signup.py index 937e276..b164233 100644 --- a/server/src/signup.py +++ b/server/src/signup.py @@ -58,7 +58,7 @@ def signup_user(self, username: str, password: str): self.logger.info(f"User {username} signed up") db.close_con() - + preferences.db_initialise_preferences(username) return True diff --git a/server/src/wayfinding.py b/server/src/wayfinding.py index 94dda0d..dca5eb9 100644 --- a/server/src/wayfinding.py +++ b/server/src/wayfinding.py @@ -15,6 +15,7 @@ logger = logging.getLogger("test_logger") preferences = Preferences(api=app, logger=logger) + @router.post("/wayfinding/get_routes") def get_routes( origin: str = Body(...), @@ -32,7 +33,8 @@ def get_routes( "key": GOOGLE_MAPS_API_KEY, } response = requests.get(url, params=parameters) - return response.json() + return response.json() + @router.post("/wayfinding/preferences/get_routes") def get_routes_with_preferences( @@ -47,14 +49,16 @@ def get_routes_with_preferences( preferencesList = preferences.db_get_preferences(username) print(preferencesList) if not preferencesList: - logger.error(f"No preferences found for user {username}. Using default route.") + logger.error( + f"No preferences found for user {username}. Using default route." + ) return get_routes( origin=origin, destination=destination, mode=mode, alternatives=alternatives, ) - + if preferencesList["tolls"] and preferencesList["motorways"]: toAvoid = "tolls|highways" elif preferencesList["tolls"]: @@ -63,7 +67,7 @@ def get_routes_with_preferences( toAvoid = "motorways" else: toAvoid = "" - + url = "https://maps.googleapis.com/maps/api/directions/json" parameters = { "origin": origin, @@ -72,7 +76,7 @@ def get_routes_with_preferences( "alternatives": str(alternatives).lower(), "key": GOOGLE_MAPS_API_KEY, "username": username, - "avoid": toAvoid + "avoid": toAvoid, } response = requests.get(url, params=parameters) From 116e14a4305a013efd42ca2679eb1f2276150f19 Mon Sep 17 00:00:00 2001 From: FEguare <123463013+FEguare@users.noreply.github.com> Date: Fri, 4 Apr 2025 12:22:40 +0100 Subject: [PATCH 3/3] linting fix --- client/src/DisplayRoute.js | 5 ++--- server/src/main.py | 5 +++-- server/src/signup.py | 5 +++-- server/src/wayfinding.py | 4 ++-- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/client/src/DisplayRoute.js b/client/src/DisplayRoute.js index 19c80d4..f6c34fc 100644 --- a/client/src/DisplayRoute.js +++ b/client/src/DisplayRoute.js @@ -3,13 +3,12 @@ import React, { useEffect, useState, useCallback } from 'react'; import { View, Text, Alert, TouchableOpacity, Switch } from 'react-native'; import MapView, { Polyline, Marker } from 'react-native-maps'; +import * as Speech from 'expo-speech'; import { haversine, startLocationTracking } from './utils/mapUtils'; import displayRouteStyles from './components/styles/DisplayRoute.styles'; import locationCircleIcon from './assets/location-circle.png'; -import * as Speech from 'expo-speech'; - export default function DisplayRouteScreen({ navigation, route }) { // route is a prop passed by the navigator, hence why that is used instead of other variable names const { origin, destination, routeData, polylineCoordinates } = route.params; @@ -57,7 +56,7 @@ export default function DisplayRouteScreen({ navigation, route }) { useEffect(() => { Speech.speak(currentInstruction); - }, [currentInstruction]) + }, [currentInstruction]); function removeHtmlTags(instruction) { return instruction.replace(/<\/?[^>]+(>|$)/g, ''); diff --git a/server/src/main.py b/server/src/main.py index 51858d3..ba22958 100644 --- a/server/src/main.py +++ b/server/src/main.py @@ -30,8 +30,9 @@ def __init__(self): self.weather_api = weatherAPI() self.networking = Networking(self.app, self.logger) self.preferences_logic = Preferences(self.app, self.logger) - self.signup_logic = Signup(self.app, self.logger, - self.preferences_logic) + self.signup_logic = Signup( + self.app, self.logger, self.preferences_logic + ) wayfinding_router = wayfinding_router_setup( preferences_logic=self.preferences_logic, diff --git a/server/src/signup.py b/server/src/signup.py index a8fc474..9edce33 100644 --- a/server/src/signup.py +++ b/server/src/signup.py @@ -9,8 +9,9 @@ class Signup: - def __init__(self, api, logger: logging.Logger, - preferences_logic: Preferences): + def __init__( + self, api, logger: logging.Logger, preferences_logic: Preferences + ): self.app = api self.logger = logger self.preferences = preferences_logic diff --git a/server/src/wayfinding.py b/server/src/wayfinding.py index fd7b15c..34feba7 100644 --- a/server/src/wayfinding.py +++ b/server/src/wayfinding.py @@ -14,7 +14,6 @@ preferences = Preferences(api=app, logger=logger) - @router.post("/wayfinding/get_routes") def get_routes( origin: str = Body(...), @@ -76,9 +75,10 @@ def get_routes_with_preferences( "alternatives": str(alternatives).lower(), "key": GOOGLE_MAPS_API_KEY, "username": username, - "avoid": toAvoid + "avoid": toAvoid, } response = requests.get(url, params=parameters) return response.json() + return router