forked from landlab/landlab
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnotebooks.py
157 lines (117 loc) · 3.76 KB
/
notebooks.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
"""Get the landlab tutorial and teaching notebooks.
Run this script to fetch the set of *landlab* notebooks compatible with
an installed version of landlab.
Usage
-----
Get notebooks for a currently installed *landlab*,
$ python -m notebooks
To get notebooks for a particular version of *landlab*, provide
a version number as an argument. For example,
$ python -m notebooks 2.5.0
"""
import argparse
import os
import pathlib
import sys
import tarfile
from urllib.error import HTTPError
from urllib.parse import urljoin
from urllib.request import urlopen
from packaging.version import Version
def main(version=None):
if version in ("master", "latest", "dev"):
version = None
if not version or (version := Version(version)).is_devrelease:
tag = "master"
else:
tag = "v" + version.base_version
notebooks = NotebookFetcher(tag)
out(f"fetching notebooks for landlab {notebooks.version}")
out(f"{notebooks.url}")
try:
stream = notebooks.open()
except NotebookError as error:
err(str(error))
return -1
with tarfile.open(fileobj=stream, mode="r|gz") as tfile:
base = NotebookExtractor(tfile).extract()
out(f"notebooks have been extracted into {base}")
out("To run the notebooks first install the required dependencies:")
out("")
out(f" $ conda install --file={base}/requirements-notebooks.txt")
out("")
out("and then open the welcome notebook:")
out("")
out(f" $ jupyter notebook {base}/notebooks/welcome.ipynb")
print(base)
return 0
class NotebookError(Exception):
def __init__(self, msg):
self._msg = msg
def __str__(self):
return self._msg
class NotebookFetcher:
URL = "https://github.com/landlab/landlab/archive/refs"
def __init__(self, version):
self._version = version
@property
def version(self):
return self._version
@property
def url(self):
return urljoin(NotebookFetcher.URL, f"{self.version}.tar.gz")
def open(self):
try:
stream = urlopen(self.url)
except HTTPError as error:
if error.code == 404:
msg = f"unable to find notebooks for requested landlab version ({self.version})"
else:
msg = f"unable to fetch notebooks ({error.reason})"
raise NotebookError(msg) from error
else:
return stream
class NotebookExtractor:
def __init__(self, tfile):
self._tfile = tfile
self._names = []
def extract(self):
self._tfile.extractall(members=self._notebooks())
return self.base
def _notebooks(self):
for tarinfo in self._tfile:
parts = pathlib.Path(tarinfo.name).parts
if (len(parts) > 1 and parts[1] == "notebooks") or (
parts[-1] == "requirements-notebooks.txt"
):
self._names.append(tarinfo.name)
yield tarinfo
@property
def names(self):
return sorted(self._names)
@property
def base(self):
return pathlib.Path(os.path.commonprefix(self.names))
def out(text):
print("\033[1m" + text + "\033[0m", file=sys.stderr)
def err(text):
print("\033[91m" + text + "\033[0m", file=sys.stderr)
if __name__ == "__main__":
try:
import landlab
except ModuleNotFoundError:
version = ""
else:
version = landlab.__version__
parser = argparse.ArgumentParser(
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter
)
parser.add_argument(
"version",
metavar="VERSION",
nargs="?",
default=version,
help="a landlab version (e.g. 2.5.0)",
)
args = parser.parse_args()
sys.exit(main(args.version))