Files

77 lines
3.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""The summary printed when ctf_status.py runs in a terminal."""
from __future__ import annotations
from collections import Counter
from .challenge import BLOCKED_ICON, SELECTIONS, STATUS_ICON, STATUS_ORDER
from .overview import Overview, icons
BOLD, DIM, RED, YEL, GRN, CYA, RST = (
"\033[1m", "\033[2m", "\033[31m", "\033[33m", "\033[32m", "\033[36m", "\033[0m")
def print_terminal(ov: Overview, c: bool) -> None:
def col(x): return x if c else ""
stages = ov.stages
groups = ov.by_category()
total = Counter(ch.stage for ch in ov.challenges)
print(f"\n{col(BOLD)}=== {len(ov.challenges)} challenges ==={col(RST)} "
+ " ".join(f"{STATUS_ICON[s]} {s or '?'}:{total[s]}" for s in stages if total[s]))
ready = ov.testable
print(f"\n{col(BOLD)}{col(GRN)}=== ready for infra testing ({len(ready)}) ==={col(RST)}")
for ch in ready:
print(f" {STATUS_ICON[ch.stage]} {ch.title[:34]:<35}{ch.category or '?':<10}"
f"{ch.difficulty or '?':<13}{col(DIM)}{ch.repo.web_url}{col(RST)}")
if ov.blocked:
print(f"\n{col(BOLD)}{col(RED)}=== {BLOCKED_ICON} claims {STATUS_ORDER[2]}+, "
f"but the repo disagrees ({len(ov.blocked)}) ==={col(RST)}")
for ch in ov.blocked:
print(f" {STATUS_ICON[ch.stage]} {ch.title[:34]:<35}{col(DIM)}"
+ "; ".join(ch.blockers) + col(RST))
print(f"\n{col(BOLD)}=== status by category ==={col(RST)}")
print(f" {'':<10}" + "".join(f"{s or '?':>14}" for s in stages) + f"{'total':>7}")
for cat in ov.categories:
chs = groups.get(cat, [])
cnt = Counter(ch.stage for ch in chs)
tint = "" if chs else DIM
print(f" {col(tint)}{cat:<10}" + "".join(f"{cnt[s] or '·':>14}" for s in stages)
+ f"{len(chs):>7}{col(RST)}")
print(f"\n{col(BOLD)}=== category × difficulty ==={col(RST)} "
+ " ".join(f"{STATUS_ICON[s]} {s}" for s in STATUS_ORDER) + f" {BLOCKED_ICON} blocked")
diffs = ov.difficulties
print(f" {'':<10}" + "".join(f"{d:<13}" for d in diffs))
for cat in ov.categories:
chs = groups.get(cat, [])
cells = [icons([ch for ch in chs if (ch.difficulty or "?") == d]) for d in diffs]
# emoji are two columns wide in a terminal
print(f" {cat:<10}" + "".join(f"{x or '·'}{' ' * (13 - (2 * len(x) if x else 1))}"
for x in cells))
if ov.excluded:
print(f"\n{col(BOLD)}=== not in this CTF ({len(ov.excluded)}) ==={col(RST)}")
for ch in ov.excluded:
print(f" {ch.title[:34]:<35}{col(DIM)}{SELECTIONS[ch.selection]}{col(RST)}")
if ov.undecided:
print(f"\n{col(BOLD)}{col(YEL)}=== not in challenges.yml: not tracked or deployed "
f"({len(ov.undecided)}) ==={col(RST)}")
for ch in ov.undecided:
print(f" {ch.title[:34]:<35}{col(DIM)}{ch.repo.path}{col(RST)}")
print(f"\n{col(BOLD)}=== needs attention ==={col(RST)}")
for ch in sorted(ov.challenges, key=lambda c: c.repo.path.lower()):
if ch.problems:
print(f" {col(YEL)}{ch.repo.path:<32}{col(RST)} {col(DIM)}"
+ "; ".join(ch.problems) + col(RST))
for ch in ov.blank:
why = "no README" if ch.repo.readme is None else "README is still the blank template"
print(f" {col(RED)}{ch.repo.path:<32}{col(RST)} {col(DIM)}{why}{col(RST)}")
for path in ov.unknown:
print(f" {col(RED)}{path:<32}{col(RST)} {col(DIM)}in challenges.yml, but no such repo{col(RST)}")
print()