Instantly share code, notes, and snippets.

@edk0 /app.py
Created Jan 31, 2018

Embed
What would you like to do?
# vim: et sw=4 sts=4
from flask import Flask, escape, redirect
app = Flask(__name__)
import posixpath
import requests
from sphinx.util.inventory import InventoryFile
from werkzeug.contrib.iterio import IterIO
INVENTORIES = {
'3': [
('https://docs.python.org/3/', 'https://docs.python.org/3/objects.inv'),
],
'2': [
('https://docs.python.org/2/', 'https://docs.python.org/2/objects.inv'),
],
}
m = {}
for mapping, l in INVENTORIES.items():
d = {}
for uri, inv in l:
print(f"Getting a {inv!r}")
r = requests.get(inv, stream=True)
s = IterIO(r.iter_content())
inv = InventoryFile.load(s, uri, posixpath.join)
# medium hack: prefer classes and then functions and then other stuff.
# when shadowing happens (e.g. 'dict', 'len') this seems to be the order we want
types = list(inv.keys())
types.remove('py:class')
types.remove('py:function')
types = ['py:class', 'py:function'] + types
for typ in types:
entries = inv[typ]
x = {k.casefold(): v for k, v in entries.items()}
x.update(d)
d = x
# this is another loop so shortened names don't ever take priority over full ones
for typ in types:
entries = inv[typ]
x = {k.split('.')[-1].casefold(): v for k, v in entries.items()}
x.update(d)
d = x
m[mapping] = d
@app.route("/<string:mapping>/<string:obj_id>")
def bounce(mapping, obj_id):
try:
index = m[mapping]
except KeyError:
return f"I don't know about {escape(mapping)}.", 404
try:
projname, version, location, _ = index[obj_id.casefold()]
except KeyError:
return f"I don't know about {escape(obj_id)} in {escape(mapping)}", 404
return redirect(location), 307
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment