#!/usr/bin/env python3 from datetime import datetime from glob import glob from zoneinfo import ZoneInfo import contextlib import os import os.path import subprocess import sys import time @contextlib.contextmanager def working_directory(dir): old_pwd = os.getcwd() try: os.chdir(dir) yield finally: os.chdir(old_pwd) WIKIROOT = '/home/hugo/wiki' WIKI_LIST = [] for file in os.listdir(WIKIROOT): path = os.path.join(WIKIROOT, file) if 'html' in file: continue if not os.path.isdir(path): continue WIKI_LIST.append(file) def git(*args): base = 'git -c color.status=always -c color.ui=always'.split(' ') # print('git', args) cmdline = base + list(args) # TODO subprocess can't forward stdout to our file-like object # and it doesn't tell us WHAT the problem is. # This probably requires us to set up a proper pipe, # and something which listen on that pipe. # But multithreading in Python is *HaRd*. cmd = subprocess.run(cmdline, stdout=sys.stdout) def commit(wiki, *msg): if not msg: now = datetime.now(Zoneinfo(time.tzname[0])) msg = f'{now:%Y-%m-%d %H:%M:%S %Z}' else: msg = ' '.join(msg) git('add', '-A') git('commit', '-m', msg) def ammend(wiki, *msg): if not msg: git('commit', '--amend') else: msg = ' '.join(msg) git('commit', '--amend', '-m', msg) def grep(wiki, *args): git('grep', '-E', '-i', ' '.join(args)) def go(*args): commit(wiki, *args) git('push') def echo(wiki, *rest): print(f'-- {wiki} --') commands = { 'commit': commit, 'ammend': ammend, 'grep': grep, 'g': go, 'go': go, 'echo': echo, } def wiki_do(wiki, command, *args): cmd = commands.get(command) with working_directory(os.path.join(WIKIROOT, wiki)): if cmd: cmd(wiki, *args) else: git(command, *args) class Prepender: def __init__(self, prefix, to): self.buf = [] self.prefix = prefix self.to = to def write(self, data): for c in data: if c == '\n': print(self.prefix + ':' + ''.join(self.buf), file=self.to) self.buf = [] else: self.buf.append(c) def flush(self): if self.buf: print(self.prefix + ':' + ''.join(self.buf), file=self.to) self.buf = [] def fileno(self): return -1 # def read(size=-1): # pass def main(): args = sys.argv[1:] wiki_list = [] while args: if args[0] == '-w' or args[0] == '--wiki': wiki_list.append(args[1]) args = args[2:] continue if args[0] == '-l' or args[0] == '--list': print("Available Wikis:") print("================") for wiki in WIKI_LIST: print(f' - {wiki}') sys.exit() if args[0] == '-h' or args[0] == '--help' or args[0] == '-?': help = ''' Wiki helper. Usage: --help | -h :: Display this help --list | -l :: Show available wikis --wiki | -w :: specify a specific wiki for operation Default acts on all wikis. wi commit [msg] :: Create a git commit on specified wikis wi ammend [msg] :: Change last commit wi g [msg] :: wi commit [msg]; wi push wi [git-command] :: run git commands on wikis ''' for line in help.strip().split('\n'): print(line.strip()) sys.exit() break if len(args) == 0: index = glob(os.path.join(WIKIROOT, (wiki_list or WIKI_LIST)[0], 'index.*')) subprocess.run(['vim', index[0]]) else: stdout = sys.stdout for wiki in wiki_list or WIKI_LIST: # TODO threads sys.stdout = Prepender(wiki, stdout) wiki_do(wiki, *args) if __name__ == '__main__': main()