#!/usr/bin/env python3 """ page_ls.py — show what a space holds. Offline. The tree, the titles, and one state tag per page. The tag is the only place this layer acknowledges that a wiki exists, and it reads it the way the issue index reads `origin:` — as an opaque fact recorded by somebody else: local never published; a complete state, not a pending one synced published, and the file matches what was pushed ahead published, and the local file has changed since ? published, but nothing recorded what was pushed Usage: page_ls.py [--space SPACE] [--prefix TITLE] [--titles] [--out DIR] """ import argparse import os import sys sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) import page # noqa: E402 def die(msg, code=1): sys.stderr.write("%s: %s\n" % (os.path.basename(sys.argv[0]), msg)) sys.exit(code) def state_of(space_dir, relpath, e): if not e.get("sub_url"): return "local" pushed = e.get("pushed") if not pushed: return "?" full = os.path.join(space_dir, relpath) if not os.path.isfile(full): return "missing" with open(full, encoding="utf-8") as f: return "synced" if page.body_hash(f.read()) == pushed else "ahead" def main(): ap = argparse.ArgumentParser() ap.add_argument("--space", default="local") ap.add_argument("--prefix", default="", help="only titles at or under this") ap.add_argument("--titles", action="store_true", help="print one title per line and nothing else") ap.add_argument("--out", help="wiki cache root (default: /tmp/wiki)") a = ap.parse_args() root = a.out or page.WIKI_ROOT space_dir = page.space_root(a.space, root) # "Does not exist" and "is empty" are different answers and get different # messages — an empty space is a space somebody made on purpose. if not os.path.isdir(space_dir): die("no such space: %s (looked in %s)" % (a.space, space_dir)) manifest = page.load_manifest(a.space, root) pages = (page.children_of(manifest, a.prefix) if a.prefix else page.sorted_pages(manifest)) if not pages: print("space %s is empty" % a.space if not a.prefix else "nothing at or under %r" % a.prefix) return 0 if a.titles: for _, e in pages: print(e.get("title", "")) return 0 sub = {p: e for p, e in pages} view = dict(manifest, pages=sub) for line in page.tree_lines(view, mark=lambda p, e: state_of(space_dir, p, e)): print(line) counts = {} for p, e in pages: s = state_of(space_dir, p, e) counts[s] = counts.get(s, 0) + 1 print("\n%d page(s): %s" % (len(pages), ", ".join("%d %s" % (v, k) for k, v in sorted(counts.items())))) return 0 if __name__ == "__main__": sys.exit(main())