Skip to content

Commit ba8c3ca

Browse files
committed
Refine 300/30 challenge template
1 parent 491c9d7 commit ba8c3ca

3 files changed

Lines changed: 26 additions & 14 deletions

File tree

chronicle/description_template.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1079,10 +1079,12 @@ def _build_sample_fixtures() -> dict[str, dict[str, Any]]:
10791079

10801080
PROFILE_TEMPLATE_DEFAULTS: dict[str, str] = {
10811081
"default": DEFAULT_DESCRIPTION_TEMPLATE,
1082-
"300-30-challenge": """🔥 Run Nut x Everest - Day {{ challenge.day }}/{{ challenge.days }}
1083-
{{ challenge.pace.distance_status_emoji }} {{ challenge.pace.distance_delta_display }} | {{ challenge.pace.elevation_status_emoji }} {{ challenge.pace.elevation_delta_display }}
1084-
🏃 Today: {{ '%.1f' | format(challenge.today.distance_miles) }} mi | +{{ challenge.today.elevation_feet }}' | 🏔️ {{ challenge.today.royale_hill_summits }}
1085-
📈 Total: {{ '%.1f' | format(challenge.totals.distance_miles) }} mi | +{{ challenge.totals.elevation_feet }}' | 🏔️ {{ challenge.totals.royale_hill_summits }}
1082+
"300-30-challenge": """{% set progress_day = challenge.day | default(0, true) | int %}{% set filled_boxes = ((progress_day - 1) // 3) + 1 %}{% if filled_boxes < 1 %}{% set filled_boxes = 1 %}{% endif %}{% if filled_boxes > 10 %}{% set filled_boxes = 10 %}{% endif %}{% set left_filled = [filled_boxes, 5] | min %}{% set right_filled = [filled_boxes - 5, 0] | max %}
1083+
🏁🥜 RUN NUT 🗙 EVEREST 🧗🏼‍♂️🏁
1084+
🏁 {{ '▰' * left_filled }}{{ '▱' * (5 - left_filled) }} Day {{ challenge.day }} {{ '▰' * right_filled }}{{ '▱' * (5 - right_filled) }}🏁
1085+
🏁🚦⚖️ • 🦖 {{ challenge.pace.distance_delta_display | replace('mi', ' mi') }} • 🦖 {{ challenge.pace.elevation_delta_display }}
1086+
🏁🏃🏽‍♂️‍➡️ Today • {{ '%.1f' | format(challenge.today.distance_miles) }} mi • {{ challenge.today.elevation_feet }}' • 🏔️×{{ challenge.today.royale_hill_summits }}
1087+
🏁✅ Total • {{ '%.1f' | format(challenge.totals.distance_miles) }} mi • {{ challenge.totals.elevation_feet }}' • 🏔️×{{ challenge.totals.royale_hill_summits }}
10861088
10871089
🏆 {{ streak_days }} days in a row
10881090
{% for notable in notables %}🏅 {{ notable }}
@@ -1096,9 +1098,8 @@ def _build_sample_fixtures() -> dict[str, dict[str, Any]]:
10961098
🌤️🌡️ Misery Index: {{ misery.index }} {{ misery.index.emoji }} {{ misery.index.severity }} | 🏭 AQI: {{ weather.aqi }}{{ weather.aqi_description }}
10971099
🌤️🚦 Training Readiness: {{ training.readiness_score }} {{ training.readiness_emoji }} | 💤 {{ training.sleep_score }} | 💗 {{ training.resting_hr }}
10981100
1099-
👟🏃 {{ activity.gap_pace }} | 🏔️ {{ activity.elevation_feet }}' | 👣 {{ activity.cadence_spm }}spm | 💓 {{ activity.average_hr }}
1100-
👟⚡ {{ activity.norm_power }} | ⚙️{{ activity.efficiency }} | 🍌☢️ {{ ((activity.calories | default(0, true) | float) / 1050) | round(2) }}µSv | 🍺 {{ activity.beers }}
1101-
1101+
👟🏃 {{ activity.gap_pace }} | 🍌☢️ {{ ((activity.calories | default(0, true) | float) / 1050) | round(2) }}µSv | 🍺 {{ activity.beers }}
1102+
👟💓 {{ activity.average_hr }} |⚡{{ activity.norm_power }} | ⚙️{{ activity.efficiency }} | 👣 {{ activity.cadence_spm }}spm
11021103
🚄{{ training.status_emoji }} {{ training.status_key }} | {{ training.aerobic_te }} : {{ training.anaerobic_te }} - {{ training.te_label }}
11031104
🚄🏋️ {{ intervals.fitness }} | 💦 {{ intervals.fatigue }} | 🗿 {{ intervals.form_percent_display }} - {{ intervals.form_class }} {{ intervals.form_class_emoji }}
11041105
🚄🏋️ {{ training.chronic_load | default('N/A') }} | 💦 {{ training.acute_load | default('N/A') }} | 🗿 {{ training.load_ratio | default('N/A') }} - {{ training.acwr_status | default('N/A') }} {{ training.acwr_status_emoji | default('⚪') }}

docs/RUN_NUT_EVEREST_CHALLENGE.md

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,20 @@ It excludes strength-like activities and only matches activity dates from `2026-
3333
The profile seed template leads with the challenge scoreboard:
3434

3535
```text
36-
🔥 Run Nut x Everest - Day 15/31
37-
🟢 +6.3mi | 🟢 +112'
38-
🏃 Today: 13.2 mi | +1,420' | 🏔️ 6
39-
📈 Total: 151.8 mi | +15,112' | 🏔️ 110
36+
🏁🥜 RUN NUT 🗙 EVEREST 🧗🏼‍♂️🏁
37+
🏁 ▰▱▱▱▱ Day 3 ▱▱▱▱▱🏁
38+
🏁🚦⚖️ • 🦖 +0.8 mi • 🦖 +112'
39+
🏁🏃🏽‍♂️‍➡️ Today • 10.2 mi • 120' • 🏔️×6
40+
🏁✅ Total • 30.8 mi • 3,112' • 🏔️×24
4041
```
4142

4243
The lower section uses the `sean_default` streak, activity-award, weather, readiness, and technical training layout. It intentionally omits the default historical totals for past 7 days, past 30 days, and year-to-date.
4344

4445
## Pace Indicators
4546

46-
The second line shows whether the challenge is ahead or behind the required average pace.
47+
The second line is a ten-block day progress bar split around the current challenge day. Days `1-3` show one filled block, `4-6` show two, and the bar clamps at ten filled blocks.
48+
49+
The third line shows whether the challenge is ahead or behind the required average pace.
4750

4851
Daily targets:
4952

tests/test_description_template.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,21 @@ def test_challenge_profile_is_seeded_disabled_with_valid_template(self) -> None:
7575
self.assertFalse(challenge["enabled"])
7676

7777
active = get_active_template(settings, profile_id="300-30-challenge")
78-
self.assertIn("Run Nut x Everest", active["template"])
78+
self.assertIn("RUN NUT", active["template"])
79+
self.assertIn("filled_boxes", active["template"])
7980
self.assertIn("challenge.pace.distance_delta_display", active["template"])
8081
self.assertIn("🍌☢️", active["template"])
8182
self.assertIn("activity_badges", active["template"])
8283
self.assertNotIn("Remaining:", active["template"])
8384
validation = validate_template_text(active["template"], get_sample_template_context())
8485
self.assertTrue(validation["valid"], validation)
8586

87+
context = get_sample_template_context()
88+
context["challenge"]["day"] = 3
89+
rendered = render_template_text(active["template"], context)
90+
self.assertTrue(rendered["ok"], rendered)
91+
self.assertIn("🏁 ▰▱▱▱▱ Day 3 ▱▱▱▱▱🏁", rendered["description"])
92+
8693
def test_challenge_profile_refreshes_untouched_seed_template(self) -> None:
8794
with tempfile.TemporaryDirectory() as td:
8895
template_path = Path(td) / "description_template.j2"
@@ -93,7 +100,8 @@ def test_challenge_profile_refreshes_untouched_seed_template(self) -> None:
93100
live_path.write_text("🔥 300/30 Challenge - Day {{ challenge.day }}/{{ challenge.days }}\nold seed\n", encoding="utf-8")
94101

95102
active = get_active_template(settings, profile_id="300-30-challenge")
96-
self.assertIn("Run Nut x Everest", active["template"])
103+
self.assertIn("RUN NUT", active["template"])
104+
self.assertIn("filled_boxes", active["template"])
97105
self.assertIn("🍌☢️", active["template"])
98106
self.assertNotIn("old seed", active["template"])
99107

0 commit comments

Comments
 (0)