docs/manage-redirects.py: add script to manage RTD redirects with the api

this is very simple, it just deletes everything and recreates it based
on what's in conf.py so that conf.py is the source of truth (it's IaC,
hah!).
This commit is contained in:
classabbyamp 2024-02-09 23:36:04 -05:00
parent 0d992db4af
commit 2bb1928c57
No known key found for this signature in database
GPG Key ID: 6BE0755918A4C7F5
3 changed files with 63 additions and 2 deletions

1
.gitignore vendored
View File

@ -2,6 +2,7 @@
*.swp
*/*.swp
.vscode/
__pycache__/
releases/*
testing/stubs/local.*
build

View File

@ -38,6 +38,15 @@ extlinks = {
# https://documatt.com/sphinx-reredirects/usage.html
# the target should be relative to ensure it works on RTD
# this is a fallback in case the redirects in the RTD settings are lost or no longer work
# RTD redirects should be:
# - Type: page redirect
# - From URL: /old/absolute/path/to/page.html
# - To URL: /new/absolute/path/to/page.html
# - HTTP status code: 301 Permanent
# - Force redirect: yes
# - Enabled: yes
# use manage-redirects.py to copy the config here to RTD
redirects = {
# source : target
"guides/binary-releases": "../../general/binary-releases.html",
@ -90,5 +99,9 @@ man_pages = [
('man/zfsbootmenu.7', 'zfsbootmenu', 'System Integration', man_author, '7'),
]
if tags.has('manpages'):
exclude_patterns += ['guides/**']
try:
# tags is set by sphinx when interpreting the config
if tags.has('manpages'):
exclude_patterns += ['guides/**']
except NameError:
...

47
docs/manage-redirects.py Normal file
View File

@ -0,0 +1,47 @@
#!/usr/bin/env python3
# Usage: RTD_TOKEN="..." python3 manage-redirects.py
# simple IaC-ish script to set redirects in readthedocs's config
# requires an api token from https://readthedocs.org/accounts/tokens/
from os import environ
import requests
from conf import redirects
SLUG = "zfsbootmenu"
URL = f"https://readthedocs.org/api/v3/projects/{SLUG}/redirects/"
HEADERS = {"Authorization": f"Token {environ.get('RTD_TOKEN')}"}
def transform_redirects(redir: dict[str, str]) -> dict[str, str]:
"""transform the redirect dictionary from the reredirects format to what rtd.org will want"""
return { k+".html": "/"+v.lstrip("../") for k, v in redir.items() }
if __name__ == "__main__":
# get the existing redirects
existing = []
req_url = URL
while req_url is not None:
resp = requests.get(req_url, headers=HEADERS)
resp.raise_for_status()
existing += resp.json().get("results", [])
req_url = resp.json().get("next")
# and delete them all
for redir in existing:
if (rid := redir.get('pk')) is not None:
print(f"=> Deleting redirect {rid}: {redir.get('from_url')} -> {redir.get('to_url')}")
resp = requests.delete(URL+f"{rid}/", headers=HEADERS)
resp.raise_for_status()
# replace them with the redirects defined in conf.py
for old, new in transform_redirects(redirects).items():
print(f"=> Creating redirect: {old} -> {new}")
resp = requests.post(URL, headers=HEADERS, data={
"from_url": old, "to_url": new, "type": "page", "http_status": 301, "force": True, "enabled": True,
})
resp.raise_for_status()