diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..de288e1 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "python.formatting.provider": "black" +} \ No newline at end of file diff --git a/src/app.py b/src/app.py index 5d402ed..903cfbc 100644 --- a/src/app.py +++ b/src/app.py @@ -1,19 +1,50 @@ import flask +from flask_minify import Minify +import json + +proj = json.load(open('./static/json/projects.json', 'r')) +timeline = json.load(open('./static/json/timeline.json', 'r')) app = flask.Flask(__name__) +Minify(app=app, html=True, js=True, cssless=True) -@app.route('/') + +@app.route("/") def home(): - return flask.render_template('home.html', title='Andrew Simonson - Portfolio Home', description="Andrew Simonson's Digital portfolio home", canonical='') + return flask.render_template( + "home.html", + title="Andrew Simonson - Portfolio Home", + description="Andrew Simonson's Digital portfolio home", + canonical="", + ) -@app.route('/about') + +@app.route("/about") def about(): - return flask.render_template('about.html', title='Andrew Simonson - About Me', description="About Andrew Simonson", canonical='about') + return flask.render_template( + "about.html", + timeline=timeline, + title="Andrew Simonson - About Me", + description="About Andrew Simonson", + canonical="about", + ) -@app.route('/resume') -@app.route('/Resume.pdf') + +@app.route("/projects") +def projects(): + return flask.render_template( + "projects.html", + projects=proj, + title="Andrew Simonson - Projects", + description="Recent projects by Andrew Simonson on his lovely portfolio website :)", + canonical="projects", + ) + + +@app.route("/resume") +@app.route("/Resume.pdf") def resume(): - return flask.send_file('./static/resume.pdf') + return flask.send_file("./static/Resume.pdf") @app.errorhandler(Exception) @@ -23,14 +54,25 @@ def page404(e): try: message = e.length finally: - return flask.render_template('error.html', error=eCode, message=message, title=f'{eCode} - Simonson Portfolio'), eCode + return ( + flask.render_template( + "error.html", + error=eCode, + message=message, + title=f"{eCode} - Simonson Portfolio", + ), + eCode, + ) -@app.route('/sitemap.xml') -@app.route('/robots.txt') + +@app.route("/sitemap.xml") +@app.route("/robots.txt") def static_from_root(): return flask.send_from_directory(app.static_folder, flask.request.path[1:]) -if __name__ == '__main__': + +if __name__ == "__main__": import sass - sass.compile(dirname=('static/scss', 'static/css'), output_style='compressed') - app.run() + + sass.compile(dirname=("static/scss", "static/css"), output_style="compressed") + app.run(debug=True) diff --git a/src/requirements.txt b/src/requirements.txt index 092dc06..1246f6b 100644 Binary files a/src/requirements.txt and b/src/requirements.txt differ diff --git a/src/static/css/head.css b/src/static/css/head.css index c13cb41..17ee26a 100644 --- a/src/static/css/head.css +++ b/src/static/css/head.css @@ -1 +1 @@ -.line:not(:first-child){position:absolute;top:0;left:0}.line:nth-child(1){animation:clip 6000ms -600ms linear infinite,glitch1 2500ms -229ms linear infinite}@keyframes glitch1{0%{transform:translateX(0)}96%{transform:translateX(0);color:#fff}97%{transform:translateX(-2px);color:#4E9A26}98%{transform:translateX(-2px);color:#AC1212}99%{transform:translateX(-3px);color:#fff}100%{transform:translateX(0)}}.line:nth-child(2){animation:clip 6000ms -1200ms linear infinite,glitch2 2500ms -409ms linear infinite}@keyframes glitch2{0%{transform:translateX(0)}96%{transform:translateX(0);color:#fff}97%{transform:translateX(3px);color:#4E9A26}98%{transform:translateX(0px);color:#AC1212}99%{transform:translateX(-3px);color:#fff}100%{transform:translateX(0)}}.line:nth-child(3){animation:clip 6000ms -1800ms linear infinite,glitch3 2500ms -39ms linear infinite}@keyframes glitch3{0%{transform:translateX(0)}96%{transform:translateX(0);color:#fff}97%{transform:translateX(1px);color:#4E9A26}98%{transform:translateX(5px);color:#AC1212}99%{transform:translateX(5px);color:#fff}100%{transform:translateX(0)}}.line:nth-child(4){animation:clip 6000ms -2400ms linear infinite,glitch4 2500ms -854ms linear infinite}@keyframes glitch4{0%{transform:translateX(0)}96%{transform:translateX(0);color:#fff}97%{transform:translateX(-2px);color:#4E9A26}98%{transform:translateX(2px);color:#AC1212}99%{transform:translateX(2px);color:#fff}100%{transform:translateX(0)}}.line:nth-child(5){animation:clip 6000ms -3000ms linear infinite,glitch5 2500ms -718ms linear infinite}@keyframes glitch5{0%{transform:translateX(0)}96%{transform:translateX(0);color:#fff}97%{transform:translateX(-3px);color:#4E9A26}98%{transform:translateX(4px);color:#AC1212}99%{transform:translateX(0px);color:#fff}100%{transform:translateX(0)}}.line:nth-child(6){animation:clip 6000ms -3600ms linear infinite,glitch6 2500ms -628ms linear infinite}@keyframes glitch6{0%{transform:translateX(0)}96%{transform:translateX(0);color:#fff}97%{transform:translateX(2px);color:#4E9A26}98%{transform:translateX(-2px);color:#AC1212}99%{transform:translateX(1px);color:#fff}100%{transform:translateX(0)}}.line:nth-child(7){animation:clip 6000ms -4200ms linear infinite,glitch7 2500ms -227ms linear infinite}@keyframes glitch7{0%{transform:translateX(0)}96%{transform:translateX(0);color:#fff}97%{transform:translateX(0px);color:#4E9A26}98%{transform:translateX(5px);color:#AC1212}99%{transform:translateX(0px);color:#fff}100%{transform:translateX(0)}}.line:nth-child(8){animation:clip 6000ms -4800ms linear infinite,glitch8 2500ms -464ms linear infinite}@keyframes glitch8{0%{transform:translateX(0)}96%{transform:translateX(0);color:#fff}97%{transform:translateX(-3px);color:#4E9A26}98%{transform:translateX(4px);color:#AC1212}99%{transform:translateX(5px);color:#fff}100%{transform:translateX(0)}}.line:nth-child(9){animation:clip 6000ms -5400ms linear infinite,glitch9 2500ms -567ms linear infinite}@keyframes glitch9{0%{transform:translateX(0)}96%{transform:translateX(0);color:#fff}97%{transform:translateX(0px);color:#4E9A26}98%{transform:translateX(-2px);color:#AC1212}99%{transform:translateX(-4px);color:#fff}100%{transform:translateX(0)}}.line:nth-child(10){animation:clip 6000ms -6000ms linear infinite,glitch10 2500ms -876ms linear infinite}@keyframes glitch10{0%{transform:translateX(0)}96%{transform:translateX(0);color:#fff}97%{transform:translateX(-1px);color:#4E9A26}98%{transform:translateX(5px);color:#AC1212}99%{transform:translateX(-4px);color:#fff}100%{transform:translateX(0)}}@keyframes clip{0%{clip-path:polygon(0 100%, 100% 100%, 100% 120%, 0 120%)}100%{clip-path:polygon(0 -20%, 100% -20%, 100% 0%, 0 0)}} +.line:not(:first-child){position:absolute;top:0;left:0}.line:nth-child(1){animation:clip 6000ms -600ms linear infinite,glitch1 2500ms -433ms linear infinite}@keyframes glitch1{0%{transform:translateX(0)}96%{transform:translateX(0);color:#fff}97%{transform:translateX(-1px);color:#4E9A26}98%{transform:translateX(4px);color:#AC1212}99%{transform:translateX(-1px);color:#fff}100%{transform:translateX(0)}}.line:nth-child(2){animation:clip 6000ms -1200ms linear infinite,glitch2 2500ms -234ms linear infinite}@keyframes glitch2{0%{transform:translateX(0)}96%{transform:translateX(0);color:#fff}97%{transform:translateX(-2px);color:#4E9A26}98%{transform:translateX(-1px);color:#AC1212}99%{transform:translateX(5px);color:#fff}100%{transform:translateX(0)}}.line:nth-child(3){animation:clip 6000ms -1800ms linear infinite,glitch3 2500ms -189ms linear infinite}@keyframes glitch3{0%{transform:translateX(0)}96%{transform:translateX(0);color:#fff}97%{transform:translateX(-4px);color:#4E9A26}98%{transform:translateX(2px);color:#AC1212}99%{transform:translateX(-2px);color:#fff}100%{transform:translateX(0)}}.line:nth-child(4){animation:clip 6000ms -2400ms linear infinite,glitch4 2500ms -105ms linear infinite}@keyframes glitch4{0%{transform:translateX(0)}96%{transform:translateX(0);color:#fff}97%{transform:translateX(-3px);color:#4E9A26}98%{transform:translateX(4px);color:#AC1212}99%{transform:translateX(1px);color:#fff}100%{transform:translateX(0)}}.line:nth-child(5){animation:clip 6000ms -3000ms linear infinite,glitch5 2500ms -89ms linear infinite}@keyframes glitch5{0%{transform:translateX(0)}96%{transform:translateX(0);color:#fff}97%{transform:translateX(-2px);color:#4E9A26}98%{transform:translateX(-2px);color:#AC1212}99%{transform:translateX(3px);color:#fff}100%{transform:translateX(0)}}.line:nth-child(6){animation:clip 6000ms -3600ms linear infinite,glitch6 2500ms -936ms linear infinite}@keyframes glitch6{0%{transform:translateX(0)}96%{transform:translateX(0);color:#fff}97%{transform:translateX(3px);color:#4E9A26}98%{transform:translateX(-4px);color:#AC1212}99%{transform:translateX(0px);color:#fff}100%{transform:translateX(0)}}.line:nth-child(7){animation:clip 6000ms -4200ms linear infinite,glitch7 2500ms -594ms linear infinite}@keyframes glitch7{0%{transform:translateX(0)}96%{transform:translateX(0);color:#fff}97%{transform:translateX(1px);color:#4E9A26}98%{transform:translateX(5px);color:#AC1212}99%{transform:translateX(-3px);color:#fff}100%{transform:translateX(0)}}.line:nth-child(8){animation:clip 6000ms -4800ms linear infinite,glitch8 2500ms -464ms linear infinite}@keyframes glitch8{0%{transform:translateX(0)}96%{transform:translateX(0);color:#fff}97%{transform:translateX(-2px);color:#4E9A26}98%{transform:translateX(5px);color:#AC1212}99%{transform:translateX(1px);color:#fff}100%{transform:translateX(0)}}.line:nth-child(9){animation:clip 6000ms -5400ms linear infinite,glitch9 2500ms -520ms linear infinite}@keyframes glitch9{0%{transform:translateX(0)}96%{transform:translateX(0);color:#fff}97%{transform:translateX(3px);color:#4E9A26}98%{transform:translateX(-2px);color:#AC1212}99%{transform:translateX(3px);color:#fff}100%{transform:translateX(0)}}.line:nth-child(10){animation:clip 6000ms -6000ms linear infinite,glitch10 2500ms -463ms linear infinite}@keyframes glitch10{0%{transform:translateX(0)}96%{transform:translateX(0);color:#fff}97%{transform:translateX(1px);color:#4E9A26}98%{transform:translateX(1px);color:#AC1212}99%{transform:translateX(-3px);color:#fff}100%{transform:translateX(0)}}@keyframes clip{0%{clip-path:polygon(0 100%, 100% 100%, 100% 120%, 0 120%)}100%{clip-path:polygon(0 -20%, 100% -20%, 100% 0%, 0 0)}} diff --git a/src/static/json/projects.json b/src/static/json/projects.json new file mode 100644 index 0000000..46eb7c9 --- /dev/null +++ b/src/static/json/projects.json @@ -0,0 +1,117 @@ +{ + "Lower 48 Alt. Energy Map": { + "status": "complete", + "classes": "pinned geospacial", + "bgi": "geovisF.png", + "content": "ArcGIS Map of the most effective alternative energy sources in the continental United States", + "links": [ + [ + "globe", + "https://ritarcgis.maps.arcgis.com/apps/dashboards/17d5bda01edc4a2eb6205a4922d889c9", + "ArcGIS" + ] + ] + }, + "OccupyRIT": { + "status": "WIP", + "classes": "pinned programming", + "bgi": "occupyRIT.png", + "content": "Collects RIT Gym Occupancy data, determining busiest workout times", + "links": [ + ["github", "https://github.com/asimonson1125/Occupy-RIT", "git repo"] + ] + }, + "Chesscom Embeds": { + "status": "complete", + "classes": "programming", + "bgi": "chessbed.png", + "content": "A template for creating Chess.com user profile embeds", + "links": [ + ["github", "https://github.com/asimonson1125/chesscom-embed", "git repo"] + ] + }, + "Resume": { + "status": "WIP", + "classes": "programming", + "bgi": "resume.png", + "content": "My Resume, made in LaTeX with a custom design derived by the AltaCV template on OverLeaf", + "links": [ + ["github", "https://github.com/asimonson1125/Resume", "git repo"], + ["globe", "https://asimonson.com/Resume.pdf/", "Resume"] + ] + }, + "Digital Portfolio": { + "status": "WIP", + "classes": "programming", + "bgi": "website.png", + "content": "My personal portfolio website (you're on it now!)", + "links": [ + ["github", "https://github.com/asimonson1125/asimonson1125.github.io", "git repo"], + ["globe", "https://asimonson.com", "site link"] + ] + }, + "Slate": { + "status": "complete", + "classes": "pinned programming", + "bgi": "slate.png", + "content": "Slate is a web app designed to help event coordinators schedule events by congregating participant calendar data. Includes Computer Science House account integration", + "links": [ + ["github", "https://github.com/asimonson1125/Slate", "git repo"], + ["globe", "https://slate.csh.rit.edu", "site link"] + ] + }, + "HvZ Bot": { + "status": "complete", + "classes": "programming", + "bgi": "", + "content": "A Discord bot to handle role management and statistics for RIT's Humans vs. Zombies games", + "links": [ + ["github", "https://github.com/asimonson1125/HvZ-bot", "git repo"] + ] + }, + "FinTech": { + "status": "WIP", + "classes": "pinned programming", + "bgi": "", + "content": "A team derived from the RIT Financial Management Association dedicated to learning about financial management of equities using automated solutions developed by students", + "links": [ + ["github", "https://github.com/LukeHorigan/Financial-Management-Assocation-", "git repo"] + ] + }, + "Browser Trivia Bot": { + "status": "complete", + "classes": "programming", + "bgi": "", + "content": "A tampermonkey tool used to automatically answer and submit online trivia forms, which can be tailored to different site layouts. Source currently private.", + "links": [ + ] + }, + "NationsGame Rolls Sim": { + "status": "complete", + "classes": "programming", + "bgi": "ceoOfYugo.png", + "content": "A simulator for the browser game, NationsGame, to analyze unit composition and predict in-game victors and unit statistics. Unfortunately, NationsGame is now defunct. Limited screenshots of functionality.", + "links": [ + ["github", "https://github.com/asimonson1125/NG-Rolls-Simulator", "git repo"] + ] + }, + "VEXcode Button Engine": { + "status": "complete", + "classes": "programming", + "bgi": "vexcodeButtons.jpeg", + "content": "VEXcode button library + examples and template for the VEX V5 brain", + "links": [ + ["github", "https://github.com/asimonson1125/VEXcode-Button-Generator", "git repo"], + ["globe", "https://www.vexforum.com/t/vexcode-button-generator/72450", "Forum post"] + ] + }, + "WinKeylogger": { + "status": "complete", + "classes": "programming", + "bgi": "", + "content": "A C++ keylogger for windows based off a Udemy course with my custom modifications and powershell script", + "links": [ + ["github", "https://github.com/asimonson1125/WinKeylogger", "git repo"] + ] + } +} diff --git a/src/static/json/timeline.json b/src/static/json/timeline.json new file mode 100644 index 0000000..6159c88 --- /dev/null +++ b/src/static/json/timeline.json @@ -0,0 +1,37 @@ +{ + "Co-op @ Dow Chemical": { + "classes": "pinned experience technical", + "date": "01/2023 - 05/2023", + "content": "Spring 2023 Semester Co-op under Dow Chemical's Global Reactive Chemicals team in Analytical Sciences. Responsibilities included management of chemical compatability data and tool creation for parsing, generating, and submitting reports." + }, + "Started Portfolio": { + "classes": "", + "date": "08/26/2021", + "content": "I started building this website on this day. I wish I could say I was farther along than I am." + }, + "Rochester Institute of Technology": { + "classes": "pinned education technical", + "date": "08/2021 - 05/2025", + "content": "Studying in Rochester Institute of Technology's Computer Science BS program with a minor in International Relations." + }, + "Pretzel & Pizza Creations": { + "classes": "experience", + "date": "04/2021 - 08/2021", + "content": "Worked part-time as a chef, managing active ingredient supply and fulfilling orders. I personally recommend the stuffed pretzels." + }, + "Election Official": { + "classes": "experience", + "date": "08/2020 - 12/2020", + "content": "Trained in voter registry operations and provisional voting by the Washington County Board of Elections for the 2020 US Presidential Election." + }, + "Boonsboro High School": { + "classes": "education", + "date": "09/2016 - 06/2021", + "content": "Graduated high school with highest honors.\nMember of National Honor Society, Academic Team County Champions. Participated in Physics Olympics, Robotics Club, and scored at state championships in Cross Country and Track and Field (4x800, 800)." + }, + "Vex Robotics Team Lead/Club Preisdent": { + "classes": "technical", + "date": "10/2015 - 04/2021", + "content": "Led 5 teams through middle and high school to VEX Robotics Competitions, elevating Boonsboro from county group-stage elimination to its first state championship participation. Reorganized club and set up its first interface with the community + sponsors" + } +} diff --git a/src/templates/about.html b/src/templates/about.html new file mode 100644 index 0000000..8b5b006 --- /dev/null +++ b/src/templates/about.html @@ -0,0 +1,131 @@ +{% extends "header.html" %} {% block content %} +
+ I'm Andrew Simonson, a second year (third year standing) student at + Rochester Institute of Technology + in the Computer Science BS program, pursuing a career in data + science with a focus on predictive analytics. +
++ When I'm not in class, you can find me working on extra collaborative + projects, building discord bots, playing chess, reading up on some + recent geopolitical development, or haphazardly expanding my list of + unusable, yet bizzarely wise quotes. +
+ +