Commit b50bc385 authored by Malsha Rathnasiri's avatar Malsha Rathnasiri

Merge branch 'IT18094664'

parents 816c46f3 7cfb27ff
venv/
backend/output.wav
backend/backend/output.m4a
ffmpeg-2022-08-03-git-d3f48e68b3-essentials_build/ffmpeg.exe
ngrok.exe
ffmpeg-2022-08-03-git-d3f48e68b3-essentials_build/ffplay.exe
ffmpeg-2022-08-03-git-d3f48e68b3-essentials_build/ffprobe.exe
{
"e997a5256149a4b76e6bfd6cbf519c5e5a0f1d278a3d8fa1253022b03c90473b": true,
"af683c96e0ffd2cf81287651c9433fa44debc1220ca7cb431fe482747f34a505": true,
"12bb71342c6255bbf50437ec8f4441c083f47cdb74bd89160c15e4f43e52a1cb": true,
"40b842e832070c58deac6aa9e08fa459302ee3f9da492c7e77d93d2fbf4a56fd": true
}
node_modules/
node_modules2/
.expo/
dist/
npm-debug.*
*.jks
*.p8
*.p12
*.key
*.mobileprovision
*.orig.*
web-build/
# macOS
.DS_Store
import { StatusBar } from 'expo-status-bar';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import useCachedResources from './hooks/useCachedResources';
import useColorScheme from './hooks/useColorScheme';
import Navigation from './navigation/index';
import { NativeBaseProvider, Box } from "native-base";
export default function App() {
const isLoadingComplete = useCachedResources();
const colorScheme = useColorScheme();
if (!isLoadingComplete) {
return null;
} else {
return (
<NativeBaseProvider>
<SafeAreaProvider>
<Navigation colorScheme={colorScheme} />
<StatusBar />
</SafeAreaProvider>
</NativeBaseProvider>
);
}
}
import React, { createContext, useContext, useState, useEffect, useLayoutEffect } from "react";
import axios from "axios";
import { BACKEND_URL } from "./constants";
// import { nexlAxios } from "../../constants/helper";
import AsyncStorage from '@react-native-async-storage/async-storage';
import { Platform } from 'react-native'
// import {
// IAuthContext,
// IAuthRequest,
// STORAGE_BEARER_TOKEN,
// UNINITIALISED,
// USER_EMAIL,
// } from "./IAuthContext";
// import { Loading } from "./state/Loading";
// import { getEnvironment } from "../../constants/variables";
// import { AxiosError, AxiosResponse } from "axios";
// import { rollbar } from "./ErrorBoundary";
// import { ENDPOINT as endpoint } from "./constants";
// const AuthContext = createContext({
// isLoggedIn: false,
// token: "",
// email: "",
// error: "",
// loading: false,
// initialised: false,
// login: UNINITIALISED,
// logout: UNINITIALISED,
// });
// export const useAuthContext = () => useContext(AuthContext);
// export const AuthConsumer = AuthContext.Consumer;
// interface IProps {
// children: any;
// }
// interface ILoginData {
// error: string;
// user: {
// email: string;
// id: string;
// first_name: string;
// last_name: string;
// };
// }
// const endpoint = getEnvironment().endpoint;
export const isLoggedIn = async () => {
const token = await AsyncStorage.getItem('access_token')
console.log({ token, has: !!token })
return !!token
}
export const login = async (username, password) => {
const endpoint = false ? 'register' : 'login';
const payload = { username: username, password: password }
const headers = new Headers({ "Content-Type": 'application./json', 'mode': 'no-cors', 'Access-Control-Allow-Headers': '*' })
const options = { method: 'POST', data: payload, headers }
axios.defaults.baseURL = BACKEND_URL;
axios.defaults.timeout = 1500;
console.log({ payload })
return axios.post('/api/auth/token/obtain/', payload)
.then(async (response) => {
const { access, refresh, user } = response.data;
axios.defaults.headers.common.Authorization = `Token ${access}`;
await AsyncStorage.setItem('user_id', String(user.id))
await AsyncStorage.setItem('username', user.username)
await AsyncStorage.setItem('user_email', user.email)
await AsyncStorage.setItem('access_token', access)
await AsyncStorage.setItem('refresh_token', refresh)
console.log("login successful")
return true
// Actions.main();
})
.catch(error => {
console.log('error in login authentication')
throw Error(error)
});
}
export const logout = async () => {
await AsyncStorage.clear()
}
// export const AuthProvider = ({ children }) => {
// const [isLoggedIn, setIsLoggedIn] = useState(false);
// const [token, setToken] = useState("");
// const [email, setEmail] = useState("");
// const [error, setError] = useState("");
// const [loading, setLoading] = useState(false);
// const [initialised, setInitialised] = useState(false);
// const login = async ({ email, password, rememberMe }) => {
// setLoading(true);
// nexlAxios(false)
// .post(`${endpoint}/accounts/sign_in.json`, {
// source: "iOS app",
// account: {
// email,
// password,
// remember_me: rememberMe ? "1" : "0",
// },
// })
// .then(async (response) => {
// setLoading(false);
// const user = response.data.user;
// user.email && setIsLoggedIn(true);
// const token = response.headers["authorization"];
// setToken(token);
// await AsyncStorage.setItem(USER_EMAIL, email);
// setEmail(email);
// rollbar.setPerson(user.id, `${user.first_name} ${user.last_name}`, user.email);
// })
// .catch((result) => {
// setLoading(false);
// setError(
// result?.response?.data?.error || result?.message || "An unknown error has occurred.",
// );
// });
// };
// const loginWithBearerToken = async (bearer) => {
// if (bearer) {
// setLoading(true);
// await nexlAxios(false, bearer)
// .post(`${endpoint}/accounts/sign_in.json`, undefined, {
// headers: {
// Authorization: bearer,
// },
// })
// .then((response) => {
// setLoading(false);
// const user = response.data.user;
// user.email && setIsLoggedIn(true);
// rollbar.setPerson(user.id, `${user.first_name} ${user.last_name}`, user.email);
// })
// .catch(() => {
// setLoading(false);
// setToken("");
// });
// }
// };
// const logout = async () => {
// const token = await AsyncStorage.getItem(STORAGE_BEARER_TOKEN);
// token && (await nexlAxios(false, token).post(`${endpoint}/sign_out.json`));
// setToken("");
// setIsLoggedIn(false);
// await AsyncStorage.removeItem(STORAGE_BEARER_TOKEN);
// rollbar.clearPerson();
// };
// // look if token / email exist in local storage on initialising the app
// // if token exists, try log in with token
// useLayoutEffect(() => {
// let isMounted = true;
// const initialise = async () => {
// const bearerToken = await AsyncStorage.getItem(STORAGE_BEARER_TOKEN);
// setToken(bearerToken || "");
// const userEmail = await AsyncStorage.getItem(USER_EMAIL);
// setEmail(userEmail || "");
// bearerToken && (await loginWithBearerToken(bearerToken));
// setInitialised(true);
// };
// if (isMounted) {
// initialise();
// }
// return () => {
// isMounted = false;
// };
// }, []);
// // update token to local storage on token change
// useEffect(() => {
// AsyncStorage.setItem(STORAGE_BEARER_TOKEN, token);
// }, [token]);
// return (
// <AuthContext.Provider
// value={{
// login,
// isLoggedIn,
// logout,
// token,
// email: email.toLowerCase(),
// loading,
// error,
// initialised,
// }}
// >
// {initialised ? children : <Loading copy="Logging in..." />}
// </AuthContext.Provider>
// );
// };
\ No newline at end of file
import { BACKEND_URL } from "./constants"
import AsyncStorage from '@react-native-async-storage/async-storage';
import { useNavigation } from "@react-navigation/native";
import axios from "axios";
//"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ0b2tlbl90eXBlIjoiYWNjZXNzIiwiZXhwIjoxNjYxMzU2NDA5LCJpYXQiOjE2NjAxNDY4MDksImp0aSI6ImFhMTljMmY2ZDNkMzRiNDdhZmZmM2FjMzVjNzI4MWJhIiwidXNlcl9pZCI6MX0.IVzibo_Rf2xzoT1J5o1L3zwu3mco6ODcNPC-7imu3Lo"
// const headers =
const getHeaders = async () => {
var token = await AsyncStorage.getItem('access_token')
return {
Authorization: `JWT ${token}`, 'Content-Type': 'application/json',
// "Access-Control-Allow-Methods": "DELETE, POST, GET, OPTIONS",
// "Access-Control-Allow-Headers": "Content-Type, Authorization, Access-Control-Allow-Methods",
// "Access-Control-Allow-Origin": "*",
}
}
export const create = async (resource, values) => {
const headers = await getHeaders()
console.log({ headers }, 'create')
console.log({values})
try {
return fetch(`${BACKEND_URL}/${resource}/`, { method: 'POST', body: JSON.stringify(values), headers })
// return Axios.post(`${BACKEND_URL}/${resource}/`, values)
}
catch (e) {
console.log(e)
}
}
export const getList = async (resource, params) => {
const url = new URL(`${BACKEND_URL}/${resource}/`)
if (params) {
Object.keys(params).map(key => {
url.searchParams.append(key, params[key])
})
}
const headers = await getHeaders()
console.log(headers, 'getList')
return fetch(url, { method: 'GET', headers: headers })
return axios.get(url.toString(), null, { headers })
}
export const getOne = async (resource, id) => {
const url = new URL(`${BACKEND_URL}/${resource}/${id}/`)
const headers = await getHeaders()
console.log(headers, 'getONe')
return fetch(url, { method: "GET", headers: headers })
}
\ No newline at end of file
// export const BACKEND_URL = "http://192.168.8.103:8000"
import { Platform } from 'react-native'
export const BACKEND_ADDRESS = Platform.OS == 'web' ? "http://127.0.0.1:8000" : "https://c881-2402-4000-2280-1401-f8b7-3e41-83a-2250.in.ngrok.io"
export const BACKEND_URL = `${BACKEND_ADDRESS}`
{
"expo": {
"name": "MobileApp",
"slug": "MobileApp",
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/images/icon.png",
"scheme": "myapp",
"userInterfaceStyle": "automatic",
"splash": {
"image": "./assets/images/splash.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"updates": {
"fallbackToCacheTimeout": 0
},
"assetBundlePatterns": [
"**/*"
],
"ios": {
"supportsTablet": true
},
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/images/adaptive-icon.png",
"backgroundColor": "#ffffff"
}
},
"web": {
"favicon": "./assets/images/favicon.png"
}
}
}
module.exports = function(api) {
api.cache(true);
return {
presets: ['babel-preset-expo']
};
};
import React from 'react'
import { Text, View, StyleSheet, Button } from 'react-native';
import { Audio } from 'expo-av';
import { createIconSetFromFontello } from '@expo/vector-icons';
import * as FileSystem from 'expo-file-system';
import { BACKEND_URL } from '../api/constants';
export const AudioRecorder = ({ setDetectedText }) => {
const [recording, setRecording] = React.useState();
const [sound, setSound] = React.useState();
async function startRecording() {
try {
console.log('Requesting permissions..');
await Audio.requestPermissionsAsync();
await Audio.setAudioModeAsync({
allowsRecordingIOS: true,
playsInSilentModeIOS: true,
});
console.log('Starting recording..');
const { recording } = await Audio.Recording.createAsync(
Audio.RECORDING_OPTIONS_PRESET_HIGH_QUALITY
);
setRecording(recording);
console.log('Recording started');
} catch (err) {
console.error('Failed to start recording', err);
}
}
async function stopRecording() {
console.log('Stopping recording..');
setRecording(undefined);
await recording.stopAndUnloadAsync();
const uri = recording.getURI();
console.log('Recording stopped and stored at', uri)
//console.log(recording)
const headers = {
'Content-Type': 'multipart/form-data'
// 'Content-Type': 'application/x-www-form-urlencoded',
}
playSound(uri)
FileSystem.uploadAsync(`${BACKEND_URL}/mlmodels/detect/`, uri, { headers: headers, uploadType: FileSystem.FileSystemUploadType.MULTIPART })
.then(data => JSON.parse(data.body))
.then(data => {
// console.log({ result: data });
setDetectedText(data.result);
// setTimeout(() => setDetectedText(''), 1000)
})
.catch(err => console.log({ err }))
}
async function playSound(uri) {
console.log('Loading Sound');
// const { sound } = await Audio.Sound.createAsync(
// require(uri)
// );
// setSound(sound);
// console.log('Playing Sound');
// await sound.playAsync();
}
return (
<Button
style={{ height: '100%', padding: 5 }}
title={recording ? 'Stop' : 'Record'}
onPress={recording ? stopRecording : startRecording}
/>
);
}
\ No newline at end of file
import * as WebBrowser from 'expo-web-browser';
import { StyleSheet, TouchableOpacity } from 'react-native';
import Colors from '../constants/Colors';
import { MonoText } from './StyledText';
import { Text, View } from './Themed';
export default function EditScreenInfo({ path }: { path: string }) {
return (
<View>
<View style={styles.getStartedContainer}>
<Text
style={styles.getStartedText}
lightColor="rgba(0,0,0,0.8)"
darkColor="rgba(255,255,255,0.8)">
Open up the code for this screen:
</Text>
<View
style={[styles.codeHighlightContainer, styles.homeScreenFilename]}
darkColor="rgba(255,255,255,0.05)"
lightColor="rgba(0,0,0,0.05)">
<MonoText>{path}</MonoText>
</View>
<Text
style={styles.getStartedText}
lightColor="rgba(0,0,0,0.8)"
darkColor="rgba(255,255,255,0.8)">
Change any of the text, save the file, and your app will automatically update.
</Text>
</View>
<View style={styles.helpContainer}>
<TouchableOpacity onPress={handleHelpPress} style={styles.helpLink}>
<Text style={styles.helpLinkText} lightColor={Colors.light.tint}>
Tap here if your app doesn't automatically update after making changes
</Text>
</TouchableOpacity>
</View>
</View>
);
}
function handleHelpPress() {
WebBrowser.openBrowserAsync(
'https://docs.expo.io/get-started/create-a-new-app/#opening-the-app-on-your-phonetablet'
);
}
const styles = StyleSheet.create({
getStartedContainer: {
alignItems: 'center',
marginHorizontal: 50,
},
homeScreenFilename: {
marginVertical: 7,
},
codeHighlightContainer: {
borderRadius: 3,
paddingHorizontal: 4,
},
getStartedText: {
fontSize: 17,
lineHeight: 24,
textAlign: 'center',
},
helpContainer: {
marginTop: 15,
marginHorizontal: 20,
alignItems: 'center',
},
helpLink: {
paddingVertical: 15,
},
helpLinkText: {
textAlign: 'center',
},
});
import { Ionicons } from "@expo/vector-icons";
import React, { useState } from "react";
import { View } from "react-native";
import { CONVO_DEFAULT_ICON_COLOR, CONVO_STOP_ICON_COLOR, styles } from "../util/styles";
import * as Speech from 'expo-speech';
export const PlayMessage = ({ message }) => {
const [isPlaying, setIsPlaying] = useState(false)
const [isTtsReady, setIsTtsReady] = useState(false)
// // Tts.setDucking(true);
// Tts.addEventListener('tts-start', (event) => console.log("start"));
// Tts.addEventListener('tts-finish', (event) => console.log("finish"));
// const synth = window.speechSynthesis;
// const speech = new SpeechSynthesisUtterance(message)
// speech.lang = 'en'
// speech.onend((e) => console.log('end'))
const onSpeechDone = (props) => {
setIsPlaying(false)
}
const onPlayPress = () => {
setIsPlaying(true)
// synth.speak(speech)
Speech.speak(message, { onDone: onSpeechDone });
// speech.onend((e) => console.log('end'))
}
const onStopPress = () => {
Speech.stop()
setIsPlaying(false)
}
if (!isPlaying) {
return (
<Ionicons name="play" size={15} style={styles.chatIcon} onPress={onPlayPress} color={CONVO_DEFAULT_ICON_COLOR} />
)
}
else {
return (
<Ionicons name="stop" size={15} style={styles.chatIcon} onPress={onStopPress} color={CONVO_STOP_ICON_COLOR} />
)
}
}
\ No newline at end of file
import { Text, TextProps } from './Themed';
export function MonoText(props: TextProps) {
return <Text {...props} style={[props.style, { fontFamily: 'space-mono' }]} />;
}
/**
* Learn more about Light and Dark modes:
* https://docs.expo.io/guides/color-schemes/
*/
import { Text as DefaultText, View as DefaultView } from 'react-native';
import Colors from '../constants/Colors';
import useColorScheme from '../hooks/useColorScheme';
export function useThemeColor(
props: { light?: string; dark?: string },
colorName: keyof typeof Colors.light & keyof typeof Colors.dark
) {
const theme = useColorScheme();
const colorFromProps = props[theme];
if (colorFromProps) {
return colorFromProps;
} else {
return Colors[theme][colorName];
}
}
type ThemeProps = {
lightColor?: string;
darkColor?: string;
};
export type TextProps = ThemeProps & DefaultText['props'];
export type ViewProps = ThemeProps & DefaultView['props'];
export function Text(props: TextProps) {
const { style, lightColor, darkColor, ...otherProps } = props;
const color = useThemeColor({ light: lightColor, dark: darkColor }, 'text');
return <DefaultText style={[{ color }, style]} {...otherProps} />;
}
export function View(props: ViewProps) {
const { style, lightColor, darkColor, ...otherProps } = props;
const backgroundColor = useThemeColor({ light: lightColor, dark: darkColor }, 'background');
return <DefaultView style={[{ backgroundColor }, style]} {...otherProps} />;
}
import React, { useEffect, useState } from 'react'
import { View, Text, ActivityIndicator } from 'react-native'
import AsyncStorage from '@react-native-async-storage/async-storage'
export const UserProfile = () => {
const [loading, setLoading] = useState(true)
const [username, setUsername] = useState("")
const [modalVisible, setModalVisible] = useState(false)
useEffect(() => {
AsyncStorage.getItem('username').then((username) => {
setUsername(username)
setLoading(false)
})
})
if (loading) {
return <ActivityIndicator />
}
return (
<>
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => {
Alert.alert('Modal has been closed.');
setModalVisible(!modalVisible);
}}>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<Text style={styles.modalText}>Hello World!</Text>
<Pressable
style={[styles.button, styles.buttonClose]}
onPress={() => setModalVisible(!modalVisible)}>
<Text style={styles.textStyle}>Hide Modal</Text>
</Pressable>
</View>
</View>
</Modal>
</>
)
}
\ No newline at end of file
import * as React from 'react';
import renderer from 'react-test-renderer';
import { MonoText } from '../StyledText';
it(`renders correctly`, () => {
const tree = renderer.create(<MonoText>Snapshot test!</MonoText>).toJSON();
expect(tree).toMatchSnapshot();
});
const tintColorLight = '#2f95dc';
const tintColorDark = '#fff';
export default {
light: {
text: '#000',
background: '#fff',
tint: tintColorLight,
tabIconDefault: '#ccc',
tabIconSelected: tintColorLight,
},
dark: {
text: '#fff',
background: '#000',
tint: tintColorDark,
tabIconDefault: '#ccc',
tabIconSelected: tintColorDark,
},
};
import { Dimensions } from 'react-native';
const width = Dimensions.get('window').width;
const height = Dimensions.get('window').height;
export default {
window: {
width,
height,
},
isSmallDevice: width < 375,
};
import { FontAwesome } from '@expo/vector-icons';
import * as Font from 'expo-font';
import * as SplashScreen from 'expo-splash-screen';
import { useEffect, useState } from 'react';
export default function useCachedResources() {
const [isLoadingComplete, setLoadingComplete] = useState(false);
// Load any resources or data that we need prior to rendering the app
useEffect(() => {
async function loadResourcesAndDataAsync() {
try {
SplashScreen.preventAutoHideAsync();
// Load fonts
await Font.loadAsync({
...FontAwesome.font,
'space-mono': require('../assets/fonts/SpaceMono-Regular.ttf'),
});
} catch (e) {
// We might want to provide this error information to an error reporting service
console.warn(e);
} finally {
setLoadingComplete(true);
SplashScreen.hideAsync();
}
}
loadResourcesAndDataAsync();
}, []);
return isLoadingComplete;
}
import { ColorSchemeName, useColorScheme as _useColorScheme } from 'react-native';
// The useColorScheme value is always either light or dark, but the built-in
// type suggests that it can be null. This will not happen in practice, so this
// makes it a bit easier to work with.
export default function useColorScheme(): NonNullable<ColorSchemeName> {
return _useColorScheme() as NonNullable<ColorSchemeName>;
}
/**
* Learn more about deep linking with React Navigation
* https://reactnavigation.org/docs/deep-linking
* https://reactnavigation.org/docs/configuring-links
*/
import { LinkingOptions } from '@react-navigation/native';
import * as Linking from 'expo-linking';
import { RootStackParamList } from '../types';
const linking: LinkingOptions<RootStackParamList> = {
prefixes: [Linking.makeUrl('/')],
config: {
screens: {
Root: {
screens: {
TabOne: {
screens: {
TabOneScreen: 'one',
},
},
TabTwo: {
screens: {
TabTwoScreen: 'two',
},
},
},
},
Modal: 'modal',
NotFound: '*',
},
},
};
export default linking;
/**
* If you are not familiar with React Navigation, refer to the "Fundamentals" guide:
* https://reactnavigation.org/docs/getting-started
*
*/
import { FontAwesome } from '@expo/vector-icons';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { NavigationContainer, DefaultTheme, DarkTheme } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { Center, Toast } from 'native-base';
import * as React from 'react';
import { ColorSchemeName, Pressable, View, Button, Text, Image } from 'react-native';
import { isLoggedIn, login, logout } from '../api/Authentication';
import Colors from '../constants/Colors';
import useColorScheme from '../hooks/useColorScheme';
import { LoginScreen } from '../screens/loginScreen';
import ModalScreen from '../screens/ModalScreen';
import NotFoundScreen from '../screens/NotFoundScreen';
import { SignupScreen } from '../screens/SignupScreen';
import ChatScreen from '../screens/TabOneScreen';
import TabTwoScreen from '../screens/TabTwoScreen';
import { RootStackParamList, RootTabParamList, RootTabScreenProps } from '../types';
import { ERROR_TOAST_PROPS } from '../util/util';
import LinkingConfiguration from './LinkingConfiguration';
import Small_logo from '../assets/images/Logo_small.jpeg'
import { PRIMARY_COLOR } from '../util/styles';
export default function Navigation({ colorScheme }) {
return (
<NavigationContainer
linking={LinkingConfiguration}
theme={colorScheme === 'dark' && false ? DarkTheme : DefaultTheme}>
<RootNavigator />
</NavigationContainer>
);
}
/**
* A root stack navigator is often used for displaying modals on top of all other content.
* https://reactnavigation.org/docs/modal
*/
const Stack = createNativeStackNavigator();
function RootNavigator() {
const [isAuthenticated, setIsAutheticated] = React.useState(false)
// console.log({ isLogged })
React.useEffect(() => {
isLoggedIn().then((res) => { setIsAutheticated(res), console.log({ setIs: res }) })
}, [])
const onLogin = async (username, password) => {
await login(username, password).then(() => setIsAutheticated(true)).catch(e => {
console.log(e)
Toast.show({ title: 'Error logging in! Try again', ...ERROR_TOAST_PROPS })
})
// setTimeout(() => setIsAutheticated(true), 2000)
}
const onLogout = () => {
logout()
setIsAutheticated(false)
}
return (
<Stack.Navigator >
{isAuthenticated ? <Stack.Screen name="Root" options={{ headerShown: false }}>{(props) => <BottomTabNavigator {...props} onLogout={onLogout} />}</Stack.Screen> :
<Stack.Screen name='Root' options={{ headerShown: false }}>{(props) => <LoginScreen {...props} onLogin={onLogin} />}</Stack.Screen>}
<Stack.Screen name='Signup' component={SignupScreen} options={{ headerShown: false, title: 'Sign up' }} />
<Stack.Screen name="NotFound" component={NotFoundScreen} options={{ title: 'Oops!' }} />
<Stack.Group screenOptions={{ presentation: 'modal' }}>
<Stack.Screen name="Modal" component={ModalScreen} />
</Stack.Group>
</Stack.Navigator>
);
}
/**
* A bottom tab navigator displays tab buttons on the bottom of the display to switch screens.
* https://reactnavigation.org/docs/bottom-tab-navigator
*/
const BottomTab = createBottomTabNavigator();
function BottomTabNavigator({ onLogout }) {
const colorScheme = useColorScheme();
return (
<BottomTab.Navigator
initialRouteName="TabOne"
screenOptions={{
// tabBarActiveBackgroundColor: 'lightgray',
tabBarActiveTintColor: PRIMARY_COLOR //Colors[colorScheme].tint,
}}>
<BottomTab.Screen
name="TabTwo"
component={TabTwoScreen}
options={{
title: 'Map',
tabBarIcon: ({ color }) => <TabBarIcon name="map" color={color} />,
}}
/>
<BottomTab.Screen
name="TabOne"
component={ChatScreen}
options={({ navigation }) => ({
title: 'Chat',
headerTitleAlign: 'center',
tabBarIcon: ({ color }) => <TabBarIcon name="comments" color={color} />,
headerLeft: () => (<Image source={Small_logo} style={{ height: 40, width: 70, marginLeft: 20 }} />),
headerRight: () => (
<Pressable
// onPress={() => navigation.navigate('Modal')}
onPress={onLogout}
style={({ pressed }) => ({
opacity: pressed ? 0.5 : 1,
})}>
{/* <Text>Logout</Text> */}
<FontAwesome
name="info-circle"
size={25}
// color={Colors[colorScheme].text}
style={{ marginRight: 15 }}
/>
</Pressable>
),
})}
/>
</BottomTab.Navigator>
);
}
/**
* You can explore the built-in icon families and icons on the web at https://icons.expo.fyi/
*/
function TabBarIcon(props) {
return <FontAwesome size={30} style={{ marginBottom: -3 }} {...props} />;
}
{
"name": "mobileapp",
"version": "1.0.0",
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"web": "expo start --web",
"eject": "expo eject",
"test": "jest --watchAll"
},
"jest": {
"preset": "jest-expo"
},
"dependencies": {
"@expo/vector-icons": "^12.0.0",
"@react-native-async-storage/async-storage": "~1.15.0",
"@react-native-community/slider": "4.1.12",
"@react-navigation/bottom-tabs": "^6.0.5",
"@react-navigation/native": "^6.0.2",
"@react-navigation/native-stack": "^6.1.0",
"axios": "^0.27.2",
"expo": "~44.0.0",
"expo-asset": "~8.4.4",
"expo-av": "~10.2.0",
"expo-constants": "~13.0.0",
"expo-file-system": "~13.1.4",
"expo-font": "~10.0.4",
"expo-linking": "~3.0.0",
"expo-media-library": "~14.0.0",
"expo-speech": "~10.1.0",
"expo-splash-screen": "~0.14.0",
"expo-status-bar": "~1.2.0",
"expo-web-browser": "~10.1.0",
"jwt-decode": "^3.1.2",
"native-base": "^3.4.11",
"react": "17.0.1",
"react-dom": "17.0.1",
"react-native": "0.64.3",
"react-native-safe-area-context": "3.3.2",
"react-native-screens": "~3.10.1",
"react-native-svg": "12.1.1",
"react-native-web": "0.17.1"
},
"devDependencies": {
"@babel/core": "^7.12.9",
"@types/react": "~17.0.21",
"@types/react-native": "~0.64.12",
"jest": "^26.6.3",
"jest-expo": "~44.0.1",
"react-test-renderer": "17.0.1",
"typescript": "~4.3.5"
},
"private": true
}
import { StatusBar } from 'expo-status-bar';
import { Platform, StyleSheet } from 'react-native';
import EditScreenInfo from '../components/EditScreenInfo';
import { Text, View } from '../components/Themed';
export default function ModalScreen() {
return (
<View style={styles.container}>
<Text style={styles.title}>Modal</Text>
<View style={styles.separator} lightColor="#eee" darkColor="rgba(255,255,255,0.1)" />
<EditScreenInfo path="/screens/ModalScreen.tsx" />
{/* Use a light status bar on iOS to account for the black space above the modal */}
<StatusBar style={Platform.OS === 'ios' ? 'light' : 'auto'} />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
title: {
fontSize: 20,
fontWeight: 'bold',
},
separator: {
marginVertical: 30,
height: 1,
width: '80%',
},
});
import { StyleSheet, TouchableOpacity } from 'react-native';
import { Text, View } from '../components/Themed';
import { RootStackScreenProps } from '../types';
export default function NotFoundScreen({ navigation }: RootStackScreenProps<'NotFound'>) {
return (
<View style={styles.container}>
<Text style={styles.title}>This screen doesn't exist.</Text>
<TouchableOpacity onPress={() => navigation.replace('Root')} style={styles.link}>
<Text style={styles.linkText}>Go to home screen!</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
padding: 20,
},
title: {
fontSize: 20,
fontWeight: 'bold',
},
link: {
marginTop: 15,
paddingVertical: 15,
},
linkText: {
fontSize: 14,
color: '#2e78b7',
},
});
import React from "react";
import { View, Button, Text } from 'react-native'
import { styles } from "../util/styles";
export const SignupScreen = ({ navigation }) => {
return (
<View style={styles.container}><Text style={{
padding: 10,
textAlign: 'center',
// fontWeight: 'bold',
fontSize: 40
}}>Sign up</Text>
<View style={{ flexDirection: 'row', padding: 10, justifyContent: 'center' }}>
<Text style={{ textAlign: 'center' }}>Already have an account? </Text>
<Text style={{ fontWeight: 'bold', textAlign: 'center', }} onPress={() => navigation.replace('Root')}>Login</Text>
</View>
<SignupForm />
</View>
)
}
const SignupForm = () => {
return(
<View>
</View>
)
}
\ No newline at end of file
import React, { useEffect, useState } from 'react'
import { FlatList, StyleSheet, TextInput, SectionList, Button, ActivityIndicator, View, Text } from 'react-native';
import { AudioRecorder } from '../components/AudioRecorder';
import _ from 'lodash'
import EditScreenInfo from '../components/EditScreenInfo';
// import { Text, View } from '../components/Themed';
import { RootTabScreenProps } from '../types';
import { create, getList, getOne } from '../api/api';
import { BACKEND_ADDRESS } from '../api/constants';
import Ionicons from '@expo/vector-icons/Ionicons';
import { CONVO_DEFAULT_ICON_COLOR, styles } from '../util/styles';
import { StatusBar } from 'expo-status-bar';
import Slider from '@react-native-community/slider';
import { PlayMessage } from '../components/PlayMessage';
import { Toast } from 'native-base';
import { ERROR_TOAST_PROPS } from '../util/util';
import AsyncStorage from '@react-native-async-storage/async-storage';
export default function ChatScreen({ navigation }) {
const currentTime = new Date()
const defaultChatData = [{ id: 1, from_user: 2, to_user: 1, message: 'How many passengers?', timestamp: currentTime.setMinutes(currentTime.getMinutes() - 1).valueOf() },
{ id: 2, from_user: 1, to_user: 2, message: 'Three', timestamp: currentTime.setMinutes(currentTime.getMinutes() - 2).valueOf(), is_detected: true },
{ id: 3, from_user: 2, to_user: 1, message: 'Should i turn left or right here?', timestamp: currentTime.setMinutes(currentTime.getMinutes() - 3).valueOf(), is_detected: false },
{ id: 4, from_user: 1, to_user: 2, message: 'Left', timestamp: currentTime.setMinutes(currentTime.getMinutes() - 4).valueOf(), is_detected: true },
{ id: 5, from_user: 1, to_user: 2, message: 'Please hurry', timestamp: currentTime.setMinutes(currentTime.getMinutes() - 5).valueOf() },
{ id: 6, from_user: 2, to_user: 1, message: 'Ok', timestamp: currentTime.setMinutes(currentTime.getMinutes() - 6).valueOf() },
// { from_user: 1, to_user: 2, message: 'msg1', timestamp: currentTime.setDate(currentTime.getDate() - 1).valueOf() },
// { from_user: 1, to_user: 2, message: 'msg2', timestamp: currentTime.setDate(currentTime.getDate() - 2).valueOf() },
// { from_user: 2, to_user: 1, message: 'msg3', timestamp: currentTime.setDate(currentTime.getDate() - 3).valueOf() },
// { from_user: 1, to_user: 2, message: 'msg4', timestamp: currentTime.setDate(currentTime.getDate() - 4).valueOf() },
// { from_user: 2, to_user: 1, message: 'msg5', timestamp: currentTime.setDate(currentTime.getDate() - 5).valueOf() },
]
const [detectedText, setDetectedText] = useState("")
const [playinId, setPlayingId] = useState(3)
const [chatDetails, setChatDetails] = useState()
const [chats, setChats] = useState([])
const [input, setInput] = useState('test')
const [loading, setLoading] = useState(true)
const loadSampleChats = () => {
const chats_ = defaultChatData//res.results
const sections = [...new Set(chats_.map(chat => new Date(chat.timestamp).setHours(0, 0, 0, 0)))];
const sectionChats = sections.map(section => {
console.log({ section })
return ({
title: section, data: chats_.filter(chat => {
console.log({ chat })
return (new Date(chat.timestamp).setHours(0, 0, 0, 0).valueOf() == section)
}).sort((a, b) => { return (a.timestamp - b.timestamp) })
})
})
console.log({ chats_, sections, sectionChats })
setChats(sectionChats)
console.log({ chats })
}
useEffect(() => { if (chatDetails) { loadChats(); setLoading(false) } }, [chatDetails])
// const ws = new WebSocket(`ws://${BACKEND_ADDRESS}/chatSocket/`)
useEffect(() => {
loadChatDetails()
// startWebsocket()
// loadSampleChats()
}, [])
// const startWebsocket = () => {
// ws.onopen = () => {
// // on connecting, do nothing but log it to the console
// console.log('connected')
// }
// ws.onmessage = evt => {
// // listen to data sent from the websocket server
// const message = JSON.parse(evt.data)
// // setState({ dataFromServer: message })
// console.log(message)
// }
// ws.onclose = () => {
// console.log('disconnected')
// // automatically try to reconnect on connection loss
// }
// }
const loadChatDetails = async () => {
await getOne('conversations', 1).then(res => {
return res.json()
}).then(res => {
console.log(res)
AsyncStorage.getItem('user_id').then((user_id) => {
console.log('chat details', user_id)
//change from user and to user depending on the current user
if (res.from_user == user_id) {
setChatDetails(res)
}
else {
const n_res = { ...res, from_user: res.to_user, to_user: res.from_user }
setChatDetails(n_res)
}
})
})
}
const loadChats = async () => {
await getList('chats').then(res => {
return res.json()
}).then(res => {
console.log("load chats")
const chats = res.results || []
const sections = [...new Set(chats.map(chat => new Date(chat.timestamp).setHours(0, 0, 0, 0)))];
const sectionChats = sections.map(section => ({ title: section, data: chats.filter(chat => new Date(chat.timestamp).setHours(0, 0, 0, 0) == section) }))
setChats(sectionChats)
})
setLoading(false)
}
const onSendPress = () => {
try {
create('chats', { message: input, from_user: chatDetails.from_user, to_user: chatDetails.to_user, conversation: chatDetails.id }).then(response => {
// console.log(response)
})
setLoading(true)
setInput('')
loadChats()
}
catch (e) {
Toast.show({ title: 'Error sending message. try again!', ...ERROR_TOAST_PROPS })
}
}
return (
<View style={styles.container}>
{/* <Text style={styles.title}>Tab One</Text>
<View style={{height: 70, width: 100, backgroundColor: ''}}><TextInput style={{borderColor: 'white', borderWidth: 1, alignSelf: }} onChange={() => console.log('change')}></TextInput></View>
<View style={styles.separator} lightColor="#000" darkColor="rgba(255,0,255,0.1)" />
<EditScreenInfo path="/screens/TabOneScreen.tsx" /> */}
<View style={{ flex: 1, width: '100%' }}>
<View style={{ display: 'flex', flex: 0.9, justifyContent: 'space-between' }}>
<StatusBar />
{loading ? <ActivityIndicator /> :
<SectionList
refreshing={loading}
onRefresh={() => {
// loadChatDetails() //remove
loadChats()
}}
inverted
sections={chats}
keyExtractor={(item, index) => item + index}
renderItem={({ item }) => {
// console.log({ item })
const timeString = new Date(item.timestamp).toLocaleTimeString()
const time = timeString.slice(-11, -6) + " " + timeString.slice(-2)
return (
<View style={{ margin: 5, padding: 5 }}><Text
style={[{ textAlign: chatDetails.from_user == item.from_user ? 'right' : 'left', backgroundColor: chatDetails.from_user == item.from_user ? 'lightgray' : '#FFDE03', borderRadius: 5, padding: 5 },
chatDetails.from_user == item.from_user ? { marginLeft: 'auto' } : { marginRight: 'auto' }
]}
key={item.timestamp}>{item.message}</Text>
<View style={{ flex: 1, flexDirection: chatDetails.from_user == item.from_user ? 'row-reverse' : 'row', textAlign: chatDetails.from_user == item.from_user ? 'right' : 'left' }}>
<Text style={{ textAlign: chatDetails.from_user == item.from_user ? 'right' : 'left', color: 'gray', fontSize: 11 }}>{time}</Text>
{item.is_detected && <Ionicons name="mic" size={15} color={CONVO_DEFAULT_ICON_COLOR} />}
{/* {chatDetails.to_user == item.from_user && item.id != playinId && <Ionicons name="play" size={15} style={styles.chatIcon} />}
{chatDetails.to_user == item.from_user && item.id == playinId && <Ionicons name="pause" size={15} style={styles.chatIcon} />} */}
{chatDetails.to_user == item.from_user && <PlayMessage message={item.message} />}
</View>
{/* {item.id == playinId ?
<Slider
style={{ width: 200, height: 40, FborderRadius: 5, padding: 0, margin: 0 }}
minimumValue={0}
maximumValue={1}
value={0.67}
minimumTrackTintColor="black"
maximumTrackTintColor="grey"
/> : null
} */}
</View>
)
}}
invertStickyHeaders
renderSectionFooter={({ section: { title } }) => {
var date = ""
if (new Date(title).toLocaleDateString() == new Date().toLocaleDateString()) {
date = "Today"
}
// else if (new Date(title).toLocaleDateString() == new Date().setDate(new Date().getDate() - 1).toLocaleDateString()){
// date = "Yesterday"
// }
else {
date = new Date(title).toLocaleDateString()
}
return (
<Text style={styles.header}>{date}</Text>
)
}}
/>
}
{/* <FlatList
inverted={true}
style={{ alignContent: 'flex-end' }}
data={chats}
keyExtractor={(item) => item.currentTime}
renderItem={({ item }) => {
console.log({ item })
return (
<View style={{ margin: 5, padding: 5 }}><Text
style={[{ textAlign: chatDetails.from == item.from ? 'right' : 'left', backgroundColor: 'blue', borderRadius: 5, padding: 5 },
chatDetails.from == item.from ? { marginLeft: 'auto' } : { marginRight: 'auto' }
]}
key={item.time}>{item.message}</Text>
<Text style={{ textAlign: chatDetails.from == item.from ? 'right' : 'left', color: 'gray' }}>{new Date(item.time).toLocaleTimeString().slice(0, 5)}</Text></View>
)
}} /> */}
</View>
<View style={{ flex: 0.075, padding: 0, backgroundColor: 'white' }}>
<View style={{ flexDirection: 'row', display: 'flex', height: '100%' }}>
<View style={{ flex: 0.8, height: '100%', flexDirection: 'column-reverse' }}>
<TextInput
style={{ borderWidth: 2, borderColor: 'gray', color: 'black', marginHorizontal: 5, paddingHorizontal: 10, borderRadius: 5 }}
defaultValue={input}
onChange={(e) => setInput(e.target.value)}></TextInput>
</View>
{input ?
<View style={{ flex: 0.2, height: '100%', flexDirection: 'column-reverse' }}>
<Button style={{ width: '100%', height: '100%' }} title='Send' onPress={onSendPress} />
</View>
:
<View style={{ flex: 0.2, height: '100%', flexDirection: 'column-reverse' }}><AudioRecorder setDetectedText={setInput} /></View>
}
</View>
</View>
</View>
</View>
);
}
import { StatusBar } from 'expo-status-bar';
import { StyleSheet } from 'react-native';
import EditScreenInfo from '../components/EditScreenInfo';
import { Text, View } from '../components/Themed';
export default function TabTwoScreen() {
return (
<View style={styles.container}>
<StatusBar />
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
title: {
fontSize: 20,
fontWeight: 'bold',
},
separator: {
marginVertical: 30,
height: 1,
width: '80%',
},
});
import React, { useState } from 'react'
import { StyleSheet, TextInput, Button, Image, Dimensions, View, Text, ActivityIndicator } from 'react-native';
import EditScreenInfo from '../components/EditScreenInfo';
// import { Text, View } from '../components/Themed';
import { TouchableOpacity } from 'react-native';
import { ScrollView, Toast } from 'native-base';
import { ERROR_TOAST_PROPS } from '../util/util';
import { screenWidth, styles } from '../util/styles';
import TTS_logo from '../assets/images/TTS_logo.jpeg'
export const LoginScreen = ({ onLogin, navigation }) => {
return (
<ScrollView style={styles.loginScreenContainer}>
<View style={{ alignContent: 'center', justifyContent: 'center' }}>
<Image source={TTS_logo} style={{ height: screenWidth - 30, width: screenWidth - 30, margin: 'auto' }} />
</View>
<Text style={{
padding: 10,
textAlign: 'center',
// fontWeight: 'bold',
fontSize: 40
}}>Login</Text>
<View style={{ flexDirection: 'row', padding: 10, justifyContent: 'center' }}>
<Text style={{ textAlign: 'center' }}>Don't have an account? </Text>
<Text style={{ fontWeight: 'bold', textAlign: 'center', }} onPress={() => navigation.replace('Signup')}>Sign up</Text>
</View>
<View style={styles.formContainer}>
<LoginForm onLogin={onLogin} />
</View>
</ScrollView>
);
}
const LoginForm = ({ onLogin, navigation }) => {
var passwordInput
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [loading, setLoading] = useState(false)
const onSubmit = () => {
console.log({ username, password })
setLoading(true)
if (!username || !password) {
Toast.show({ title: 'Please fill in all the fields!', ...ERROR_TOAST_PROPS })
} else {
onLogin(username, password)
}
setLoading(false)
}
return (
<View >
<TextInput style={styles.input}
defaultValue={username}
onChangeText={(e) => {
console.log(e);
setUsername(e)
}}
autoCapitalize="none"
onSubmitEditing={() => passwordInput.focus()}
autoCorrect={false}
keyboardType='email-address'
returnKeyType="next"
placeholder='Email'
// placeholderTextColor='rgba(225,225,225,0.7)'
/>
<TextInput style={styles.input}
defaultValue={password}
onChangeText={(e) => setPassword(e)}
returnKeyType="go"
autoCapitalize="none"
ref={(input) => passwordInput = input}
placeholder='Password'
onSubmitEditing={onSubmit}
// placeholderTextColor='rgba(225,225,225,0.7)'
secureTextEntry />
<TouchableOpacity style={styles.buttonContainer}
// onPress={onButtonPress}
// disabled={!username || !password}
onPress={onSubmit}
disabled={loading}
>{loading ? <ActivityIndicator /> : <Text style={styles.buttonText}>LOGIN</Text>}
</TouchableOpacity>
</View>
// define your styles
)
}
{
"extends": "expo/tsconfig.base",
"compilerOptions": {
"strict": true
}
}
/**
* Learn more about using TypeScript with React Navigation:
* https://reactnavigation.org/docs/typescript/
*/
import { BottomTabScreenProps } from '@react-navigation/bottom-tabs';
import { CompositeScreenProps, NavigatorScreenParams } from '@react-navigation/native';
import { NativeStackScreenProps } from '@react-navigation/native-stack';
declare global {
namespace ReactNavigation {
interface RootParamList extends RootStackParamList {}
}
}
export type RootStackParamList = {
Root: NavigatorScreenParams<RootTabParamList> | undefined;
Modal: undefined;
Login: undefined;
NotFound: undefined;
};
export type RootStackScreenProps<Screen extends keyof RootStackParamList> = NativeStackScreenProps<
RootStackParamList,
Screen
>;
export type RootTabParamList = {
TabOne: undefined;
TabTwo: undefined;
};
export type RootTabScreenProps<Screen extends keyof RootTabParamList> = CompositeScreenProps<
BottomTabScreenProps<RootTabParamList, Screen>,
NativeStackScreenProps<RootStackParamList>
>;
import { StyleSheet, Dimensions } from "react-native"
export const screenWidth = Dimensions.get('window').width
export const screenHeight = Dimensions.get('window').height
export const PRIMARY_COLOR = '#2f95dc'
export const COLOR1 = '#fff'//'#2c3e50'
export const CONVO_DEFAULT_ICON_COLOR = '#000'
export const CONVO_STOP_ICON_COLOR = '#f00'
export const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: COLOR1,
},
loginContainer: {
alignItems: 'center',
flexGrow: 1,
justifyContent: 'center',
backgroundColor: 'blue'
},
logo: {
position: 'absolute',
width: 300,
height: 100
},
loginScreenContainer: {
padding: 20,
backgroundColor: 'white',
flex: 1,
},
formContainer: {
// backgroundColor: 'green'
},
input: {
height: 40,
backgroundColor: 'rgba(225,225,225,0.2)',
marginBottom: 10,
padding: 10,
// color: '#fff',
borderRadius: 5,
},
buttonContainer: {
backgroundColor: '#2980b6',
paddingVertical: 15,
borderRadius: 5
},
buttonText: {
// color: '#fff',
textAlign: 'center',
fontWeight: '700'
},
chatIcon: {
paddingHorizontal: 4
},
// container: {
// flex: 1,
// alignItems: 'center',
// justifyContent: 'center',
// },
title: {
fontSize: 20,
fontWeight: 'bold',
},
separator: {
marginVertical: 30,
height: 1,
width: '80%',
},
convoFooter: {
},
header: { textAlign: 'center', backgroundColor: 'gray', marginRight: 'auto', marginLeft: 'auto', padding: 3, borderRadius: 5 }
})
\ No newline at end of file
export const TOAST_PROPS = {placement : 'top'}
export const ERROR_TOAST_PROPS = {...TOAST_PROPS, style:{backgroundColor: '#B00020'}}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
Main objective:- Is to ensure that the passengers who are using public staff transport (Bus) are safe with covid and they are given the service according the government health regulations. Main objective:- Is to ensure that the passengers who are using public staff transport (Bus) are safe with covid and they are given the service according the government health regulations.
Main Research questions: How to deliver a safe public transport during the pandemic? Main Research questions: How to deliver a safe public transport during the pandemic?
How to Ensure Passenger's health is safe? How to Ensure Passenger's health is safe?
How to build trust and motivate passengers to use Public Transport? How to build trust and motivate passengers to use Public Transport?
Individual research question Individual research question
IT18145380 - How to select the perfect seat based on passenger attributes? IT18145380 - How to select the perfect seat based on passenger attributes?
IT19012384 - How to manage real time tracking with the real time data? IT19012384 - How to manage real time tracking with the real time data?
How to do the payments through QR code with the public transportation? How to do the payments through QR code with the public transportation?
IT18094664 - Interfaces to perform in-vehicle tasks while driving? IT18094664 - Interfaces to perform in-vehicle tasks while driving?
voice or manual interfaces? voice or manual interfaces?
IT19153728 - How to confirm the arrival of the relevant passenger and calculate the monthly fare based on the arrival of the passenger? IT19153728 - How to confirm the arrival of the relevant passenger and calculate the monthly fare based on the arrival of the passenger?
Individual Objectives, Individual Objectives,
IT18145380 - Provide a comfortable ride for the passenger IT18145380 - Provide a comfortable ride for the passenger
IT19012384 - To be able to use the time effectively with the help of route tracking. IT19012384 - To be able to use the time effectively with the help of route tracking.
To decrease the use of paper and cash usage by using QR payment method. To decrease the use of paper and cash usage by using QR payment method.
To facilitate daily activities in transportation. To facilitate daily activities in transportation.
IT18094664 - The main objective of this proposed research is to develop an application for the prevention of driver-related accidents and to make driver and passenger communication more efficient and convenient. IT18094664 - The main objective of this proposed research is to develop an application for the prevention of driver-related accidents and to make driver and passenger communication more efficient and convenient.
IT19153728 - The main objective of this research is marking the passenger's arrival and identify the passenger. IT19153728 - The main objective of this research is marking the passenger's arrival and identify the passenger.
backend/data/
*.pyc
\ No newline at end of file
"""
ASGI config for backend project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/4.0/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
# os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings')
# application = get_asgi_application()
from channels.routing import ProtocolTypeRouter, URLRouter # noqa isort:skip
from .routing import websocket_urlpatterns# noqa isort:skip
application = ProtocolTypeRouter(
{
"http": get_asgi_application(),
"websocket": URLRouter(websocket_urlpatterns),
}
)
from django.contrib import admin
# Register your models here.
from django.apps import AppConfig
class CmsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'backend.cms'
# Generated by Django 4.0.4 on 2022-04-25 19:51
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='MlModel',
fields=[
('id', models.AutoField(primary_key=True, serialize=False)),
('description', models.TextField(blank=True)),
('timestamp', models.DateTimeField(auto_now=True)),
('details', models.JSONField()),
],
),
]
# Generated by Django 4.1 on 2022-08-10 13:05
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('cms', '0001_initial'),
]
operations = [
migrations.CreateModel(
name='Conversation',
fields=[
('id', models.AutoField(primary_key=True, serialize=False)),
('timestamp', models.DateTimeField(auto_now=True)),
('from_user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='from_chat', to=settings.AUTH_USER_MODEL)),
('to_user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='to_chat', to=settings.AUTH_USER_MODEL)),
],
),
migrations.CreateModel(
name='Chat',
fields=[
('id', models.AutoField(primary_key=True, serialize=False)),
('message', models.TextField()),
('timestamp', models.DateTimeField(auto_now=True)),
('conversation', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='cms.conversation')),
('from_user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='from_convo', to=settings.AUTH_USER_MODEL)),
('to_user', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='to_convo', to=settings.AUTH_USER_MODEL)),
],
),
]
# Generated by Django 4.1 on 2022-08-18 03:33
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('cms', '0002_conversation_chat'),
]
operations = [
migrations.AddField(
model_name='chat',
name='is_detected',
field=models.BooleanField(default=False),
),
]
import pickle
from keras.models import load_model
import numpy as np
import IPython.display as ipd
import random
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
def predict(samples):
#load the trained model
model=load_model(r'./best_model_final.hdf5')
#load labels
f1 = open('all_label.txt', 'rb')
all_label = pickle.load(f1)
print('loaded labels')
#preprocess recorded audio
le = LabelEncoder()
y = le.fit_transform(all_label)
classes = list(le.classes_)
def predictSamples(audio):
prob=model.predict(audio.reshape(1,8000,1))
index=np.argmax(prob[0])
return classes[index]
ipd.Audio(samples, rate=8000)
#run the prediction
result = predictSamples(samples)
print("Text:",result)
return result
\ No newline at end of file
import pickle
from matplotlib import pyplot
import os
import librosa
import IPython.display as ipd
import matplotlib.pyplot as plt
import numpy as np
from scipy.io import wavfile
import warnings
from sklearn.preprocessing import LabelEncoder
from keras.utils import np_utils
from sklearn.model_selection import train_test_split
from keras.layers import Dense, Dropout, Flatten, Conv1D, Input, MaxPooling1D
from keras.models import Model
from keras.callbacks import EarlyStopping, ModelCheckpoint
from keras import backend as K
K.clear_session()
warnings.filterwarnings("ignore")
# os.listdir('../../../data/')
# list of words to detect
classes = ['down', 'go', 'left', 'no', 'off',
'on', 'right', 'stop', 'up', 'yes']
def train():
#data preprocessing
train_audio_path = r'./backend/data/train/train/audio/'
samples, sample_rate = librosa.load(
train_audio_path+'yes/0a7c2a8d_nohash_0.wav', sr=16000)
# fig = plt.figure(figsize=(14, 8))
# ax1 = fig.add_subplot(211)
# ax1.set_title('Raw wave of ' + r'../input/train/audio/yes/0a7c2a8d_nohash_0.wav')
# ax1.set_xlabel('time')
# ax1.set_ylabel('Amplitude')
# ax1.plot(np.linspace(0, sample_rate/len(samples), sample_rate), samples)
ipd.Audio(samples, rate=sample_rate)
print(sample_rate)
samples = librosa.resample(samples, sample_rate, 8000)
ipd.Audio(samples, rate=8000)
labels = os.listdir(train_audio_path)
no_of_recordings = []
for label in labels:
waves = [f for f in os.listdir(
train_audio_path + '/' + label) if f.endswith('.wav')]
no_of_recordings.append(len(waves))
index = np.arange(len(labels))
labels = ["yes", "no", "up", "down", "left",
"right", "on", "off", "stop", "go"]
duration_of_recordings = []
for label in labels:
print('2.1', label)
waves = [f for f in os.listdir(
train_audio_path + '/' + label) if f.endswith('.wav')]
for wav in waves:
sample_rate, samples = wavfile.read(
train_audio_path + '/' + label + '/' + wav)
duration_of_recordings.append(float(len(samples)/sample_rate))
plt.hist(np.array(duration_of_recordings))
train_audio_path = r'./backend/data/train/train/audio/'
all_wave = []
all_label = []
#If labels are already generated load them
f1 = open('all_label.txt', 'rb')
all_label = pickle.load(f1)
f2 = open('all_waves_file.txt', 'rb')
all_wave = pickle.load(f2)
if(all_wave and all_label):
print('loaded labels and waves')
else:
print('Creating labels and waves files')
for label in labels:
print(label)
waves = [f for f in os.listdir(
train_audio_path + '/' + label) if f.endswith('.wav')]
for wav in waves:
samples, sample_rate = librosa.load(
train_audio_path + '/' + label + '/' + wav, sr=16000)
samples = librosa.resample(samples, sample_rate, 8000)
if(len(samples) == 8000):
all_wave.append(samples)
all_label.append(label)
all_labels_file = open('all_label.txt', 'wb+')
pickle.dump(file=all_labels_file, obj=all_label)
all_labels_file.close()
all_waves_file = open('all_waves_file.txt', 'wb+')
pickle.dump(file=all_waves_file, obj=all_wave)
all_waves_file.close()
print('Done: creating labels and waves files')
le = LabelEncoder()
y = le.fit_transform(all_label)
classes = list(le.classes_)
y = np_utils.to_categorical(y, num_classes=len(labels))
all_wave = np.array(all_wave).reshape(-1, 8000, 1)
x_tr, x_val, y_tr, y_val = train_test_split(np.array(all_wave), np.array(
y), stratify=y, test_size=0.2, random_state=777, shuffle=True)
train_data_file = open('train_data_file.txt', 'wb+')
np.save(file=train_data_file, arr=np.array([x_tr, x_val, y_tr, y_val]))
train_data_file.close()
inputs = Input(shape=(8000, 1))
# First Conv1D layer
conv = Conv1D(8, 13, padding='valid', activation='relu', strides=1)(inputs)
conv = MaxPooling1D(3)(conv)
conv = Dropout(0.3)(conv)
# Second Conv1D layer
conv = Conv1D(16, 11, padding='valid', activation='relu', strides=1)(conv)
conv = MaxPooling1D(3)(conv)
conv = Dropout(0.3)(conv)
# Third Conv1D layer
conv = Conv1D(32, 9, padding='valid', activation='relu', strides=1)(conv)
conv = MaxPooling1D(3)(conv)
conv = Dropout(0.3)(conv)
# Fourth Conv1D layer
conv = Conv1D(64, 7, padding='valid', activation='relu', strides=1)(conv)
conv = MaxPooling1D(3)(conv)
conv = Dropout(0.3)(conv)
# Flatten layer
conv = Flatten()(conv)
# Dense Layer 1
conv = Dense(256, activation='relu')(conv)
conv = Dropout(0.3)(conv)
# Dense Layer 2
conv = Dense(128, activation='relu')(conv)
conv = Dropout(0.3)(conv)
outputs = Dense(len(labels), activation='softmax')(conv)
# initializing the model
model = Model(inputs, outputs)
model.summary()
model.compile(loss='categorical_crossentropy',
optimizer='adam', metrics=['accuracy'])
es = EarlyStopping(monitor='val_loss', mode='min',
verbose=1, patience=10, min_delta=0.0001)
mc = ModelCheckpoint('best_model.hdf5', monitor='val_accuracy',
verbose=1, save_best_only=True, mode='max')
#training the model
history = model.fit(x_tr, y_tr, epochs=100, callbacks=[
es, mc], batch_size=32, validation_data=(x_val, y_val))
# code to plot the graphs
# pyplot.plot(history.history['loss'], label='train')
# pyplot.plot(history.history['val_loss'], label='test')
# pyplot.legend()
# pyplot.show()
return history
from argparse import ONE_OR_MORE
from operator import truediv
from sqlite3 import Timestamp
from django.db import models
from django.contrib.auth.models import User
# Create your models here.
class MlModel(models.Model):
id = models.AutoField(primary_key=True)
description = models.TextField(blank=True)
timestamp = models.DateTimeField(blank=True, auto_now=True)
details = models.JSONField()
class Conversation(models.Model):
id = models.AutoField(primary_key=True)
from_user = models.ForeignKey(
User, related_name='from_chat', on_delete=models.PROTECT)
to_user = models.ForeignKey(
User, related_name='to_chat', on_delete=models.PROTECT)
timestamp = models.DateTimeField(auto_now=True)
class Chat(models.Model):
id = models.AutoField(primary_key=True)
conversation = models.ForeignKey(Conversation, on_delete=models.PROTECT)
from_user = models.ForeignKey(
User, related_name='from_convo', on_delete=models.PROTECT)
to_user = models.ForeignKey(
User, related_name='to_convo', on_delete=models.PROTECT)
message = models.TextField()
timestamp = models.DateTimeField(auto_now=True)
is_detected = models.BooleanField(default=False)
from django.contrib.auth.models import User, Group
from .models import Chat, Conversation, MlModel
from rest_framework import serializers
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from django.forms.models import model_to_dict
class MyTokenObtainPairSerializer(TokenObtainPairSerializer):
@classmethod
def get_token(cls, user):
token = super(MyTokenObtainPairSerializer, cls).get_token(user)
# Add custom claims
return token
def validate(self, attrs):
data = super().validate(attrs)
refresh = self.get_token(self.user)
data['refresh'] = str(refresh)
data['access'] = str(refresh.access_token)
# Add extra responses here
user = self.user
print(user.id)
user_obj = User.objects.filter(id=user.id).values('username', 'email', 'id').first()
print(user_obj)
data['user'] = user_obj
return data
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ['url', 'username', 'email', 'groups']
class GroupSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Group
fields = ['url', 'name']
class MlModelSerializer(serializers.ModelSerializer):
class Meta:
model = MlModel
fields = (
'__all__'
)
class ChatSerializer(serializers.ModelSerializer):
class Meta:
model = Chat
fields = (
'__all__'
)
class ConversationSerializer(serializers.ModelSerializer):
class Meta:
model = Conversation
fields = (
'__all__'
)
\ No newline at end of file
from django.test import TestCase
# Create your tests here.
from django.contrib.auth.models import User, Group
from rest_framework import viewsets
from rest_framework import permissions
from backend.cms.serializers import MyTokenObtainPairSerializer
from backend.cms.serializers import MlModelSerializer, ChatSerializer, ConversationSerializer
from backend.cms.serializers import UserSerializer, GroupSerializer
from rest_framework.decorators import action
from rest_framework.response import Response
import os
from rest_framework.parsers import MultiPartParser
from datetime import datetime, timedelta
import librosa
from django.db.models import Q
from django.core.files.storage import FileSystemStorage
from .models import Chat, Conversation, MlModel
from rest_framework_simplejwt.views import TokenObtainPairView
from .model.train import train
from .model.predict import predict
from pydub import AudioSegment
import numpy as np
#Custom Viewset to get auth token
class ObtainTokenPairWithUserView(TokenObtainPairView):
permission_classes = (permissions.AllowAny,)
serializer_class = MyTokenObtainPairSerializer
class UserViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = User.objects.all().order_by('-date_joined')
serializer_class = UserSerializer
permission_classes = [permissions.IsAuthenticated]
@action(detail=False)
def runFunction(*args, **kwargs):
print('Function ran')
results = {} # train() CHANGE HERE
print(results)
return Response({'success': True})
class GroupViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows groups to be viewed or edited.
"""
queryset = Group.objects.all()
serializer_class = GroupSerializer
permission_classes = [permissions.IsAuthenticated]
class MlModelViewSet(viewsets.ViewSet):
queryset = MlModel.objects.all()
serializer_class = MlModelSerializer
permission_classes = [permissions.AllowAny]
parser_classes = [MultiPartParser]
#Custom api to add sample chats
@action(detail=False)
def addChats(*args, **kwargs):
admin = User.objects.get(username='admin')
user2 = User.objects.get(username='user2')
convo = Conversation(from_user=admin, to_user=user2)
convo.save()
now = datetime.now()
chats = [{'from': 1, 'to': 2, 'message': 'msg1', 'time': now},
{'from': 1, 'to': 2, 'message': 'msg2',
'time': now + timedelta(minutes=1)},
{'from': 2, 'to': 1, 'message': 'msg3',
'time': now + timedelta(minutes=2)},
{'from': 1, 'to': 2, 'message': 'msg4',
'time': now + timedelta(minutes=3)},
{'from': 2, 'to': 1, 'message': 'msg5',
'time': now + timedelta(minutes=4)},
{'from': 1, 'to': 2, 'message': 'msg11', 'time': now},
{'from': 1, 'to': 2, 'message': 'msg22',
'time': now + timedelta(days=1)},
{'from': 2, 'to': 1, 'message': 'msg33',
'time': now + timedelta(days=2)},
{'from': 1, 'to': 2, 'message': 'msg44',
'time': now + timedelta(days=3)},
{'from': 2, 'to': 1, 'message': 'msg55',
'time': now + timedelta(days=4)},
]
for chat in chats:
object = Chat(
conversation=convo, from_user_id=chat['from'], to_user_id=chat['to'], messsage=chat['message'])
object.save()
#Custom api to train the model
@action(detail=False)
def train(*args, **kwargs):
print('Function ran')
results = train()
print(results)
return Response({'success': True})
#Custom api to convert audio to text
@action(detail=False, methods=["POST"])
def detect(self, request, *args, **kwargs):
print('Function ran')
print(request.headers)
bytesio_object = list(request.data.dict().values())[0].file
print(bytesio_object)
with open("output.m4a", "wb") as f:
f.write(bytesio_object.getbuffer())
path = os.path.abspath("output.m4a")
print(path)
# convert wav to mp3
audSeg = AudioSegment.from_file("output.m4a")
audSeg.export('output.wav', format="wav")
samples, sample_rate = librosa.load(
'output.wav', sr=16000)
samples = librosa.resample(samples, sample_rate, 8000)
print('---------------------------------------------------------')
if(samples.shape[0] > 8000):
print('grater -------------------------------------')
samples = samples[-8000:]
print(samples.shape)
else:
len = 8000 - samples.shape[0]
new_arr = np.zeros(len, )
samples = np.concatenate((samples, new_arr))
print(samples.shape)
results = predict(samples)
print(results)
return Response({'success': True, 'result': results})
class ChatViewSet(viewsets.ModelViewSet):
queryset = Chat.objects.all().order_by('-timestamp')
serializer_class = ChatSerializer
permission_classes = [permissions.IsAuthenticated]
#ovveride defualt list action to get chats of specific user conversation
def list(self, request, pk=None):
if pk == None:
chats = Chat.objects \
.filter(conversation_id=1) \
.filter(Q(from_user_id=request.user.id) | Q(
to_user_id=request.user.id))
else:
chats = Chat.objects.get(id=pk)
page = self.paginate_queryset(chats)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(page, many=True)
result_set = serializer.data
return Response(result_set)
def get_result_set(self, chats):
result_set = ChatSerializer(chats, many=True).data
return result_set
class ConversationViewSet(viewsets.ModelViewSet):
queryset = Conversation.objects.all().order_by('id')
serializer_class = ConversationSerializer
permission_classes = [permissions.IsAuthenticated]
from channels.generic.websocket import JsonWebsocketConsumer
class ChatConsumer(JsonWebsocketConsumer):
"""
This consumer is used to show user's online status,
and send notifications.
"""
def __init__(self, *args, **kwargs):
super().__init__(args, kwargs)
self.room_name = None
def connect(self):
print("Connected!")
self.room_name = "home"
self.accept()
self.send_json(
{
"type": "welcome_message",
"message": "Hey there! You've successfully connected!",
}
)
def disconnect(self, code):
print("Disconnected!")
return super().disconnect(code)
def receive_json(self, content, **kwargs):
print(content)
return super().receive_json(content, **kwargs)
\ No newline at end of file
from django.urls import path
from backend.consumers import ChatConsumer
websocket_urlpatterns = [
path("/chatSocket", ChatConsumer.as_asgi())
]
\ No newline at end of file
"""
Django settings for backend project.
Generated by 'django-admin startproject' using Django 4.0.4.
For more information on this file, see
https://docs.djangoproject.com/en/4.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.0/ref/settings/
"""
from pathlib import Path
import datetime
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'django-insecure-54-4$#$7yzk9*+myixyk2fu(-u0sg(wtf8a$ets11yeqs5w0ly'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['*']
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'backend.cms',
'corsheaders',
'channels'
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'backend.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'backend.wsgi.application'
# Database
# https://docs.djangoproject.com/en/4.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
# Password validation
# https://docs.djangoproject.com/en/4.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
# {
# 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
# },
# {
# 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
# },
# {
# 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
# },
# {
# 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
# },
]
# Internationalization
# https://docs.djangoproject.com/en/4.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.0/howto/static-files/
STATIC_URL = 'static/'
# Default primary key field type
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 100,
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
'rest_framework.authentication.SessionAuthentication',
]
}
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': datetime.timedelta(minutes=14*24*60),
'REFRESH_TOKEN_LIFETIME': datetime.timedelta(days=30),
'ROTATE_REFRESH_TOKENS': True,
'BLACKLIST_AFTER_ROTATION': True,
'ALGORITHM': 'HS256',
'SIGNING_KEY': SECRET_KEY,
'VERIFYING_KEY': None,
'AUTH_HEADER_TYPES': ('JWT',),
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_id',
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
'TOKEN_TYPE_CLAIM': 'token_type',
'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
'SLIDING_TOKEN_LIFETIME': datetime.timedelta(minutes=60),
'SLIDING_TOKEN_REFRESH_LIFETIME': datetime.timedelta(days=1),
}
CORS_ALLOW_ALL_ORIGINS = True # If this is used then `CORS_ALLOWED_ORIGINS` will not have any effect
CORS_ALLOW_CREDENTIALS = True
ASGI_APPLICATION = "backend.asgi.application"
\ No newline at end of file
from django.urls import include, path, re_path
from rest_framework import routers
from backend.cms.views import ObtainTokenPairWithUserView
from backend.cms import views
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
from rest_framework.authtoken.views import obtain_auth_token
from django.contrib import admin
router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)
router.register(r'mlmodels', views.MlModelViewSet)
router.register(r'chats', views.ChatViewSet)
router.register(r'conversations', views.ConversationViewSet)
# Wire up our API using automatic URL routing.
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
path('', include(router.urls)),
path('admin/', admin.site.urls),
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
re_path(r'^api/auth/token/obtain/$', ObtainTokenPairWithUserView.as_view()),
re_path(r'^api/auth/token/refresh/$', TokenRefreshView.as_view()),
# url(r'^auth/login/$',
# obtain_auth_token,
# name='auth_user_login'),
]
\ No newline at end of file
"""
WSGI config for backend project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/4.0/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings')
application = get_wsgi_application()
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'backend.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment