Skip to content

Commit

Permalink
Merge pull request #1 from larsvantol/production-ready
Browse files Browse the repository at this point in the history
Code cleanup and making it production ready
  • Loading branch information
larsvantol authored Nov 25, 2024
2 parents 04c9ca4 + 14e1d1b commit 1dbf793
Show file tree
Hide file tree
Showing 13 changed files with 735 additions and 495 deletions.
49 changes: 40 additions & 9 deletions app.py → AoCH/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
from datetime import datetime, timedelta

import requests
from dotenv import load_dotenv
from flask import Flask, render_template, render_template_string
from flask import Blueprint, Flask, render_template, render_template_string
from flask_cors import CORS

load_dotenv()
import logging

app = Flask(__name__)
CORS(app)

logger = logging.getLogger('aoch')
logger.setLevel(logging.INFO)
bp = Blueprint('aoch', __name__)

data = {}
# the two below variables are used to keep track of when was last pulled, so we do not overload the Advent of Code servers
Expand All @@ -35,6 +36,20 @@
}


def create_app():
cur_folder = os.path.dirname(os.path.realpath(__file__))
app = Flask(__name__,
static_url_path='',
static_folder=os.path.join(cur_folder, '../static'),
template_folder=os.path.join(cur_folder, '../templates'))
CORS(app)

app.register_blueprint(bp)
app.add_url_rule('/', endpoint='index')

return app


def current_time() -> tuple[int, int, int]:
"""
Returns the current day, month, and year in a tuple of strings.
Expand Down Expand Up @@ -70,10 +85,11 @@ def get_data(today: tuple[int, int, int]):
if (now - last_pull) < timedelta(minutes=15):
return data

app.logger.info("Pulling new data from Advent of Code!")
logger.info("Pulling new data from Advent of Code!")

url = f"https://adventofcode.com/{this_year}/leaderboard/private/view/{leaderboard_id}.json"
response = requests.get(url, headers=headers, timeout=5)
logger.info(f'Getting data for {this_year}, response: {response.status_code}')
data = response.json()
last_pull = now
return data
Expand All @@ -100,6 +116,7 @@ def get_day_assignment(today: tuple[int, int, int]):

url = f"https://adventofcode.com/{this_year}/day/{this_day}"
response = requests.get(url, headers=headers, timeout=5)
logger.info(f'Getting challenge for {this_day}-{this_month}-{this_year}, response: {response.status_code}')
assignment["puzzle"] = response.text
assignment["last_pulled"] = datetime(year=this_year, month=this_month, day=this_day)
return response.text
Expand Down Expand Up @@ -217,7 +234,7 @@ def return_global_data(members):
return global_data


@app.route("/data")
@bp.route("/data")
def return_data():
"""
Endpoint for the frontend.
Expand All @@ -235,7 +252,20 @@ def return_data():
return data


@app.route("/")
@bp.route("/challenge")
def return_challenge():
return render_template("challenge.html")

@bp.route("/leaderboard")
def return_leaderboard():
return render_template("leaderboard.html")

@bp.route("/leaderboard/today")
def return_leaderboard_today():
return render_template("leaderboard_today.html")


@bp.route("/")
def return_index():
"""
Endpoint for the frontend.
Expand All @@ -244,4 +274,5 @@ def return_index():


if __name__ == "__main__":
app.run(port=5000, debug=True)
app = create_app()
app.run()
15 changes: 15 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM python:3-alpine as build
RUN pip install --upgrade pip

RUN mkdir /app
COPY requirements.txt /app
COPY pyproject.toml /app
COPY AoCH/ /app/AoCH/
COPY static/ /app/static/
COPY templates/ /app/templates/

WORKDIR /app
RUN python -m pip install -r requirements.txt

EXPOSE 8080:8080
CMD ["waitress-serve", "--call", "AoCH:create_app"]
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ This project shows the current statistics and leaderboard of CH members for the

This script follows the guidelines stated by [Advent of Code](https://www.reddit.com/r/adventofcode/wiki/faqs/automation), namely:
- it includes the emails of the maintainers and a link to the current repo in the User-Agent header for all outbound requests;
- it throttles the requests made to the website by only requesting (private) leaderboard updates every 15 minutes (`L55: get_data()`);
- the puzzle for each day is requested only once and 'cached' runtime only, so restarting the server removes the 'cache' (`L79: get_day_assignment()`).
- it throttles the requests made to the website by only requesting (private) leaderboard updates every 15 minutes (`L68: get_data()`);
- the puzzle for each day is requested only once and 'cached' runtime only, so restarting the server removes the 'cache' (`L93: get_day_assignment()`).

Do not misuse this leaderboard we created and if you decide to fork this repository, please update the User-Agent to your own email and repository.

Expand Down Expand Up @@ -55,8 +55,12 @@ pip install -r requirements.txt

### 4. Adding environmental variables

Create a `.env` file in the project folder. Add the following two variables: `session` and `leaderboard_id`. `session` is the cookie stored by AoC if you authenticate in the browser (valid for a month) and `leaderboard_id` can be found in the url of the leaderboard you are trying to add.
Configuration of the leaderboard is stored in environment variables. Add the following two variables: `session` and `leaderboard_id`. `session` is the cookie stored by AoC if you authenticate in the browser (valid for a month) and `leaderboard_id` can be found in the url of the leaderboard you are trying to add.

### 5. Start the server

Start the server by running the `app.py` file. If the server has started, you can go to `localhost:5000` in your browser.
Start the server by running the application with `waitress`, e.g. `session=<SESSION> leaderboard_id=<LEADERBOARD_ID> waitress-serve --call AoCH:create_app`

## Docker

The project can also be run using the provided `Dockerfile` for this, simply build the docker image, `docker build -t aoch .` and run it: `docker run aoch`.
46 changes: 0 additions & 46 deletions get_json.js

This file was deleted.

15 changes: 15 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
[project]
name = "AoCH"
version = "2024.0.0"
description = "Advent of Code leaderboard for in CH"
dependencies = [
"flask",
"requests",
]

[build-system]
requires = ["flit_core<4"]
build-backend = "flit_core.buildapi"

[tool.flit.sdist]
include = ["static/", "templates/"]
27 changes: 13 additions & 14 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
blinker==1.7.0
certifi==2023.11.17
charset-normalizer==3.3.2
blinker==1.9.0
certifi==2024.8.30
charset-normalizer==3.4.0
click==8.1.7
colorama==0.4.6
Flask==3.0.0
Flask-Cors==4.0.0
idna==3.6
itsdangerous==2.1.2
Jinja2==3.1.2
MarkupSafe==2.1.3
python-dotenv==1.0.0
requests==2.31.0
urllib3==2.1.0
Werkzeug==3.0.1
Flask==3.1.0
Flask-Cors==5.0.0
idna==3.10
itsdangerous==2.2.0
Jinja2==3.1.4
MarkupSafe==3.0.2
requests==2.32.3
urllib3==2.2.3
waitress==3.0.2
Werkzeug==3.1.3
Loading

0 comments on commit 1dbf793

Please sign in to comment.