# Project export: EcoScan

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: CruzHacks 2024
- Tagline: Explore products, trace their impact, and joina community dedicated to conscious choices fora greener tomorrow.
- Devpost: https://devpost.com/software/ecoscan-p85m9g
- GitHub: https://github.com/Jeffuz/eco_scan
- Result: winner (Most Ambitious)
- Team: 4 GitHub contributor(s) — Jeffuz (23 commits), CallMeCalvin101 (7 commits), Mona Zhao (4 commits), Ginna Khang (4 commits)

## Devpost submission (written by the team)

### What it does

The website would prompt the user to input a link specifically from amazon. If the user inputs a valid link, it will then send that link to the server. The server would scrape all relevant information on the inputted link and feed that information to a trained AI from openAI. The AI would then upload the environmental impacts of the product based on the scraped data and upload that to an online database, which the website would read and output the results back to the user on their browser.

### How we built it

The project is built using React for the front-end user page and python for the server that houses the AI. The server was implemented with 3 different libraries/APIs, BeautifulSoup for web scraping, OpenAI for the AI system, and Firebase for data storage and travel. The webpage was primarily built using React and javascript, with the addition of firebase to handle the reading information from the database.

### Challenges we ran into

The main challenge we ran into was trying to set up the project. With trying to integrate so many different libraries into our project, it was difficult to set up, not only on one person’s system, but replicated that on everyone else's as well. We also had trouble trying to train the Ai to have desirable results. At the start, the responses it gave were too generic and not specific to be useful to the user, but we managed to fix that with refinement.

### Accomplishments we're proud of

We are proud to be able to put out a viable project in such a short timeframe, and to be able to use a lot of complicated, yet relevant tools in our disposal. Being able to use React, AI, web scraping, and an online database, in the same project and in less than 2 days at that, is an accomplishment.

### What we learned

We learned a lot about the technologies and tools that we are using. Many of us aren’t familiar with web development so It was a good experience to step out of our comfort zone and learn something new. It was also a nice opportunity to collaborate with each other for the first time, being able to learn about our working styles and improve on our skills to work as part of a team.

### What's next

Currently, there are no immediate plans to expand on this project. However, there are different ideas bouncing around on ways to improve on this project, One of which is to improve the UI of the result page by making it less text-heavy, and more visual. We could also improve the AI to read images from Amazon using a more advanced AI model. But outside of just the website, we can take this idea and expand it to be a web-extension rather than a separate website that users can install for online shopping, having a convenient way of seeing their environmental impact. We can even take this idea further and take it out of the internet, and have an app that allows users to use their camera on their phone to scan real life products as well.

## README (from the GitHub repository)

# EcoScan 
EcoScan is an environmental impact assessment tool that utilizes data scraped from Amazon (more soon to come) to generate informative results pages for products, showcasing key details such as material composition, and environmental impacts from manufacturing and shipping.

