diff --git a/.dockerignore b/.dockerignore index 03e373d..e7417b3 100755 --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,15 @@ -react_OLD +.git +.gitignore +.env .venv .vscode -.git -.git* -__pycache__ \ No newline at end of file +.claude +CLAUDE.md +README.md +STATUS_MONITOR_README.md +Dockerfile +docker-compose.yml +notes.txt +react_OLD +__pycache__ +*.pyc diff --git a/.gitignore b/.gitignore index 58d1e7c..084e014 100755 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,5 @@ envs.py status_history.json .claude -CLAUDE.md \ No newline at end of file +CLAUDE.md +.aider* diff --git a/Dockerfile b/Dockerfile index 581693b..b7fb346 100755 --- a/Dockerfile +++ b/Dockerfile @@ -2,13 +2,9 @@ FROM python:3.10-bullseye LABEL maintainer="Andrew Simonson " WORKDIR /app -ADD ./src /app -COPY . . +COPY src/ . -WORKDIR /app/src - -RUN apt-get -yq update && \ - pip install --no-cache-dir -r requirements.txt +RUN pip install --no-cache-dir -r requirements.txt CMD [ "gunicorn", "--bind", "0.0.0.0:8080", "app:app"] diff --git a/README.md b/README.md index a9612ff..9d35853 100755 --- a/README.md +++ b/README.md @@ -7,3 +7,5 @@ So people can see how excellent my coding standards are. * Viruses: not included You gotta uhh `pip3 install -r requirements.txt` and `python3 app.py` that thing + +Docker compose configured to expose at `localhost:8080` diff --git a/docker-compose.yml b/docker-compose.yml index 39a0294..04bdf71 100755 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,3 @@ -version: '3.8' services: portfolio: image: 'asimonson1125/portfolio' @@ -6,3 +5,5 @@ services: context: ./ dockerfile: Dockerfile restart: 'no' + ports: + - 8080:8080 diff --git a/src/app.py b/src/app.py index dc466e9..3228f56 100755 --- a/src/app.py +++ b/src/app.py @@ -7,9 +7,6 @@ from monitor import monitor, SERVICES app = flask.Flask(__name__) -# Start service monitoring -monitor.start_monitoring() - # Add security and caching headers @app.after_request def add_security_headers(response): @@ -32,11 +29,15 @@ def add_security_headers(response): -proj = json.load(open("./static/json/projects.json", "r")) -books = json.load(open("./static/json/books.json", "r")) -skillList = json.load(open("./static/json/skills.json", "r")) -timeline = json.load(open("./static/json/timeline.json", "r")) -pages = json.load(open("./static/json/pages.json", "r")) +def load_json(path): + with open(path, "r") as f: + return json.load(f) + +proj = load_json("./static/json/projects.json") +books = load_json("./static/json/books.json") +skillList = load_json("./static/json/skills.json") +timeline = load_json("./static/json/timeline.json") +pages = load_json("./static/json/pages.json") pages['projects']['skillList'] = skillList # pages['about']['timeline'] = timeline @@ -53,12 +54,13 @@ def api_status(): @app.route('/api/goto/') @app.route('/api/goto/') def goto(location='home'): + if location not in pages: + flask.abort(404) pagevars = pages[location] page = None try: page = flask.render_template(pagevars["template"], var=pagevars) except Exception as e: - # raise e e = HTTPerror.InternalServerError(None, e) page = page404(e) return [pagevars, page] @@ -83,29 +85,45 @@ for i in pages: def resume(): return flask.send_file("./static/Resume_Simonson_Andrew.pdf") -@app.errorhandler(Exception) +@app.errorhandler(HTTPerror.HTTPException) def page404(e): eCode = e.code message = e.description - try: - message = e.length - finally: - pagevars = { - "template": "error.html", - "title": f"{eCode} - Simonson", - "description": "Error on Andrew Simonson's Digital Portfolio", - "canonical": "404", - } - return ( - flask.render_template( - "header.html", - var=pagevars, - error=eCode, - message=message, - title=f"{eCode} - Simonson Portfolio", - ), - eCode, - ) + pagevars = { + "template": "error.html", + "title": f"{eCode} - Simonson", + "description": "Error on Andrew Simonson's Digital Portfolio", + "canonical": "404", + } + return ( + flask.render_template( + "header.html", + var=pagevars, + error=eCode, + message=message, + title=f"{eCode} - Simonson Portfolio", + ), + eCode, + ) + +@app.errorhandler(Exception) +def page500(e): + pagevars = { + "template": "error.html", + "title": "500 - Simonson", + "description": "Error on Andrew Simonson's Digital Portfolio", + "canonical": "404", + } + return ( + flask.render_template( + "header.html", + var=pagevars, + error=500, + message="Internal Server Error", + title="500 - Simonson Portfolio", + ), + 500, + ) @app.route("/sitemap.xml") @@ -121,3 +139,4 @@ if __name__ == "__main__": app.run(debug=False) else: Minify(app=app, html=True, js=True, cssless=True) + monitor.start_monitoring() diff --git a/src/static/js/status.js b/src/static/js/status.js index a69a029..eb19784 100644 --- a/src/static/js/status.js +++ b/src/static/js/status.js @@ -236,10 +236,16 @@ function refreshStatus() { /** * Initialize on page load */ +let statusIntervalId = null; + function initStatusPage() { + // Clear any existing interval from a previous SPA navigation + if (statusIntervalId !== null) { + clearInterval(statusIntervalId); + } fetchStatus(); // Auto-refresh every 5 minutes to get latest data - setInterval(fetchStatus, 300000); + statusIntervalId = setInterval(fetchStatus, 300000); } // Start when page loads diff --git a/src/templates/header.html b/src/templates/header.html index 7f860ba..2eaf366 100755 --- a/src/templates/header.html +++ b/src/templates/header.html @@ -20,7 +20,7 @@ property="og:image" content="{{ url_for('static', filename='icons/rasterLogoCircle.png') }}" /> - + diff --git a/src/templates/partials/project.html b/src/templates/partials/project.html index 454cb8a..412ad97 100755 --- a/src/templates/partials/project.html +++ b/src/templates/partials/project.html @@ -17,13 +17,15 @@

{{ content }}