Skip to content

Commit a09505f

Browse files
authored
Merge branch 'master' into 000971
2 parents cc03f6c + 1efb910 commit a09505f

File tree

15 files changed

+6615
-8
lines changed

15 files changed

+6615
-8
lines changed

.github/scripts/collect_and_render.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
import os
2+
from typing import List, Dict, Any, Optional
3+
from jinja2 import Environment, FileSystemLoader
4+
from dandi.dandiapi import DandiAPIClient
5+
6+
7+
def get_dandiset_metadata(dandiset_id: str) -> Optional[Dict[str, Any]]:
8+
"""
9+
Fetch metadata for a given dandiset ID.
10+
11+
Parameters
12+
----------
13+
dandiset_id : str
14+
The ID of the dandiset to fetch metadata for.
15+
16+
Returns
17+
-------
18+
Optional[Dict[str, Any]]
19+
A dictionary containing the dandiset metadata if successful, None otherwise.
20+
"""
21+
with DandiAPIClient() as client:
22+
try:
23+
dandiset = client.get_dandiset(dandiset_id)
24+
metadata = dandiset.get_raw_metadata()
25+
return metadata
26+
except Exception as e:
27+
print(f"Error fetching metadata for dandiset {dandiset_id}: {str(e)}")
28+
return None
29+
30+
31+
def find_notebooks(folder: str) -> List[str]:
32+
"""
33+
Recursively find all Jupyter notebooks in a given folder.
34+
35+
Parameters
36+
----------
37+
folder : str
38+
The path to the folder to search in.
39+
40+
Returns
41+
-------
42+
List[str]
43+
A list of relative paths to the found notebooks.
44+
"""
45+
notebooks = []
46+
for root, _, files in os.walk(folder):
47+
for file in files:
48+
if file.endswith('.ipynb'):
49+
rel_path = os.path.relpath(os.path.join(root, file), folder)
50+
notebooks.append(rel_path)
51+
return notebooks
52+
53+
54+
def collect_metadata() -> List[Dict[str, Any]]:
55+
"""
56+
Collect metadata and notebook information for all dandisets in the current directory.
57+
58+
Returns
59+
-------
60+
List[Dict[str, Any]]
61+
A list of dictionaries, each containing information about a dandiset,
62+
sorted by dandiset ID.
63+
"""
64+
dandisets = []
65+
for folder in os.listdir('.'):
66+
if os.path.isdir(folder) and folder.isdigit():
67+
metadata = get_dandiset_metadata(folder)
68+
if metadata:
69+
notebooks = find_notebooks(folder)
70+
dandisets.append({
71+
'id': folder,
72+
'metadata': metadata,
73+
'notebooks': notebooks
74+
})
75+
76+
dandisets.sort(key=lambda x: x['id'])
77+
return dandisets
78+
79+
80+
def render_webpage(dandisets: List[Dict[str, Any]]) -> None:
81+
"""
82+
Render the webpage using the collected dandiset information.
83+
84+
Parameters
85+
----------
86+
dandisets : List[Dict[str, Any]]
87+
A list of dictionaries containing information about each dandiset.
88+
89+
Returns
90+
-------
91+
None
92+
"""
93+
current_dir = os.path.dirname(os.path.abspath(__file__))
94+
template_dir = os.path.join(current_dir, '..', 'templates')
95+
96+
env = Environment(loader=FileSystemLoader(template_dir))
97+
template = env.get_template('index.html')
98+
99+
output = template.render(dandisets=dandisets)
100+
101+
output_dir = os.path.join(current_dir, '..', '..', 'output')
102+
os.makedirs(output_dir, exist_ok=True)
103+
with open(os.path.join(output_dir, 'index.html'), 'w') as f:
104+
f.write(output)
105+
106+
if __name__ == "__main__":
107+
dandisets = collect_metadata()
108+
render_webpage(dandisets)

