Created
May 10, 2024 04:51
-
-
Save thegamecracks/e7870f1b922c11c9d3f14b0565f07024 to your computer and use it in GitHub Desktop.
Basic sphinx objects.inv parser I wrote a year ago
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
objects.inv v2 Syntax Reference: | |
https://sphobjinv.readthedocs.io/en/stable/syntax.html | |
Python Discord Bot Reference: | |
https://github.com/python-discord/bot/blob/main/bot/exts/info/doc/_inventory_parser.py | |
""" | |
import re | |
import zlib | |
from dataclasses import dataclass | |
from typing import Generator | |
__version__ = "0.1.0" | |
V2_PATTERN = re.compile( | |
r""" | |
(?P<name>.+) | |
\s+ | |
(?P<domain>[^\s:]+):(?P<role>\S+) | |
\s+ | |
(?P<priority>-?\d+) | |
\s+ | |
(?P<uri>\S*) | |
\s+ | |
(?P<dispname>.+) | |
\s* | |
""", | |
re.VERBOSE, | |
) | |
@dataclass | |
class DocItem: | |
name: str | |
domain: str | |
role: str | |
priority: int | |
uri: str | |
dispname: str | |
def __post_init__(self): | |
if self.dispname == "-": | |
self.dispname = self.name | |
def yield_zlib_chunks(f) -> Generator[bytes, None, None]: | |
decomp = zlib.decompressobj() | |
while chunk := f.read(1024): | |
yield decomp.decompress(chunk) | |
def yield_zlib_lines(f) -> Generator[str, None, None]: | |
buf = b"" | |
for chunk in yield_zlib_chunks(f): | |
buf += chunk | |
while (pos := buf.find(b"\n")) != -1: | |
line, buf = buf[:pos], buf[pos + 1:] | |
yield line.decode() | |
if buf: | |
yield buf.decode() | |
def yield_inventory_items(f) -> Generator[DocItem, None, None]: | |
inv_version = f.readline().rstrip() | |
if inv_version != b"# Sphinx inventory version 2": | |
raise ValueError(f"Expected version 2 header, got {inv_version!r}") | |
name = f.readline().rstrip() | |
if not name.startswith(b"# Project: "): | |
raise ValueError(f"Unknown project header: {name!r}") | |
name = name[11:] | |
version = f.readline().rstrip() # apparently this can be empty | |
if not version.startswith(b"# Version:"): | |
raise ValueError(f"Unknown project version: {version!r}") | |
version = version[11:] | |
remainder = f.readline() | |
if b"zlib" not in remainder: | |
raise ValueError(f"Expected zlib in header, got {remainder!r}") | |
for line in yield_zlib_lines(f): | |
m = V2_PATTERN.fullmatch(line) | |
if m is None: | |
raise ValueError(f"Failed to match line: {line}") | |
params = m.groupdict() | |
params["priority"] = int(params["priority"]) | |
yield DocItem(**params) | |
def main(): | |
fmt = ":{0.domain}:{0.role}:`{0.name}`" | |
with open("objects.inv", "rb") as f: | |
for item in yield_inventory_items(f): | |
print(fmt.format(item), end="") | |
if item.priority == -1: | |
print(" (hidden)", end="") | |
print() | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment