Repository navigation
Expand file tree
/
Copy pathfetch_python_docs.py
More file actions
executable file
·110 lines (89 loc) · 3.19 KB
/
Copy pathfetch_python_docs.py
File metadata and controls
executable file
·110 lines (89 loc) · 3.19 KB
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
#!/usr/bin/env python
"""Idempotently download, extract, and serve a mirror of <docs.python.org>."""
import argparse
import http.client
import shlex
import subprocess
import sys
import tarfile
from pathlib import Path
import requests
HERE = Path(__file__).parent
def get_options():
"""Parse command line options."""
parser = argparse.ArgumentParser(
description="Idempotently download/serve Python docs from a local copy"
)
parser.add_argument(
"--systemd", action="store_true", help="Also create a systemd service"
)
return parser.parse_args()
def download_extract():
"""Download and extract Python docs to `HERE`."""
major, minor, *_ = sys.version_info
url = f"https://docs.python.org/{major}.{minor}/archives/python-{major}.{minor}-docs-html.tar.bz2"
outfile = HERE / f"python-{major}.{minor}-docs-html.tar.bz2"
print(f"Downloading {url}")
if outfile.is_file():
print(f"{outfile} already exists")
else:
with requests.get(url) as r, open(outfile, "wb") as f:
if r.status_code != 200:
descr = http.client.responses[r.status_code]
raise RuntimeError(f"{r.status_code = } ({descr})")
f.write(r.content)
print(f"Saved to {outfile} ({len(r.content)} bytes)")
print(f"Extracting {outfile}")
assert outfile.is_file()
outdir = HERE / f"python-{major}.{minor}-docs-html"
if (outdir / "index.html").is_file():
print(f"{outdir}/index.html already exists")
else:
with tarfile.open(outfile) as f:
f.extractall(path=HERE, filter="data") # Extracting HERE creates outdir
assert (outdir / "index.html").is_file()
return outdir
def define_user_service(outdir):
"""Create a systemd unit file to serve docs as a user service."""
print("Creating systemd unit file")
if not Path("/run/systemd/system").exists():
print("Host appears not to use systemd; skipping")
return
dest = Path.home() / ".config" / "systemd" / "user" / "python-docs.service"
dest.parent.mkdir(parents=True, exist_ok=True)
cmd = shlex.join(
[sys.executable, "-m", "http.server", "-d", str(outdir.absolute()), "8004"]
)
body = f"""\
# Autogenerated by {__file__}
[Service]
Type=simple
Description=Serve Python docs on port 8004
ExecStart={cmd}
[Install]
WantedBy=default.target
"""
if dest.is_file():
with open(dest) as f:
contents = f.read()
if contents == body:
print(f"{dest} already defined")
return
with open(dest, "w") as f:
f.write(body)
print(f"Saved to {dest}")
def enable_user_service():
"""Start and enable the systemd unit service."""
cmd = ["systemctl", "--user", "daemon-reload"]
print("Enabling and starting systemd user service")
print(f"{shlex.join(cmd)}")
subprocess.run(cmd).check_returncode()
cmd = ["systemctl", "--user", "enable", "--now", "python-docs"]
print(f"{shlex.join(cmd)}")
subprocess.run(cmd).check_returncode()
if __name__ == "__main__":
options = get_options()
outdir = download_extract()
if options.systemd:
define_user_service(outdir)
enable_user_service()