52
52
logging .basicConfig (level = logging .DEBUG )
53
53
54
54
55
- def findlast (fname , tocheck ):
55
+ # beware of triksy mutable defaults!
56
+ def findlast (fname , tocheck , * , _cache = {}):
56
57
"""
57
58
Check the directories listed in ``tocheck`` to see if they have
58
59
``fname`` in them. Return the first one found, or None
59
60
"""
60
61
p = pathlib .Path (fname )
62
+ if p in _cache :
63
+ return _cache [p ]
61
64
for t in tocheck :
62
65
pnew = pathlib .Path (t , p )
63
66
if pnew .exists ():
67
+ _cache [p ] = t
64
68
return t
65
69
else :
70
+ _cache [p ] = None
66
71
return None
67
72
68
73
@@ -88,56 +93,59 @@ def do_links(root0):
88
93
Either soft link a file at the top level to its newest position,
89
94
or make an html redirect if it is an html file.
90
95
"""
91
- _log .info (f'Doing links on { root0 } ' )
96
+
97
+ _log .info (f"Doing links on { root0 } " )
92
98
for root , dirs , files in os .walk (root0 ):
93
99
for name in files :
94
100
fullname = os .path .join (root , name )
95
101
last = findlast (fullname , tocheck )
96
- _log .debug (f'Checking: { fullname } found { last } ' )
102
+ _log .debug (f"Checking: { fullname } found { last } " )
103
+ depth = root .count ("/" )
97
104
if last is not None :
98
105
os .remove (fullname )
99
- if name .endswith ((' .htm' , ' .html' )):
106
+ if name .endswith ((" .htm" , " .html" )):
100
107
# make an html redirect.
101
- _log .info (f'Rewriting HTML: { fullname } in { last } ' )
102
- with open (fullname , 'w' ) as fout :
103
- oldname = '/' + os .path .join (last , fullname )
104
- st = html_redirect % (oldname , oldname , oldname )
108
+ _log .info (f"Rewriting HTML: { fullname } in { last } " )
109
+ with open (fullname , "w" ) as fout :
110
+ oldname = os .path .join (last , fullname )
111
+ st = html_redirect % (
112
+ "../" * (depth + 1 ) + oldname ,
113
+ "/" + oldname ,
114
+ "../" * (depth + 1 ) + oldname ,
115
+ )
105
116
fout .write (st )
106
117
else :
107
118
# soft link
108
119
# Need to do these relative to where the link is
109
120
# so if it is a level down `ln -s ../3.1.1/boo/who boo/who`
110
- last = os .path .join ('..' , last )
111
- depth = root .count ('/' )
121
+ last = os .path .join (".." , last )
112
122
for i in range (depth ):
113
- last = os .path .join ('..' , last )
123
+ last = os .path .join (".." , last )
114
124
oldname = os .path .join (last , fullname )
115
- _log .info (f' Linking { fullname } to { oldname } ' )
125
+ _log .info (f" Linking { fullname } to { oldname } " )
116
126
os .symlink (oldname , fullname )
117
- for d in dirs :
118
- do_links (d )
119
127
120
128
121
129
def do_canonicals (dname ):
122
130
"""
123
131
For each html file in the versioned docs, make the canonical link point
124
132
to the newest version.
125
133
"""
126
- _log .debug (f' Walking { dname } ' )
134
+ _log .debug (f" Walking { dname } " )
127
135
for root , dirs , files in os .walk (dname ):
128
136
for name in files :
129
137
fullname = os .path .join (root , name )
130
138
p = pathlib .Path (fullname )
131
- _log .debug (f' Checking { fullname } ' )
132
- if name .endswith ((' .htm' , ' .html' )):
139
+ _log .debug (f" Checking { fullname } " )
140
+ if name .endswith ((" .htm" , " .html" )):
133
141
basename = pathlib .Path (* p .parts [1 :])
134
142
last = findlast (basename , tocheck )
135
143
if last is not None :
136
144
update_canonical (fullname , last )
137
145
138
146
for d in dirs :
139
- _log .info (f' DIR: { d } ' )
140
- do_canonicals (os .path .join (dname ,d ))
147
+ _log .info (f" DIR: { d } " )
148
+ do_canonicals (os .path .join (dname , d ))
141
149
142
150
143
151
def update_canonical (fullname , last ):
@@ -150,19 +158,19 @@ def update_canonical(fullname, last):
150
158
this will change all of them.
151
159
"""
152
160
p = pathlib .Path (fullname )
153
- pre = ' https://matplotlib.org/'
161
+ pre = " https://matplotlib.org/"
154
162
pnew = pathlib .Path (last , * p .parts [1 :])
155
- newcanon = f' { pre + str (pnew )} '
156
- _log .info (f' { p } to { pre + str (pnew )} ' )
163
+ newcanon = f" { pre + str (pnew )} "
164
+ _log .info (f" { p } to { pre + str (pnew )} " )
157
165
with tempfile .NamedTemporaryFile (delete = False ) as fout :
158
- with open (fullname , 'rb' ) as fin :
166
+ with open (fullname , "rb" ) as fin :
159
167
for line in fin :
160
168
if b'<link rel="canonical"' in line :
161
- new = bytes (f'<link rel="canonical" href=" { newcanon } "' ,
162
- encoding = ' utf-8' )
163
- ll = re . sub ( b'<link rel="canonical" href=".*"' , new ,
164
- line )
165
- _log .debug (f' new { line } ->{ ll } ' )
169
+ new = bytes (
170
+ f'<link rel="canonical" href=" { newcanon } "' , encoding = " utf-8"
171
+ )
172
+ ll = re . sub ( b'<link rel="canonical" href=".*"' , new , line )
173
+ _log .debug (f" new { line } ->{ ll } " )
166
174
fout .write (ll )
167
175
else :
168
176
fout .write (line )
@@ -171,13 +179,15 @@ def update_canonical(fullname, last):
171
179
172
180
if __name__ == "__main__" :
173
181
174
- parser = argparse .ArgumentParser (description = ' Optional app description' )
182
+ parser = argparse .ArgumentParser (description = " Optional app description" )
175
183
176
- parser .add_argument ('--np' , type = int , help = 'Number of processors to use' )
177
- parser .add_argument ('--no_canonicals' , help = 'do not do canonical links' ,
178
- action = "store_true" )
179
- parser .add_argument ('--no_redirects' , help = 'do not do redirects links' ,
180
- action = "store_true" )
184
+ parser .add_argument ("--np" , type = int , help = "Number of processors to use" )
185
+ parser .add_argument (
186
+ "--no_canonicals" , help = "do not do canonical links" , action = "store_true"
187
+ )
188
+ parser .add_argument (
189
+ "--no_redirects" , help = "do not do redirects links" , action = "store_true"
190
+ )
181
191
182
192
args = parser .parse_args ()
183
193
if args .np :
@@ -188,22 +198,22 @@ def update_canonical(fullname, last):
188
198
# html redirect or soft link most things in the top-level directory that
189
199
# are not other modules or versioned docs.
190
200
if not args .no_redirects :
191
- for entry in os .scandir ('./' ):
201
+ for entry in os .scandir ("./" ):
192
202
if not (entry .name in toignore ):
193
203
if entry .is_dir ():
194
204
do_links (entry .name )
195
- elif entry .name .endswith ((' .htm' , ' .html' )):
205
+ elif entry .name .endswith ((" .htm" , " .html" )):
196
206
fullname = entry .name
197
207
last = findlast (fullname , tocheck )
198
- _log .debug (f' Checking: { fullname } found { last } ' )
208
+ _log .debug (f" Checking: { fullname } found { last } " )
199
209
if last is not None :
200
- os .remove ('./' + fullname )
201
- _log .info (f' Rewriting HTML: { fullname } in { last } ' )
202
- with open (fullname , 'w' ) as fout :
203
- oldname = '/' + os .path .join (last , fullname )
204
- st = html_redirect % (oldname , oldname , oldname )
210
+ os .remove ("./" + fullname )
211
+ _log .info (f" Rewriting HTML: { fullname } in { last } " )
212
+ with open (fullname , "w" ) as fout :
213
+ oldname = os .path .join (last , fullname )
214
+ st = html_redirect % (oldname , "/" + oldname , oldname )
205
215
fout .write (st )
206
- _log .info (' Done links and redirects' )
216
+ _log .info (" Done links and redirects" )
207
217
208
218
# change the canonical url for all html to the newest version in the docs:
209
219
if not args .no_canonicals :
0 commit comments