Skip to content

Commit 7737b1f

Browse files
Robbie1977claude
andcommitted
Merge master into doc-refactoring: resolve conflicts and fix build paths
- Resolve .gitignore conflict (keep both sides' additions) - Update vfbterms.py datasets path from '../datasets/' to 'datasets/' to match new ontologies location at blog/ontologies/ - Add datasets/_index.md under blog/ontologies/ for term page generation - Remove accidentally staged __pycache__ file Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2 parents e77d89b + 9ef66ef commit 7737b1f

6 files changed

Lines changed: 994 additions & 452 deletions

File tree

.github/workflows/test_vfbterms.yml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,4 +38,20 @@ jobs:
3838
name: test-results
3939
path: |
4040
FBbt_00003748_v*.md
41-
retention-days: 7
41+
retention-days: 7
42+
43+
check_image_refs:
44+
runs-on: ubuntu-latest
45+
needs: test
46+
steps:
47+
- uses: actions/checkout@v3
48+
49+
- name: Set up Python
50+
uses: actions/setup-python@v4
51+
with:
52+
python-version: '3.9'
53+
54+
- name: Run external image references check
55+
run: |
56+
python check_images.py --base content --include-themes
57+

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,6 @@ transcript.en.vtt
55
.idea/*
66
.hugo_build.lock
77
resources/*
8+
__pycache__
9+
__pycache__/
10+
__pycache__/*.pyc

check_images.py

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#!/usr/bin/env python3
2+
"""Check external image URLs in content (optionally themes) and report failures."""
3+
4+
from __future__ import annotations
5+
import argparse
6+
import pathlib
7+
import re
8+
import sys
9+
import ssl
10+
import socket
11+
import urllib.request
12+
import urllib.error
13+
14+
IMAGE_PATTERN = re.compile(r'https?://[^\s"\')]+\.(?:png|jpg|jpeg|gif|svg)', re.IGNORECASE)
15+
DEFAULT_EXTENSIONS = ['.md', '.html', '.yml', '.yaml', '.toml', '.json', '.js', '.ts', '.scss', '.css']
16+
17+
18+
def collect_image_urls(base_dir: pathlib.Path, ext_filter=None):
19+
ext_filter = ext_filter or DEFAULT_EXTENSIONS
20+
matches = []
21+
for path in base_dir.rglob('*'):
22+
if not path.is_file() or path.suffix.lower() not in ext_filter:
23+
continue
24+
text = path.read_text(encoding='utf-8', errors='ignore')
25+
for m in IMAGE_PATTERN.finditer(text):
26+
matches.append((str(path), m.group(0)))
27+
return matches
28+
29+
30+
def check_url(url: str, timeout: float = 8.0):
31+
socket.setdefaulttimeout(timeout)
32+
ctx = ssl.create_default_context()
33+
headers = {'User-Agent': 'Mozilla/5.0 (compatible; image-link-checker/1.0)'}
34+
try:
35+
req = urllib.request.Request(url, method='HEAD', headers=headers)
36+
with urllib.request.urlopen(req, timeout=timeout, context=ctx) as response:
37+
return response.status, None
38+
except urllib.error.HTTPError as he:
39+
if 300 <= he.code < 400 and he.headers.get('Location'):
40+
return he.code, None
41+
try:
42+
req = urllib.request.Request(url, method='GET', headers=headers)
43+
with urllib.request.urlopen(req, timeout=timeout, context=ctx) as response:
44+
return response.status, None
45+
except Exception as inner_e:
46+
return he.code, str(inner_e)
47+
except Exception as e:
48+
return None, str(e)
49+
50+
51+
def main() -> int:
52+
parser = argparse.ArgumentParser(description='Check external image URLs in a static site repo')
53+
parser.add_argument('--base', default='content', help='Base directory to scan (default: content)')
54+
parser.add_argument('--include-themes', action='store_true', help='Also include themes directory')
55+
parser.add_argument('--timeout', type=float, default=8.0, help='HTTP timeout in seconds')
56+
args = parser.parse_args()
57+
58+
dirs = [pathlib.Path(args.base)]
59+
if args.include_themes:
60+
dirs.append(pathlib.Path('themes'))
61+
62+
all_urls = []
63+
for d in dirs:
64+
if not d.exists():
65+
continue
66+
all_urls.extend(collect_image_urls(d))
67+
68+
if not all_urls:
69+
print('No external image URLs found')
70+
return 0
71+
72+
unique = list(dict.fromkeys(all_urls))
73+
print(f'Found {len(all_urls)} references, {len(unique)} unique URLs')
74+
75+
failures = []
76+
for i, (path, url) in enumerate(unique, 1):
77+
status, err = check_url(url, timeout=args.timeout)
78+
if status is None or status >= 400:
79+
failures.append((path, url, status, err))
80+
if i % 20 == 0:
81+
print(f'Checked {i}/{len(unique)}')
82+
83+
if failures:
84+
print(f'FAILED {len(failures)} URLs')
85+
for p, u, s, e in failures:
86+
print(f'{p} {s or "ERR"} {e or ""} {u}')
87+
return 1
88+
89+
print('All URLs OK')
90+
return 0
91+
92+
93+
if __name__ == '__main__':
94+
sys.exit(main())

content/en/blog/_index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: "VFB Latest"
3-
linkTitle: "Latest (Release: v4 2025.11.22)"
3+
linkTitle: "Latest (Release: v4 2026.03.23)"
44
menu:
55
main:
66
weight: 30
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
title: "Datasets available on VFB"
3+
linkTitle: "Datasets"
4+
weight: 25
5+
tags: [DataSet,Content,VFB,FBrf]
6+
description: >
7+
Here is a list of all available datasets available on Virtual Fly Brain (VFB).
8+
cascade:
9+
- type: "docs"
10+
_target:
11+
path: "/**"
12+
---
13+

0 commit comments

Comments
 (0)