Skip to content

Commit

Permalink
Add total completed stars header
Browse files Browse the repository at this point in the history
  • Loading branch information
LiquidFun committed Jan 1, 2024
1 parent 2d75ae8 commit 26b9406
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 23 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Add this pre-commit hook to your `.pre-commit-config.yaml` (create it, if you do
```yaml
repos:
- repo: https://github.com/LiquidFun/aoc_tiles
rev: 0.5.6
rev: 0.6.0
hooks:
- id: aoc-tiles
# Optionally use these arguments. Auto add tiles to git adds the tiles to git,
Expand All @@ -46,7 +46,7 @@ repos:
# args:
# - --auto-add-tiles-to-git=amend
# - --language-sorting=jl,kt,py,rs
# - --exclude-patterns="2021/*/*.apl,2021/*/*.py,2021/*/*.cpp"
# - --exclude-patterns=2021/*/*.apl,2021/*/*.py,2021/*/*.cpp
```

Now **install** the hook with:
Expand Down
12 changes: 9 additions & 3 deletions aoc_tiles/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class Config:
"help": "What information to display on the right side of each tile. "
"'checkmark' only displays a checkmark for each part if the day is solved. "
"'time_and_rank' displays the time and rank on the global leaderboard (requires session.cookie). "
"'loc' displays the number of lines of code of the solution (not implemented. "
"'loc' displays the number of lines of code of the solution (not implemented). "
"'auto' will use 'time_and_rank' if session.cookie exists, otherwise 'checkmark'."}
)
count_as_solved_when: Literal["auto", "on_leaderboard", "file_exists", "either", "both"] = field(
Expand All @@ -50,6 +50,11 @@ class Config:
"otherwise all solutions will be used. This is useful for example to ignore auto-generated"
"files, like '.d' in Rust or '.o' files in C++."})

show_total_stars_for_all_years: Literal["no", "auto", "yes"] = field(default="auto", metadata={
"help": "Whether to add an additional header in front which shows the total collected stars for all years."
"'auto' will only show the header if you have stars in at least 3 separate years. "
"'yes' will always show the header. 'no' will never show the header."})

year_pattern: str = field(
default=r"(?<!\d)(20[123]\d)(?!\d)",
metadata={
Expand All @@ -66,8 +71,9 @@ class Config:
"help": "A list of comma separated glob patterns to ignore when looking for solutions. "
"Listing the paths works too. "
"For example: '*.py,*.js', '2023/05/05.c' or '2021/**.py'."
"Make sure to escape the patterns with single quotes when running from the shell and with"
"double quotes when using in the yaml to avoid shell expansion!"
"Make sure to escape the patterns with single quotes when running from the shell! "
"Do NOT escape them when using the flag in the yaml! "
"Otherwise the qoute will be part of the pattern."
}
)

