From 7232d1f8deb0c0a5185aa0d5c8d6c2a240151962 Mon Sep 17 00:00:00 2001 From: Andrew Simonson Date: Fri, 20 Feb 2026 22:23:25 -0600 Subject: [PATCH] formalizing --- README.md | 97 ++++++++++++++++++++++++++++++++++--- src/static/js/responsive.js | 3 -- 2 files changed, 89 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 9d35853..4a99d49 100755 --- a/README.md +++ b/README.md @@ -1,11 +1,92 @@ -# I made a uhh website -So people can see how excellent my coding standards are. +# Personal Portfolio & Service Monitor -* Style: 5/10 -* Originality: 3/10 -* Security: Yes* -* Viruses: not included +A Flask-based website for my personal portfolio and a service monitoring dashboard. This project handles dynamic project showcases, automated service health tracking, and production-ready optimizations. -You gotta uhh `pip3 install -r requirements.txt` and `python3 app.py` that thing +## Features -Docker compose configured to expose at `localhost:8080` +- **Content Management**: Pages like projects, books, and skills are managed via JSON files in the `static` directory. +- **Service Monitoring**: Background health checks for external services with uptime statistics stored in PostgreSQL. +- **Optimizations**: + - HTML, CSS, and JS minification via `Flask-Minify`. + - MD5-based cache busting for static assets. + - Configurable cache-control headers. +- **Security**: Pre-configured headers for XSS protection and frame security. +- **Deployment**: Ready for containerized deployment with Docker and Gunicorn. + +## Tech Stack + +- **Backend**: Python 3.12, Flask +- **Frontend**: Vanilla CSS/JS, Jinja2 +- **Database**: PostgreSQL (optional, for monitoring history) +- **Infrastructure**: Docker, docker-compose + +## Project Structure + +```text +. +├── src/ +│ ├── app.py # Application entry point +│ ├── monitor.py # Service monitoring logic +│ ├── config.py # Environment configuration +│ ├── templates/ # HTML templates +│ ├── static/ # CSS, JS, and JSON data +│ └── requirements.txt # Python dependencies +├── Dockerfile # Container definition +├── docker-compose.yml # Local stack orchestration +└── STATUS_MONITOR_README.md # Monitoring system documentation +``` + +## Getting Started + +### Using Docker + +To run the full stack (App + PostgreSQL): + +1. **Clone the repository**: + ```bash + git clone https://github.com/asimonson1125/asimonson1125.github.io.git + cd asimonson1125.github.io + ``` + +2. **Start services**: + ```bash + docker-compose up --build + ``` + +3. **Access the site**: + Visit [http://localhost:8080](http://localhost:8080). + +### Local Development + +To run the Flask app without Docker: + +1. **Set up a virtual environment**: + ```bash + python3 -m venv .venv + source .venv/bin/activate + ``` + +2. **Install dependencies**: + ```bash + pip install -r src/requirements.txt + ``` + +3. **Run the application**: + ```bash + cd src + python3 app.py + ``` + *Note: status monitor is by default disabled outside of its container cluster* + +## Service Monitoring + +The monitoring system in `src/monitor.py` tracks service availability. It: +- Runs concurrent health checks every hour. +- Calculates uptime for various windows (24h, 7d, 30d). +- Provides a status UI at `/status` and a JSON API at `/api/status`. + +See [STATUS_MONITOR_README.md](./STATUS_MONITOR_README.md) for more details. + +## License + +This project is personal property. All rights reserved. diff --git a/src/static/js/responsive.js b/src/static/js/responsive.js index 8a6e62e..a4d9b32 100755 --- a/src/static/js/responsive.js +++ b/src/static/js/responsive.js @@ -15,7 +15,6 @@ function toggleMenu(collapse) { async function goto(location, { push = true } = {}) { const loadingBar = document.getElementById('loading-bar'); - console.log(`Navigating to ${location}`); if (loadingBar) { loadingBar.style.width = ''; // Clear inline style from previous run @@ -23,7 +22,6 @@ async function goto(location, { push = true } = {}) { let loadingTimeout = setTimeout(() => { if (loadingBar) { - console.log("Navigation taking > 150ms, showing bar"); loadingBar.classList.remove('finish'); loadingBar.classList.add('active'); loadingBar.classList.add('visible'); @@ -78,7 +76,6 @@ async function goto(location, { push = true } = {}) { } finally { clearTimeout(loadingTimeout); if (loadingBar && loadingBar.classList.contains('active')) { - console.log("Navigation finished, hiding bar"); loadingBar.classList.add('finish'); loadingBar.classList.remove('active'); setTimeout(() => {