Giter Site home page Giter Site logo

clean-marine's Introduction

Clean Marine

This web app serves as a centralized hub for information about local beach clean up events, originally created for the HOTHX hackathon, hosted by UCLA ACM Hack in 2023.

Clean Marine was built using the Python Django full-stack webframework for hosting th SQLite database and web server, webscraping scripts using Selenium and Beautiful Soup, and the Google Maps API to provide users a visual guide on locating nearby events. Additionally, this app has been Dockerizied allowing it to be run in any environment (with Docker installed) with a simplified setup process. This feature was implemented for Paramount Data and Decision Science Group's Hackweek 2023 to research how to Dockerize multi-container applications.

HothX Presentation and Demo: https://youtu.be/zuwXPLttlSM

Table of Contents

Docker Setup

Steps

  1. Install Docker Desktop. Open Docker and restart the your terminal window.
  2. Clone the repository and cd into it.
    git clone https://github.com/ajtadeo/clean-marine.git
    cd clean-marine
  3. In the project root directory, create .env with the following credentials:
    GOOGLE_MAPS_KEY=secret
    SECRET_KEY=secret
  4. Execute docker compose up in the project root directory.
  5. Open the app at 0.0.0.0:8000
  6. To stop the app, either click Ctrl-C in the terminal or run docker compose down in a seperate terminal.

Docker-ization Steps

Originally, Clean Marine was setup using a conda virtual environment. The code for this implementation can be viewed here. The following steps were taken to Dockerize the application to the current implementation:

  1. Convert base.yml to requirements.txt.

    pip freeze > requirements.txt
  2. Fill out .env with the following credentials. If .env hasn't already been created, create it.

    GOOGLE_MAPS_KEY=secret
    SECRET_KEY=secret

    NOTE: We can't use Docker Secrets because this app isn't configured as a Docker Swarm.

  3. In the root directory, initialize Docker files and create an image of the application

    docker init
        ? What application platform does your project use? Python
        ? What version of Python do you want to use? 3.11.4
        ? What port do you want your app to listen on? 8000
        ? What is the command to run your app? python manage.py runserver 0.0.0.0:8000
    

    Now, the file structure should look like this:

    clean-marine/           <-- Django project root     
    ├── clean-marine/       <-- clean-marine app, contains settings and configuration
    ├── dashboard/          <-- dashboard app
    │   ├── static/
    │   ├── templates/
    │   ├── base.yml
    │   ├── db.sqlite3
    │   ├── dump.json
    │   ├── manage.py
    │   ├── notes.txt
    │   └── tasks.py
    ├── components/         <-- components
    │   └── event/
    ├── .gitignore
    ├── .dockerignore       <-- NEW
    ├── .env
    ├── .gitignore
    ├── compose.yaml        <-- NEW
    ├── Dockerfile          <-- NEW
    ├── manage.py
    ├── tasks.py
    ├── requirements.txt
    └── README.md
    
  4. Update compose.yaml to reference .env as the environment variables file.

    services:
     django:
       build:
         context: .
       ports:
         - 8000:8000
       env_file:
         - ./.env

    NOTE: Selenium must be added as a service to fix the broken webscrapers. This will be implemented in a future update.

  5. In clean-marine/settings.py, add 0.0.0.0 to ALLOWED-HOSTS to let the user connect to the Django app through the isolated Docker environment.

    # ...
    ALLOWED_HOSTS = ['0.0.0.0']
    # ...
  6. Create the Docker image and run the app.

    docker compose up

    Visit your newly Docker-ized app at 0.0.0.0:8000 🥳!

    NOTE: The Docker images in this multi-container app have the format clean-marine-[service].

  7. To stop the app, either click Ctrl-C in the terminal or run docker compose down in a seperate terminal.

Making Changes

If changes are made to the Django app or the Docker configuration files, its necessary to remove the containers and images and create new ones.

  1. Stop any running containers by either clicking Ctrl-C in the terminal or run docker compose down in a seperate terminal. These commands will also remove the containers.

  2. Verify the containers were removed.

    docker ps -a
  3. Remove the image.

    docker image rm clean-marine-django
  4. Verify the image was removed.

    docker images
  5. Recreate the image.

    docker compose up

Invoke Commands

Invoke commands are this app's custom CLI, used for simplifying tasks that are done regularly. Run these commands from the root directory clean-marine.

invoke scrape

  • Runs all web scrapers and updates the database with new information.
  • Currently implemented web scrapers:
    • Surfrider Foundation

invoke dump

  • Dumps data from the SQLite database into dump.json in the project root directory.

Database Manipulation

View Table Structure

  1. In the terminal:
    python3 manage.py dbshell
  2. In the dbshell:
    .header on
    .mode column
    pragma table_info('dashboard_events');