Expand Down
5 changes: 3 additions & 2 deletions aoc_tiles/html.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,9 @@ class HTML:
Originally, this was used a lot more, however at this point it is only needed for a single with statement.
"""

tags: list[str] = []
depth = 0
def __init__(self):
self.tags: list[str] = []
self.depth = 0

def push(self, tag: str, depth=0):
if depth < 0:
Expand Down
56 changes: 41 additions & 15 deletions aoc_tiles/make_tiles.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import re
from concurrent.futures import ProcessPoolExecutor
from dataclasses import dataclass
import datetime
from pathlib import Path
from typing import Dict, Set, List, Optional, Any

Expand Down Expand Up @@ -102,11 +103,10 @@ def fill_empty_days_in_dict(self, day_to_solutions: Dict[int, List[Path]], max_d
if day not in day_to_solutions:
day_to_solutions[day] = []

def handle_year(self, year: int, year_data: YearData):
def handle_year(self, year: int, year_data: YearData, html: HTML):
print(f"=== Generating table for year {year} ===")
leaderboard = year_data.day_to_scores
day_to_solutions = year_data.day_to_paths
html = HTML()
with html.tag("h1", align="center"):
stars = sum(year_data.day_to_stars.values())
html.push(f"{year} - {stars} ⭐")
Expand All @@ -132,11 +132,11 @@ def handle_year(self, year: int, year_data: YearData):
tile_path, solution_path = future.result()

if solution_path is None:
sol_path = str(solution_path)
solution_href = str(solution_path)
else:
sol_path = str(solution_path.as_posix())
solution_href = str(solution_path.as_posix())

with html.tag("a", href=sol_path):
with html.tag("a", href=solution_href):
html.tag("img", closing=False, src=tile_path.as_posix(), width=self.config.tile_width_px)

# with open(completed_cache_path, "w") as file:
Expand All @@ -145,6 +145,13 @@ def handle_year(self, year: int, year_data: YearData):
# json.dumps({day: solutions for day, solutions in day_to_solutions.items() if day in completed_days})
# )

def _ensure_is_not_running_already(self):
if self.config.aoc_tiles_dir.exists():
if self.config.running_lock_path in self.config.aoc_tiles_dir.iterdir():
print("AoC-Tiles is already running! Remove running.lock if this is not the case.")
exit()

def _write_to_readme(self, html: HTML):
with open(self.config.readme_path, "r", encoding="utf-8") as file:
text = file.read()
begin = README_TILES_BEGIN
Expand All @@ -159,33 +166,52 @@ def handle_year(self, year: int, year_data: YearData):
with open(self.config.readme_path, "w", encoding="utf-8") as file:
file.write(str(new_text))

def _ensure_is_not_running_already(self):
if self.config.aoc_tiles_dir.exists():
if self.config.running_lock_path in self.config.aoc_tiles_dir.iterdir():
print("AoC-Tiles is already running! Remove running.lock if this is not the case.")
exit()
@staticmethod
def _get_total_possible_stars_for_date(utc_date: datetime.datetime):
total = 0
for year in range(2015, utc_date.year + 2):
for day in range(1, 26):
unlock_time = datetime.datetime(year, 12, day, 0, 0, 0, 0, tzinfo=datetime.UTC)
if utc_date >= unlock_time:
total += 2
return total

def _add_total_completed_stars_to_html(self, solve_data: SolveData, html: HTML):
add_header = self.config.show_total_stars_for_all_years == 'yes' \
or self.config.show_total_stars_for_all_years == 'auto' and len(solve_data.year_to_data) >= 3
if add_header:
total_stars = sum(sum(data.day_to_stars.values()) for data in solve_data.year_to_data.values())
total_possible_stars = self._get_total_possible_stars_for_date(datetime.datetime.now(datetime.UTC))
with html.tag("h1", align="center"):
html.push(f"Advent of Code - {total_stars}/{total_possible_stars} ⭐")

def make_tiles(self):
self._ensure_is_not_running_already()
print("Running AoC-Tiles")
solve_data = self.compose_solve_data()
logger.info("Found {} years with solutions", len(solve_data.year_to_data))
html = HTML()
self._add_total_completed_stars_to_html(solve_data, html)

for year, data in sorted(solve_data.year_to_data.items(), reverse=True):
logger.debug("year={} data={}", year, data)
self.handle_year(year, data)
self.handle_year(year, data, html)

self._write_to_readme(html)

if self.config.auto_add_tiles_to_git in ["add", "amend"]:
self.solution_finder.git_add(self.config.image_dir)
self.solution_finder.git_add(self.config.readme_path)

if self.config.auto_add_tiles_to_git in ["amend"]:
with open(self.config.running_lock_path, "w") as file:
file.write("")
try:
with open(self.config.running_lock_path, "w") as file:
file.write("")
self.solution_finder.git_commit_amend()
finally:
print("Could not amend commit. Maybe there is nothing to amend?")
self.config.running_lock_path.unlink()
# print("Could not amend commit. Maybe there is nothing to amend?")
if self.config.running_lock_path.exists():
self.config.running_lock_path.unlink()


def main():
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "aoc-tiles"
version = "0.5.6"
version = "0.6.0"
description = "Fancy Advent of Code README tiles showing the completion status of the challenges per day"
authors = ["Brutenis Gliwa, <[email protected]>"]
license = "Apache-2.0"
Expand Down

0 comments on commit 26b9406

Please sign in to comment.