![ecoscan](https://github.com/Jeffuz/eco_scan/assets/52511888/cc404033-de65-49e9-9b57-8de847ac6d9b)

## About 
### What it does
The website would prompt the user to input a link specifically from Amazon. If the user inputs a valid link, it will send it to the server. The server would scrape all relevant information on the inputted link and feed that information to a trained AI from openAI. The AI would then upload the environmental impacts of the product based on the scraped data and upload that to an online database, which the website would read and output the results back to the user on their browser.

### How we built it
The project is built using React for the front-end user page and Python for the server that houses the AI. The server was implemented with 3 different libraries/APIs, BeautifulSoup for web scraping, OpenAI for the AI system, and Firebase for data storage and travel. The webpage was primarily built using React and JavaScript, with the addition of Firebase to handle the reading information from the database.

### Challenges we ran into
The main challenge we ran into was trying to set up the project. With trying to integrate so many different libraries into our project, it wasn't easy to set up, not only on one person’s system, but replicated on everyone else's as well. We also had trouble trying to train the Ai to have desirable results. At the start, the responses it gave were too generic and not specific to be useful to the user, but we managed to fix that with refinement.

### Accomplishments that we’re proud of
We are proud to be able to put out a viable project in such a short timeframe and to be able to use a lot of complicated, yet relevant tools in our disposal. Being able to use React, AI, web scraping, and an online database, in the same project and in less than 2 days at that, is an accomplishment.

### What we learned
We learned a lot about the technologies and tools that we are using. Many of us aren’t familiar with web development so It was a good experience to step out of our comfort zone and learn something new. It was also a nice opportunity to collaborate with each other for the first time, being able to learn about our working styles, and improve our skills to work as part of a team.

### What’s next for EcoScan
Currently, there are no immediate plans to expand on this project. However, different ideas are bouncing around on ways to improve this project, One of which is to improve the UI of the result page by making it less text-heavy, and more visual. We could also improve the AI to read images from Amazon using a more advanced AI model.

But outside of just the website, we can take this idea and expand it to be a web extension rather than a separate website that users can install for online shopping, having a convenient way of seeing their environmental impact. We can even take this idea further and take it out of the internet and have an app that allows users to use their camera on their phone to scan real-life products as well.

## Installation
Use the package manager [npm](https://www.npmjs.com/) to install packages for frontend dependencies.
```bash
npm install 
```

Setup enviornment variables for server side.
```bash
python -m pip install --user virtualenv
python -m venv env
# Make sure to enable scripts on Power Shell for Window users
Set-ExecutionPolicy RemoteSigned
```
Create .env file and put in your own private OpenAi API key.
```bash
OPENAI_API_KEY = (API KEY)
```

Create headers.py file, go to this [website](https://httpbin.org/get) and fill in the below header.
```bash
HEADERS = {
    "Accept": "",
    "Accept-Encoding": "",
    "Accept-Language": "",
    "User-Agent": "",
    "X-Amzn-Trace-Id": ""
}
```

Open 2 terminals up...
```bash
# Start up the browser side in the first terminal
npm start
# Enable virtual enviornment in the second terminal
.\env\Scripts\activate # Run for Windows
source env/bin/activate # Run for MacOS
# Pip install packages and start up server within the virtual env.
pip install -r requirements.txt
python server.py
```


## Detected evidence (automated analysis)

Indexed codebase: 15 recognized source files, 23 KB.
- CSS (language) — detected in the code
- Firebase (technology) — detected in the code
- Flask (technology) — detected in the code
- HTML (language) — detected in the code
- JavaScript (language) — detected in the code
- OpenAI (technology) — detected in the code
- Python (language) — detected in the code
- React (technology) — detected in the code
- Tailwind CSS (technology) — detected in the code

## Codebase structure (from repository index)

### Files (22 of 22)

```
.gitattributes
.gitignore
eco-scan-firebase-adminsdk-zb1aw-f22f3c50fd.json
package.json
public/index.html
public/manifest.json
public/robots.txt
README.md
requirements.txt
server.py
src/App.css
src/App.js
src/components/navbar.jsx
src/components/searchbar.js
src/firebase.js
src/index.css
src/index.js
src/pages/AboutPage.js
src/pages/ContactPage.js
src/pages/HomePage.js
src/pages/ResultPage.js
tailwind.config.js
```

### Dependencies

- package.json: @testing-library/jest-dom@^5.17.0, @testing-library/react@^13.4.0, @testing-library/user-event@^13.5.0, firebase@^10.7.2, react@^18.2.0, react-dom@^18.2.0, react-intersection-observer@^9.5.3, react-router-dom@^6.21.3, react-scripts@^5.0.1, tailwindcss@^3.4.1, web-vitals@^2.1.4
- requirements.txt: beautifulsoup4, firebase, firebase-admin, Flask, lxml, openai, python-dotenv, requests

### Recent commits (newest first)

- Update README.md
- Update README.md
- update scroll bar ui
- Update searchbar.js
- Update requirements.txt
- small ui fix
- Merge pull request #7 from Jeffuz/update-ui-jeff
- enable scanning after scanning
- scrape product title and display on results page
- Merge pull request #6 from Jeffuz/contactPage
- update searchbar ui
- Merge pull request #5 from Jeffuz/aboutPage
- Merge branch 'main' into aboutPage
- update about page
- created and completed contact page
- Merge pull request #4 from Jeffuz/firebase-calvin
- added firebase-admin
- added to requirements.txt
- Renamed firebase file
- read data from db

## Key source files (fetched from GitHub, selected and truncated for size)

### requirements.txt

```
Flask
beautifulsoup4
requests
lxml
openai
python-dotenv
firebase
firebase-admin
```

### package.json

```
{
  "name": "eco_scan",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@testing-library/jest-dom": "^5.17.0",
    "@testing-library/react": "^13.4.0",
    "@testing-library/user-event": "^13.5.0",
    "firebase": "^10.7.2",
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "react-intersection-observer": "^9.5.3",
    "react-router-dom": "^6.21.3",
    "react-scripts": "^5.0.1",
    "web-vitals": "^2.1.4"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "devDependencies": {
    "tailwindcss": "^3.4.1"
  }
}

```

### server.py

```python
from flask import Flask, request
from bs4 import BeautifulSoup
import requests
import lxml
from dotenv import load_dotenv
from openai import OpenAI
import firebase_admin
from firebase_admin import credentials
from firebase_admin import db
import os
from headers import HEADERS

# setup
app = Flask(__name__)
load_dotenv()
api_key = os.getenv("OPENAI_API_KEY")

# Firebase Setup
cred = credentials.Certificate('eco-scan-firebase-adminsdk-zb1aw-f22f3c50fd.json')
firebase_admin.initialize_app(cred, {
    'databaseURL': 'https://eco-scan-default-rtdb.firebaseio.com'
})
ans = db.reference('answers')

# Scrape Content Based on ID
def scrape_elements_content(url, headers, element_ids):
    page = requests.get(url, headers=headers)
    raw_html = BeautifulSoup(page.content, "lxml")
    
    result = {}
    for element_id in element_ids:
        element = raw_html.find(id=element_id)
        if element:
            result[element_id] = element.get_text(strip=True)

    return result

def feed_scrape_data(url):
    element_ids_to_scrape = ["productTitle", "productFactsDesktopExpander", "feature-bullets", "productDetails_detailBullets_sections1", "productDescription", "important-information", "aplus"]
    headers = HEADERS
    scraped_elements = scrape_elements_content(url, headers, element_ids_to_scrape)

    return scraped_elements
    
def process_AI(queary):
    # Setup for OpenAI
    load_dotenv()
    api_key = os.getenv("OPENAI_API_KEY")
    client = OpenAI(api_key=api_key)

    # Prompt OpenAi
    completion = client.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=[
            {"role": "system",
            "content": "Given the scraped data from Amazon, describe what materials that the product is made out of and approximately the amount of that material. Describe the environmental impacts of said material taking in consideration how much of it is present in the product. Also describe the envirenmental impact of shipping the product from its manufactured location. Also, output a response in a organized under the headers of: 'Materials', 'Manufacturing', 'Shipping'"
            },
            {"role": "user", 
            "content": str(queary)
            }
        ]
    )

    return completion.choices[0].message.content

def write_to_firebase(data, product_title):
    ans.set({
        'test': data,
        'productTitle': product_title,
    })

def write_product_title_to_firebase(product_title):
    ans.child('productTitle').set(product_title)

@app.route("/")
def homePage():
    search_input = request.args.get('searchInput', default='', type=str)
    url = str(search_input)

    scraped_data = feed_scrape_data(url)
    product_title = scraped_data.get('productTitle', '')

    write_to_firebase(str(process_AI(feed_scrape_data(url))), product_title)
    return str(process_AI(feed_scrape_data(url)))

if __name__ == "__main__":
    app.run(debug=True)


```

### src/index.js

```javascript
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import { BrowserRouter } from 'react-router-dom';


const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <BrowserRouter><App /></BrowserRouter>
  </React.StrictMode>
);


```

### src/App.js

```javascript
import "./index.css";
import { Routes, Route } from "react-router-dom";

import Home from "./pages/HomePage";
import AboutPage from "./pages/AboutPage";
import ResultPage from "./pages/ResultPage";
import ContactPage from "./pages/ContactPage";
// import { testFirebase } from "./firebaseTest.js";

/* 
To add more paths for the paging, follow:
* import cruzhacks2024 from ...;
* <Route path='/cruzhacks2024' element={<cruzhacks2024 />} />
*/

function App() {
  // testFirebase();

  return (
    <>
      <Routes>
        <Route index element={<Home />} />
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<AboutPage />} />
        <Route path="/result" element={<ResultPage />} />
        <Route path="/contact" element={<ContactPage />} />
      </Routes>
    </>
  );
}

export default App;

```

### tailwind.config.js

```javascript
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [
    "./src/**/*.{js,jsx,ts,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}


```

### src/index.css

```css
@tailwind base;
@tailwind components;
@tailwind utilities;

::-webkit-scrollbar {
    width: 12px;
  }
  
  ::-webkit-scrollbar-thumb {
    background-color: #333a5a; 
  }
```

### src/firebase.js

```javascript
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getDatabase } from "firebase/database";
// import firebase from "firebase/compat/app";
// import "firebase/compat/database";
// import { get, child } from 'firebase/database';


// Your web app's Firebase configuration
const firebaseConfig = {
  apiKey: "AIzaSyCBZH1M16kvK4_AUVlZtCHxY5ZLE3y_1I8",
  authDomain: "eco-scan.firebaseapp.com",
  databaseURL: "https://eco-scan-default-rtdb.firebaseio.com",
  projectId: "eco-scan",
  storageBucket: "eco-scan.appspot.com",
  messagingSenderId: "985585837598",
  appId: "1:985585837598:web:4b41d85a1e908de55db00f",
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);
const db = getDatabase(app);
export default db;

// const ansRef = firebase.database().ref(`answers`);

// export const testFirebase = () => {
//   get(child(ansRef, `test`)).then((snapshot) => {
//     if (snapshot.exists()) {
//       console.log(snapshot.val());
//     } else {
//       console.log("No Data Found");
//     }
//   });
// } 
```

### public/index.html

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <!--
      manifest.json provides metadata used when your web app is installed on a
      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>React App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  </body>
</html>

```

### src/components/navbar.jsx

```javascript
import React from 'react';
import logoImage from './logo-white2.png';
import { Link } from 'react-router-dom';

const Navbar = ({ navbarColor }) => {
  return (
    <div className={`py-4 px-28 flex justify-between items-center fixed ${navbarColor} w-[100%]`}>
      <Link to="/" className="no-underline transition-transform transform hover:scale-105 duration-300">
        <img src={logoImage} alt="Logo" className="logo-img h-12 mr-4" />
      </Link>

      <div className="flex font-mono gap-12">
        <Link to="/" className="text-white text-lg no-underline hover:text-gray-400 duration-300">
          Home
        </Link>
        <Link to="/about" className="text-white text-lg no-underline hover:text-gray-400 duration-300">
          About
        </Link>
        <Link to="/contact" className="text-white text-lg no-underline hover:text-gray-400 duration-300">
          Contact
        </Link>
      </div>
    </div>
  );
};

export default Navbar;

```

[5 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]