Skip to content

Commit c195f1d

Browse files
Fix AttributeError on empty youtube field + add events YAML validation (#108)
* Initial plan * Fix AttributeError for empty youtube field, add YAML validation script, and update CI Co-authored-by: alexeygrigorev <875246+alexeygrigorev@users.noreply.github.com> * Add CI workflow to validate events YAML on push/PR when file changes Co-authored-by: alexeygrigorev <875246+alexeygrigorev@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: alexeygrigorev <875246+alexeygrigorev@users.noreply.github.com>
1 parent ace063f commit c195f1d

4 files changed

Lines changed: 87 additions & 1 deletion

File tree

.github/workflows/generate_all.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ jobs:
2929
run: |
3030
(cd previews && \
3131
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true npm install)
32+
- name: Validate events YAML
33+
run: uv run python scripts/validate_events_yaml.py
3234
- name: make all
3335
env:
3436
AIRTABLE_TOKEN: ${{ secrets.AIRTABLE_TOKEN }}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: Validate events YAML
2+
3+
on:
4+
push:
5+
paths:
6+
- '_data/events.yaml'
7+
pull_request:
8+
paths:
9+
- '_data/events.yaml'
10+
11+
jobs:
12+
validate:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v2
16+
- uses: actions/setup-python@v2
17+
with:
18+
python-version: '3.12'
19+
- name: uv install
20+
run: |
21+
pip install uv
22+
uv sync
23+
- name: Validate events YAML
24+
run: uv run python scripts/validate_events_yaml.py

scripts/airtable.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,10 @@ def find_matching_podcasts_youtube(youtube_id):
308308
if 'youtube' not in event:
309309
continue
310310

311-
event_youtube_url = event['youtube'].strip()
311+
event_youtube_url = event.get('youtube')
312+
if not event_youtube_url:
313+
continue
314+
event_youtube_url = event_youtube_url.strip()
312315
if '?v=' not in event_youtube_url:
313316
print(f'wrong url: {event_youtube_url}, skipping it...')
314317
continue

scripts/validate_events_yaml.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import sys
2+
import yaml
3+
4+
REQUIRED_FIELDS = ['time', 'title', 'type']
5+
6+
7+
def main():
8+
filepath = '_data/events.yaml'
9+
10+
with open(filepath, encoding='utf-8') as f:
11+
try:
12+
events = yaml.safe_load(f)
13+
except yaml.YAMLError as e:
14+
print(f"YAML parsing error in {filepath}: {e}")
15+
print("Suggestion: Check for incorrect indentation, missing quotes, or invalid characters.")
16+
sys.exit(1)
17+
18+
if not isinstance(events, list):
19+
print(f"ERROR: {filepath} must contain a list of events.")
20+
print("Suggestion: Ensure the file starts with a list (each entry begins with '- ').")
21+
sys.exit(1)
22+
23+
errors = []
24+
for i, event in enumerate(events):
25+
if not isinstance(event, dict):
26+
errors.append(
27+
f"Event at index {i} is not a dictionary. "
28+
"Suggestion: Ensure each event entry is a YAML mapping (key: value pairs)."
29+
)
30+
continue
31+
for field in REQUIRED_FIELDS:
32+
if field not in event or not event[field]:
33+
errors.append(
34+
f"Event at index {i} (title: '{event.get('title', 'unknown')}') "
35+
f"is missing required field '{field}'. "
36+
f"Suggestion: Add '{field}: <value>' to this event entry."
37+
)
38+
if 'youtube' in event and event['youtube'] is not None:
39+
if not isinstance(event['youtube'], str):
40+
errors.append(
41+
f"Event at index {i} (title: '{event.get('title', 'unknown')}') "
42+
"has a non-string 'youtube' field. "
43+
"Suggestion: Set 'youtube' to a string URL (e.g. https://www.youtube.com/watch?v=...) "
44+
"or leave it empty / remove it entirely."
45+
)
46+
47+
if errors:
48+
print(f"Found {len(errors)} error(s) in {filepath}:\n")
49+
for err in errors:
50+
print(f" ERROR: {err}")
51+
sys.exit(1)
52+
53+
print(f"Validation passed: {len(events)} events OK.")
54+
55+
56+
if __name__ == "__main__":
57+
main()

0 commit comments

Comments
 (0)