31
31
_log = logging .getLogger ("make_redirect_links" )
32
32
33
33
34
- tocheck = ["stable" ] + [
35
- f"{ major } .{ minor } .{ micro } "
34
+ tocheck = [pathlib . Path ( "stable" ) ] + [
35
+ pathlib . Path ( f"{ major } .{ minor } .{ micro } " )
36
36
for major in range (6 , - 1 , - 1 )
37
37
for minor in range (6 , - 1 , - 1 )
38
38
for micro in range (6 , - 1 , - 1 )
39
- if pathlib .Path (f"{ major } .{ minor } .{ micro } " ).exists ()
40
39
]
41
40
42
- toignore = tocheck + [
41
+ toignore = tocheck + [pathlib . Path ( p ) for p in [
43
42
"mpl-probscale" ,
44
43
"mpl_examples" ,
45
44
"mpl_toolkits" ,
49
48
"robots.txt" ,
50
49
"CNAME" ,
51
50
".git" ,
52
- ]
51
+ ]]
53
52
54
53
logging .basicConfig (level = logging .DEBUG )
55
54
@@ -60,16 +59,15 @@ def findlast(fname, tocheck, *, _cache={}):
60
59
Check the directories listed in ``tocheck`` to see if they have
61
60
``fname`` in them. Return the first one found, or None
62
61
"""
63
- p = pathlib .Path (fname )
64
- if p in _cache :
65
- return _cache [p ]
62
+ if fname in _cache :
63
+ return _cache [fname ]
66
64
for t in tocheck :
67
- pnew = pathlib . Path ( t , p )
65
+ pnew = t / fname
68
66
if pnew .exists ():
69
- _cache [p ] = t
67
+ _cache [fname ] = t
70
68
return t
71
69
else :
72
- _cache [p ] = None
70
+ _cache [fname ] = None
73
71
return None
74
72
75
73
@@ -111,32 +109,29 @@ def do_links(root0):
111
109
_log .info (f"Doing links on { root0 } " )
112
110
for root , dirs , files in os .walk (root0 ):
113
111
for name in files :
114
- fullname = os . path . join (root , name )
112
+ fullname = pathlib . Path (root , name )
115
113
last = findlast (fullname , tocheck )
116
114
_log .debug (f"Checking: { fullname } found { last } " )
117
- depth = root .count ("/" )
118
115
if last is not None :
119
- os .remove (fullname )
116
+ fullname .unlink ()
117
+ oldname = last / fullname
118
+ # Need to do these relative to where the final is, but note
119
+ # that `Path.relative_to` does not allow '.' as a common path
120
+ # prefix, so we need to use `os.path.relpath` instead.
121
+ relpath = os .path .relpath (oldname , start = fullname .parent )
120
122
if name .endswith ((".htm" , ".html" )):
121
123
# make an html redirect.
122
124
_log .info (f"Rewriting HTML: { fullname } in { last } " )
123
- with open (fullname , "w" ) as fout :
124
- oldname = os .path .join (last , fullname )
125
+ with fullname .open ("w" ) as fout :
125
126
st = html_redirect .format (
126
- newurl = "../" * ( depth + 1 ) + oldname ,
127
+ newurl = relpath ,
127
128
canonical = oldname ,
128
129
)
129
130
fout .write (st )
130
131
else :
131
132
# soft link
132
- # Need to do these relative to where the link is
133
- # so if it is a level down `ln -s ../3.1.1/boo/who boo/who`
134
- last = os .path .join (".." , last )
135
- for i in range (depth ):
136
- last = os .path .join (".." , last )
137
- oldname = os .path .join (last , fullname )
138
133
_log .info (f"Linking { fullname } to { oldname } " )
139
- os . symlink ( oldname , fullname )
134
+ fullname . symlink_to ( relpath )
140
135
141
136
142
137
def do_canonicals (dname ):
@@ -145,16 +140,12 @@ def do_canonicals(dname):
145
140
to the newest version.
146
141
"""
147
142
_log .debug (f"Walking { dname } " )
148
- for root , dirs , files in os .walk (dname ):
149
- for name in files :
150
- fullname = os .path .join (root , name )
151
- p = pathlib .Path (fullname )
152
- _log .debug (f"Checking { fullname } " )
153
- if name .endswith ((".htm" , ".html" )):
154
- basename = pathlib .Path (* p .parts [1 :])
155
- last = findlast (basename , tocheck )
156
- if last is not None :
157
- update_canonical (fullname , last , dname == tocheck [1 ])
143
+ for fullname in dname .rglob ("*.html" ):
144
+ _log .debug (f"Checking { fullname } " )
145
+ basename = pathlib .Path (* fullname .parts [1 :])
146
+ last = findlast (basename , tocheck )
147
+ if last is not None :
148
+ update_canonical (fullname , last , dname == tocheck [1 ])
158
149
159
150
160
151
def update_canonical (fullname , last , newest ):
@@ -168,15 +159,14 @@ def update_canonical(fullname, last, newest):
168
159
Note that if for some reason there are more than one canonical link
169
160
this will change all of them.
170
161
"""
171
- p = pathlib .Path (fullname )
172
162
pre = "https://matplotlib.org/"
173
- pnew = pathlib . Path ( last , * p .parts [1 :])
163
+ pnew = last . joinpath ( * fullname .parts [1 :])
174
164
newcanon = f"{ pre } { str (pnew )} "
175
- _log .info (f"{ p } to { pre } { str (pnew )} " )
165
+ _log .info (f"{ fullname } to { pre } { str (pnew )} " )
176
166
rec = re .compile (b'<link rel="canonical" href=".*"' )
177
167
with tempfile .NamedTemporaryFile (delete = False ) as fout :
178
168
found = False
179
- with open (fullname , "rb" ) as fin :
169
+ with fullname . open ("rb" ) as fin :
180
170
for line in fin :
181
171
if not found and b'<link rel="canonical"' in line :
182
172
new = f'<link rel="canonical" href="{ newcanon } "'
@@ -188,11 +178,12 @@ def update_canonical(fullname, last, newest):
188
178
# add a warning right under:
189
179
fout .write (line )
190
180
line = next (fin )
191
- if last == 'stable' :
192
- new = warn_banner_exists .format (version = p .parts [0 ],
193
- url = newcanon )
181
+ if last == tocheck [0 ]:
182
+ new = warn_banner_exists .format (
183
+ version = fullname .parts [0 ],
184
+ url = newcanon )
194
185
else :
195
- new = warn_banner_old .format (version = p .parts [0 ])
186
+ new = warn_banner_old .format (version = fullname .parts [0 ])
196
187
fout .write (new .encode ("utf-8" ))
197
188
if b'<div id="olddocs-message">' not in line :
198
189
# write the line out if it wasn't an olddocs-message:
@@ -221,25 +212,25 @@ def update_canonical(fullname, last, newest):
221
212
np = None
222
213
223
214
# figure out the newest version and trim tocheck at the same time:
224
- tocheck = [ t for t in tocheck if os . path . exists (t )]
215
+ tocheck = tuple ( p for p in tocheck if p . exists ())
225
216
print (tocheck )
226
217
227
218
# html redirect or soft link most things in the top-level directory that
228
219
# are not other modules or versioned docs.
229
220
if not args .no_redirects :
230
221
for entry in os .scandir ("." ):
231
- if entry .name not in toignore :
222
+ fullname = pathlib .Path (entry .name )
223
+ if fullname not in toignore :
232
224
if entry .is_dir ():
233
225
do_links (entry .name )
234
- elif entry .name .endswith ((".htm" , ".html" )):
235
- fullname = entry .name
226
+ elif fullname .suffix == ".html" :
236
227
last = findlast (fullname , tocheck )
237
228
_log .debug (f"Checking: { fullname } found { last } " )
238
229
if last is not None :
239
- os . remove ( fullname )
230
+ fullname . unlink ( )
240
231
_log .info (f"Rewriting HTML: { fullname } in { last } " )
241
- with open (fullname , "w" ) as fout :
242
- oldname = os . path . join ( last , fullname )
232
+ with fullname . open ("w" ) as fout :
233
+ oldname = last / fullname
243
234
st = html_redirect .format (newurl = oldname ,
244
235
canonical = oldname )
245
236
fout .write (st )
0 commit comments