From 39e611f8c312bf9acd10ef9b1e18abdc399829fc Mon Sep 17 00:00:00 2001 From: ardaakman Date: Wed, 28 Feb 2024 14:22:22 -0800 Subject: [PATCH 1/4] Made small improvement, so website waits for model wakeup. Pushing model autoscaling duration to an hour --- src/components/App.tsx | 4 ++- src/components/SearchBar.tsx | 10 -------- src/helpers/contexts.tsx | 5 ++++ src/helpers/index.ts | 3 ++- src/pages/index.tsx | 47 ++++++++++++++++++++++++++++++++++++ 5 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 src/helpers/contexts.tsx diff --git a/src/components/App.tsx b/src/components/App.tsx index e118002..1a87d9e 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -1,8 +1,10 @@ // pages/index.tsx import React from "react"; -import { RotatingCarousel, SearchBar } from "../components"; + import styles from "../styles/App.module.css"; +import { RotatingCarousel, SearchBar } from "../components"; + const App = () => { return (
diff --git a/src/components/SearchBar.tsx b/src/components/SearchBar.tsx index 4553cdf..976cd79 100644 --- a/src/components/SearchBar.tsx +++ b/src/components/SearchBar.tsx @@ -37,19 +37,10 @@ export const SearchBar = () => { const { vendor, useComponents } = useSearchStore((state) => { return { vendor: state.vendor, useComponents: state.useComponents }; }); - debugger; const rootRef = React.useRef(null); const fileInputRef = useRef(null); - React.useEffect(() => { - debugger; - console.log(vendor, useComponents); - // Wake up the model when we first load this page. - // dont fetch components here, just send a get request to wake up the model - // fetch(ENDPOINT + "/wakeup"); - }, []); - const handleKeyPress = (e: React.KeyboardEvent) => { if (e.key === "Enter") { const routeObject: routeInput = { @@ -100,7 +91,6 @@ export const SearchBar = () => { // This function loads in the image, and then also sets the imageSrc to the right src so the canvas can load the image. // Furthermore, it obtains the image components for a given image, sending the base64 encoding of the image as part of a json payload. // Then, we can provide the options to the users to select from. - console.log(useComponents); useSearchStore.setState({ useComponents: !useComponents }); setUpload(true); diff --git a/src/helpers/contexts.tsx b/src/helpers/contexts.tsx new file mode 100644 index 0000000..5f41f40 --- /dev/null +++ b/src/helpers/contexts.tsx @@ -0,0 +1,5 @@ +import React from "react"; + +import { createContext, useState } from "react"; + +export const LoadingContext = createContext(false); diff --git a/src/helpers/index.ts b/src/helpers/index.ts index 65bd1bc..be8b9ca 100644 --- a/src/helpers/index.ts +++ b/src/helpers/index.ts @@ -1,4 +1,5 @@ export type {searchRequestPayload, routeInput, configJson} from './backendTypes'; export type { Item, searchBoxInput, modalInput } from './frontendTypes'; export { getJsonResponse } from './api'; -export { fetchFromS3, uploadToS3 } from './aws'; \ No newline at end of file +export { fetchFromS3, uploadToS3 } from './aws'; +export { LoadingContext } from './contexts'; \ No newline at end of file diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 9564b2b..33f72c6 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -1,7 +1,54 @@ import React from "react"; +import ReactLoading from "react-loading"; + import { App, Logo } from "../components"; +import config from "../../config.json"; +import { Typography } from "@mui/material"; + +const ENDPOINT = + // @ts-ignore + config.config.api.api_endpoints[config.config.api.current_version]; + const Home = () => { + const [loading, setLoading] = React.useState(true); + + const makeWakeUpRequest = async () => { + await fetch(ENDPOINT + "/wakeup"); + }; + + React.useEffect(() => { + debugger; + // Wake up the model when we first load this page. + // dont fetch components here, just send a get request to wake up the model + makeWakeUpRequest(); + // Wait a random amount of seconds, between 2-3 seconds. + setTimeout(() => { + setLoading(false); + }, Math.random() * 1000 + 2000); + }, []); + + if (loading) { + return ( +
+ + Waking up the model... +
+ ); + } return (
From 5d6fc8f259ec74b1d89a7e2f4eb9556e71c053ea Mon Sep 17 00:00:00 2001 From: ardaakman Date: Mon, 25 Mar 2024 21:47:02 -0700 Subject: [PATCH 2/4] Lol security vulnerability --- src/pages/results.tsx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/pages/results.tsx b/src/pages/results.tsx index ef464c8..bff7ed7 100644 --- a/src/pages/results.tsx +++ b/src/pages/results.tsx @@ -22,12 +22,6 @@ type ResultsProps = { searchQuery: string; }; -const s3 = new AWS.S3({ - accessKeyId: "AKIAXWYG7NAVSRIQFHK2", - secretAccessKey: "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", - region: "us-east-2", -}); - const Results: React.FC = ({ items, searchQuery }) => { const [validItems, setValidItems] = React.useState([]); const vendor = useSearchStore((state) => state.vendor); From 6eddd0c7f0c07f62a62d0927417d242dea43d907 Mon Sep 17 00:00:00 2001 From: ardaakman Date: Sun, 14 Jul 2024 17:07:57 -0700 Subject: [PATCH 3/4] Set website offline after killing rds --- .env.local | 4 +++ package.json | 1 + src/.aws/config | 2 ++ src/.aws/credentials | 3 +++ src/components/SearchBar.tsx | 52 ++++++++++-------------------------- src/helpers/aws.ts | 20 +++++++++----- src/pages/_app.tsx | 2 ++ src/pages/index.tsx | 3 +-- src/pages/offline.tsx | 45 +++++++++++++++++++++++++++++++ 9 files changed, 85 insertions(+), 47 deletions(-) create mode 100644 .env.local create mode 100644 src/.aws/config create mode 100644 src/.aws/credentials create mode 100644 src/pages/offline.tsx diff --git a/.env.local b/.env.local new file mode 100644 index 0000000..a0700c8 --- /dev/null +++ b/.env.local @@ -0,0 +1,4 @@ +NEXT_PUBLIC_AWS_API_ENDPOINT=https://simple-api-it6x.onrender.com +OBVIOUS_AWS_KEY=AKIAXWYG7NAVSRIQFHK2 +0BVIUOS_AWS_SECRET=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 +OBVIOUS_AWS_REGION=us-east-2 \ No newline at end of file diff --git a/package.json b/package.json index eff8121..e1cad45 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "private": true, "dependencies": { "@auth0/nextjs-auth0": "^3.1.0", + "@aws-sdk/client-s3": "^3.540.0", "@emotion/react": "^11.11.1", "@emotion/server": "^11.11.0", "@emotion/styled": "^11.11.0", diff --git a/src/.aws/config b/src/.aws/config new file mode 100644 index 0000000..4e9dd40 --- /dev/null +++ b/src/.aws/config @@ -0,0 +1,2 @@ +[default] +region = us-east-2 \ No newline at end of file diff --git a/src/.aws/credentials b/src/.aws/credentials new file mode 100644 index 0000000..e7efdf2 --- /dev/null +++ b/src/.aws/credentials @@ -0,0 +1,3 @@ +[default] +aws_access_key_id = AKIAXWYG7NAVSRIQFHK2 +aws_secret_access_key = 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 diff --git a/src/components/SearchBar.tsx b/src/components/SearchBar.tsx index 976cd79..259d28f 100644 --- a/src/components/SearchBar.tsx +++ b/src/components/SearchBar.tsx @@ -1,16 +1,8 @@ -import React, { use } from "react"; +import React, { useState, useRef } from "react"; import AddAPhotoIcon from "@mui/icons-material/AddAPhoto"; -// import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; - -import { useState, useRef } from "react"; import { useRouter } from "next/router"; -// import { Box, Button, Modal, Typography, Checkbox } from "@mui/material"; -// import { MenuProps } from "@mui/material/Menu"; - import SearchModal from "./Modal"; import styles from "../styles/SearchBar.module.css"; - -// import { ImageCanvas } from "./ImageUploaderCanvas"; import { uploadToS3, getJsonResponse, @@ -22,7 +14,11 @@ import { useSearchStore } from "../lib/searchStore"; import VendorMenu from "./VendorMenu"; import { config } from "../../config.json"; +type websiteStatus = "Online" | "Offline"; + +const STATUS: websiteStatus = "Offline"; const configContents: configJson = config; +// @ts-ignore const ENDPOINT = // @ts-ignore configContents.api.api_endpoints[configContents.api.current_version]; @@ -38,19 +34,18 @@ export const SearchBar = () => { return { vendor: state.vendor, useComponents: state.useComponents }; }); - const rootRef = React.useRef(null); const fileInputRef = useRef(null); const handleKeyPress = (e: React.KeyboardEvent) => { if (e.key === "Enter") { const routeObject: routeInput = { - pathname: "/results", + pathname: STATUS !== "Offline" ? "/results" : "/offline", query: { - q: input, + q: STATUS !== "Offline" ? input : "", imageSearch: false, imageName: null, - component: selectedChoice, - vendor: vendor, + component: selectedChoice || "", + vendor: vendor || "", }, }; router.push(routeObject); @@ -62,18 +57,13 @@ export const SearchBar = () => { const base64Image = imageSrc.split(",")[1]; const key = await uploadToS3(base64Image); - // Convert to base64 actually - const encodedChoice = selectedChoice !== "All" ? selectedChoice : null; - - console.log(key); - const routeObject: routeInput = { - pathname: "/results", + pathname: STATUS !== "Offline" ? "/results" : "/offline", query: { q: null, imageSearch: true, imageName: config.s3_bucket_prefix + key, - component: encodedChoice, + component: selectedChoice !== "All" ? selectedChoice : null, vendor: vendor, }, }; @@ -88,35 +78,24 @@ export const SearchBar = () => { }; const getImageComponents = async () => { - // This function loads in the image, and then also sets the imageSrc to the right src so the canvas can load the image. - // Furthermore, it obtains the image components for a given image, sending the base64 encoding of the image as part of a json payload. - // Then, we can provide the options to the users to select from. - useSearchStore.setState({ useComponents: !useComponents }); setUpload(true); - const fileInput = fileInputRef.current; if (!fileInput || !fileInput.files || fileInput.files.length === 0) { return; } const imageFile = fileInput.files[0]; - - // Convert the image to a base64 string const reader = new FileReader(); reader.readAsDataURL(imageFile); reader.onload = async () => { const image = reader.result as string; - //ignore the type error here, it is a known issue - setImageSrc(image); // Set the image source for canvas + setImageSrc(image); if ( typeof image === "string" && ENDPOINT !== undefined && - useComponents && - false + useComponents ) { - console.log(useComponents); - // Convert the image to base64 actually const base64Image = image.split(",")[1]; const request: searchRequestPayload = { requestType: "POST", @@ -163,12 +142,10 @@ export const SearchBar = () => { onKeyPress={handleKeyPress} className={styles.input} /> - {/* The icon is positioned absolutely within the relative inputWrapper */} - {/* The input is hidden with opacity 0 and position absolute. This is what actually does the uplpad image functionality */} { onChange={getImageComponents} />
- {/* Add a menu dropdown here, where you have multiple options and a scroller if necessary here, that says "wayfair search" */}
diff --git a/src/helpers/aws.ts b/src/helpers/aws.ts index 7de2040..a9c3c37 100644 --- a/src/helpers/aws.ts +++ b/src/helpers/aws.ts @@ -1,13 +1,18 @@ -import AWS from "aws-sdk"; +import AWS from 'aws-sdk' +import * as dotenv from 'dotenv'; + import { v4 as uuidv4 } from "uuid"; -const s3 = new AWS.S3({ - accessKeyId: "AKIAXWYG7NAVSRIQFHK2", - secretAccessKey: "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", - region: "us-east-2", - }); - +dotenv.config(); + +const s3 = new AWS.S3(); + +s3.config.update({ + region: 'us-east-2', + accessKeyId: process.env.OBVIOUS_AWS_KEY ?? '', + secretAccessKey: process.env.OBVIOUS_AWS_SECRET ?? '', +}) const fetchFromS3 = async (key: string) => { const params = { @@ -45,6 +50,7 @@ const uploadToS3 = async (base64Data: string) => { ContentType: 'image/jpeg' }; + console.log(s3) try { await s3.upload(params).promise(); return uniqueKey; diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index df05b52..6864d3a 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -1,4 +1,5 @@ import React from "react"; +import * as dotenv from "dotenv"; import type { AppProps } from "next/app"; import { Box } from "@mui/system"; @@ -8,6 +9,7 @@ import "../styles/global.css"; import { NavBar, Footer } from "../components"; +dotenv.config(); function MyApp({ Component, pageProps }: AppProps) { return ( diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 33f72c6..391c917 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -18,10 +18,9 @@ const Home = () => { }; React.useEffect(() => { - debugger; // Wake up the model when we first load this page. // dont fetch components here, just send a get request to wake up the model - makeWakeUpRequest(); + // makeWakeUpRequest(); // Wait a random amount of seconds, between 2-3 seconds. setTimeout(() => { setLoading(false); diff --git a/src/pages/offline.tsx b/src/pages/offline.tsx new file mode 100644 index 0000000..ce3cbc1 --- /dev/null +++ b/src/pages/offline.tsx @@ -0,0 +1,45 @@ +// Create view that just says "Thank you for visiting our page! You can view the code for the project at _______, but we have stopped working on this to cut from monthly model and hosting costs." Then add a portion with a video that shows a demo of the website, and under it say "here is a demo of what the website looked like while online." +import React from "react"; + +import { Typography } from "@mui/material"; + +export default function Offline() { + return ( +
+ + Thank you for visiting our projects page! You can view the code for the + project at https://github.com/ObviousAI/website (if you want to see the + code for the actual models and embeddings, reach me out on linkedin), + but we have stopped working on this to cut from monthly model and + hosting costs." Then add a portion with a video that shows a demo of the + website, and under it say "here is a demo of what the website looked + like while online. + +
+ +
+ + Above is a demo of what the website looked like while online. + +
+ ); +} From b137c7fe11ae75b2ab441e35c1b3bf13d5a79384 Mon Sep 17 00:00:00 2001 From: ardaakman Date: Sun, 14 Jul 2024 17:13:04 -0700 Subject: [PATCH 4/4] Removed submit button functionality --- src/components/SearchBar.tsx | 14 +++++++++----- src/pages/offline.tsx | 20 ++++++++++---------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/components/SearchBar.tsx b/src/components/SearchBar.tsx index 259d28f..62c41a0 100644 --- a/src/components/SearchBar.tsx +++ b/src/components/SearchBar.tsx @@ -54,8 +54,12 @@ export const SearchBar = () => { const handleSubmitButton = async () => { if (!imageSrc) return; - const base64Image = imageSrc.split(",")[1]; - const key = await uploadToS3(base64Image); + let base64Image = ""; + let key: string | null = ""; + if (STATUS !== "Offline") { + base64Image = imageSrc.split(",")[1]; + key = await uploadToS3(base64Image); + } const routeObject: routeInput = { pathname: STATUS !== "Offline" ? "/results" : "/offline", @@ -72,7 +76,7 @@ export const SearchBar = () => { }; const handleButtonClick = () => { - if (fileInputRef.current) { + if (fileInputRef.current && STATUS !== "Offline") { fileInputRef.current.click(); } }; @@ -142,10 +146,10 @@ export const SearchBar = () => { onKeyPress={handleKeyPress} className={styles.input} /> - + /> */} - + Thank you for visiting our projects page! You can view the code for the - project at https://github.com/ObviousAI/website (if you want to see the - code for the actual models and embeddings, reach me out on linkedin), - but we have stopped working on this to cut from monthly model and - hosting costs." Then add a portion with a video that shows a demo of the - website, and under it say "here is a demo of what the website looked - like while online. + project here{" "} + (if you want to see the code for the actual models and embeddings, reach + me out on linkedin), but we have stopped working on this to cut from + monthly model and hosting costs." Then add a portion with a video that + shows a demo of the website, and under it say "here is a demo of what + the website looked like while online.
- + Above is a demo of what the website looked like while online.