Update Table Structure

  1. Make changes to dashboard/models.py
  2. In the terminal in the root directory:
    python manage.py makemigrations
    python manage.py migrate

Delete the Table

Sometimes it's best to just start from scratch and rerun the webscraper ;-;

  1. In the terminal:
    python manage.py dbshell
  2. In the dbshell:
    DROP TABLE dashboard_events;

Create the Table

  1. In the terminal:
    python manage.py dbshell
  2. In the dbshell:
    CREATE TABLE dashboard_events (
        id INTEGER PRIMARY KEY NOT NULL,
        eventname TEXT NOT NULL UNIQUE,
        organization TEXT NOT NULL,
        link TEXT NOT NULL,
        datetime TEXT,
        location TEXT,
        lng FLOAT,
        lat FLOAT
    );

Conda Setup (Deprecated)

The code for this deprecated setup method is intended to be used at this release or earlier. Use the Docker setup for current implementation.

Steps

  1. Install python3 and the Chrome driver for web scraping on your machine
  2. Clone the repository and cd into it.
    git clone https://github.com/ajtadeo/clean-marine.git
    cd clean-marine
  3. Set up the virtual environment.
    • Create the virutal environment.
      conda env create -f base.yml
    • Verify that the virtual environment was created correctly.
      conda info --envs
    • Activate the virtual environment.
      conda activate cm_base
  4. Migrate and update the SQLite database. Currently, running ./manage.py makemigrations makes migrations and scrapes the web since there is no automated scraping capability.
    ./manage.py makemigrations
    ./manage.py migrate
  5. Start the development server.
    ./manage.py runserver

Updating dependencies

  1. Update dependencies under pip in base.yml.
  2. Deactivate the virtual environment if it is currently running.
    conda deactivate
  3. Update the virtual environment.
    • If you are removing a dependency, removing and recreating the virtual environment is necessary since --prune does not work as of August 9 2023.
      conda remove --name cm_base --all
      conda env create -f base.yml
    • Otherwise, update the virtual environment as normal.
      conda env update -f base.yml
  4. Verify that the virtual environment was updated correctly.
    conda info --envs
  5. Activate the virtual environment.
    conda activate cm_base
  6. Verify that the new dependency was added to the virtual environment.
    pip list --local

Resources

clean-marine's People

Contributors

ajtadeo avatar tylerdtran avatar awest25 avatar colleenhlam avatar

clean-marine's Issues

Change SQLite DB to PostgreSQL

right now the DB is kinda disorganized and I don't understand it. need to start from scratch to recreate it in psql so i can figure out how the backend works

Fix invoke commands for Dockerized apps

The web app functions correctly, however the invoke commands are not working.

  • invoke scrape fails because Selenium must be added as a service in compose.yaml
$ invoke scrape
Starting Surfrider web scraper...
/bin/sh: 1: google-chrome: not found
/bin/sh: 1: google-chrome-stable: not found
/bin/sh: 1: google-chrome-beta: not found
/bin/sh: 1: google-chrome-dev: not found
/bin/sh: 1: google-chrome: not found
/bin/sh: 1: google-chrome-stable: not found
/bin/sh: 1: google-chrome-beta: not found
/bin/sh: 1: google-chrome-dev: not found
/bin/sh: 1: google-chrome: not found
/bin/sh: 1: google-chrome-stable: not found
/bin/sh: 1: google-chrome-beta: not found
/bin/sh: 1: google-chrome-dev: not found
[ERROR] The scraping job failed. See exception:
[Errno 13] Permission denied: '/nonexistent'
Done.
  • invoke dump fails because the user cannot write to the isolated Docker file system
$ invoke dump
/bin/bash: line 1: dump.json: Permission denied

Create invoke command to run web scrapers

Right now the web scraper is set to run on ./manage.py makemigrations which makes no sense. need to make a separate command so i can do this manually (or automatically at like 3am?)

Fix Surfrider web scraper

when i run the web scraper i get some weird errors and messages that need to be fixed. this may be solved by recreating the database

Starting the scraping tool
[{'placeid': '', 'eventname': 'Siuslaw Chapter Meeting August', 'organization': 'Surfrider Siuslaw', 'link': 'https://volunteer.surfrider.org/opportunities/Mjvoj0pS3X', 'date_and_time': 'Thu, Aug 10, 2023: 1:00AM-3:00AM GMT', 'location': 'Location: Florence, OR'}, {'placeid': '', 'eventname': 'Net Patrol Cleanups', 'organization': 'Surfrider Kauaʻi', 'link': 'https://volunteer.surfrider.org/opportunities/jHl7fDPvQX', 'date_and_time': 'Thu, Aug 10, 2023: 1:30AM-4:00AM GMT (+ 2 more)', 'location': 'Location: Anahola, HI'}]
failed at latest_event is none
UNIQUE constraint failed: webscraper_events.eventname

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.