.github/templates/index.html

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>DANDI Datasets</title>
7+
<style>
8+
body {
9+
font-family: 'Arial', sans-serif;
10+
line-height: 1.6;
11+
margin: 0;
12+
padding: 20px;
13+
}
14+
.container {
15+
max-width: 1200px;
16+
margin: 0 auto;
17+
}
18+
h1 {
19+
text-align: center;
20+
margin-bottom: 30px;
21+
}
22+
.dandiset {
23+
border-radius: 8px;
24+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
25+
margin-bottom: 30px;
26+
padding: 20px;
27+
transition: box-shadow 0.3s ease;
28+
}
29+
.dandiset:hover {
30+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
31+
}
32+
.dandiset h2 {
33+
margin-top: 0;
34+
margin-bottom: 15px;
35+
}
36+
.dandiset p {
37+
margin-bottom: 10px;
38+
}
39+
.dandiset a {
40+
text-decoration: none;
41+
font-weight: bold;
42+
}
43+
.dandiset a:hover {
44+
text-decoration: underline;
45+
}
46+
.notebooks {
47+
margin-top: 15px;
48+
}
49+
.notebooks h3 {
50+
font-size: 1.1em;
51+
margin-bottom: 10px;
52+
}
53+
.notebooks ul {
54+
list-style-type: disc;
55+
padding-left: 20px;
56+
}
57+
.notebooks li {
58+
margin-bottom: 5px;
59+
}
60+
@media (max-width: 768px) {
61+
body {
62+
padding: 10px;
63+
}
64+
.dandiset {
65+
padding: 15px;
66+
}
67+
}
68+
</style>
69+
</head>
70+
<body>
71+
<div class="container">
72+
<h1>DANDI Datasets</h1>
73+
74+
<div class="toc">
75+
<h2>Table of Contents</h2>
76+
<ul>
77+
{% for dandiset in dandisets %}
78+
<li><a href="#dandiset-{{ dandiset.id }}">{{ dandiset.id }} - {{ dandiset.metadata.name }}</a></li>
79+
{% endfor %}
80+
</ul>
81+
</div>
82+
83+
{% for dandiset in dandisets %}
84+
<div id="dandiset-{{ dandiset.id }}" class="dandiset">
85+
<h2>{{ dandiset.metadata.name }}</h2>
86+
<p><strong>ID:</strong> {{ dandiset.id }}</p>
87+
<p><strong>Description:</strong> {{ dandiset.metadata.description }}</p>
88+
<p><a href="https://dandiarchive.org/dandiset/{{ dandiset.id }}" target="_blank">View on DANDI Archive</a></p>
89+
{% if dandiset.notebooks %}
90+
<div class="notebooks">
91+
<h3>Notebooks:</h3>
92+
<ul>
93+
{% for notebook in dandiset.notebooks %}
94+
<li><a href="https://github.com/dandi/example-notebooks/blob/master/{{ dandiset.id }}/{{ notebook }}" target="_blank">{{ notebook }}</a></li>
95+
{% endfor %}
96+
</ul>
97+
</div>
98+
{% endif %}
99+
</div>
100+
{% endfor %}
101+
</div>
102+
</body>
103+
</html>

.github/workflows/index_workflow.yml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: DANDI Metadata Collector
2+
3+
on:
4+
push:
5+
branches: [ master ]
6+
7+
jobs:
8+
collect-and-render:
9+
runs-on: ubuntu-latest
10+
steps:
11+
- uses: actions/checkout@v2
12+
13+
- name: Set up Python
14+
uses: actions/setup-python@v2
15+
with:
16+
python-version: '3.9'
17+
18+
- name: Install dependencies
19+
run: |
20+
python -m pip install --upgrade pip
21+
pip install requests jinja2 dandi
22+
23+
- name: Run metadata collector and renderer
24+
run: python .github/scripts/collect_and_render.py
25+
26+
- name: Deploy to GitHub Pages
27+
uses: peaceiris/actions-gh-pages@v3
28+
with:
29+
github_token: ${{ secrets.GITHUB_TOKEN }}
30+
publish_dir: ./output

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
.ipynb_checkpoints
22
*.DS_Store
33
*__pycache__/
4+
*.ipynb_checkpoints/
5+
output/
6+

000010/DataJoint/DJ-NWB-Li-Daie-2015-2016/notebooks/Li-2015-examples.ipynb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2111,9 +2111,9 @@
21112111
"metadata": {},
21122112
"source": [
21132113
"For each group of **contra** vs. **ipsi** selective units, the units are further sorted in to three categories:\n",
2114-
"+ unit exibited selectivity during **sample** or **delay** and not **response** period\n",
2115-
"+ unit exibited selectivity during **sample** or **delay** and **response** period\n",
2116-
"+ unit exibited selectivity only during **response** period"
2114+
"+ unit exhibited selectivity during **sample** or **delay** and not **response** period\n",
2115+
"+ unit exhibited selectivity during **sample** or **delay** and **response** period\n",
2116+
"+ unit exhibited selectivity only during **response** period"
21172117
]
21182118
},
21192119
{

000728/AllenInstitute/visual_coding_ophys_tutorial.ipynb

Lines changed: 3 additions & 3 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)