aboutsummaryrefslogtreecommitdiff
path: root/wiki
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-05-10 22:57:02 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-05-10 22:57:02 +0200
commit3cd9138c9d8fb9be248c75330cca9da47f4d2e8a (patch)
treeb3b677a9c1a474589f45d20953028a987fa73b80 /wiki
parent83f7fe4b8402bab171d110703a1b1115efbc9b28 (diff)
downloadbin-3cd9138c9d8fb9be248c75330cca9da47f4d2e8a.tar.gz
bin-3cd9138c9d8fb9be248c75330cca9da47f4d2e8a.zip
added a whole bunch of scripts
Diffstat (limited to 'wiki')
-rwxr-xr-xwiki341
1 files changed, 341 insertions, 0 deletions
diff --git a/wiki b/wiki
new file mode 100755
index 0000000..b629903
--- /dev/null
+++ b/wiki
@@ -0,0 +1,341 @@
+#!/usr/bin/python3
+# coding=utf-8
+#
+# See LICENSE.
+#
+# Copy me if you can.
+# by 20h
+#
+
+import os
+import sys
+import re
+import getopt
+import click
+import codecs
+from subprocess import Popen, PIPE
+
+DEFAULTBASE = "~/.psw"
+
+class git(object):
+ def __init__(self, base=None):
+ if base == None:
+ base = DEFAULTBASE
+ self.base = os.path.expanduser(base)
+ if not os.path.exists(self.base):
+ os.makedirs(self.base, 0o750)
+
+ if self.base[-1] != os.sep:
+ self.pages = "%s%s" % (self.base, os.sep)
+ else:
+ self.pages = self.base
+
+ self.keycache = None
+
+ """ I/O helper functions. """
+ def getfile(self, fi):
+ fd = codecs.open(fi, mode="r", encoding="utf-8")
+ text = fd.read()
+ fd.close()
+ return text
+
+ def putfile(self, fi, content):
+ os.makedirs(os.path.dirname(fi), exist_ok=True)
+ fd = codecs.open(fi, mode="w+", encoding="utf-8")
+ fd.write(content)
+ fd.close()
+ return None
+
+ def mkpath(self, path, fi=None):
+ if path[-1] != os.sep:
+ path = "%s%s" % (path, os.sep)
+ if fi != None:
+ path = "%s%s" % (path, fi)
+
+ return path
+
+ def recursedir(self, path):
+ subdirs = []
+ files = os.listdir(path)
+ files.sort()
+ for f in files:
+ npath = self.mkpath(path, f)
+ if os.path.isfile(npath) or \
+ os.path.islink(npath):
+ yield npath
+ else:
+ subdirs.append(f)
+
+ for s in subdirs:
+ npath = self.mkpath(path, s)
+ if s == ".git":
+ continue
+ for j in self.recursedir(npath):
+ yield j
+
+ def makesearchlist(self, fun, path):
+ li = []
+ npath = self.mkpath(path)
+ for i in fun(path):
+ i = i.replace(npath, "")
+ i = i.removesuffix(".md")
+ li.append(i)
+ return li
+
+ """ Git command functions. """
+ def git(self, args):
+ gitdir = "%s.git" % (self.pages)
+ workdir = self.pages
+ cmd = ["git", "--git-dir=%s" % gitdir, "--work-tree=%s" % workdir] + args
+
+ p = Popen(cmd, stdout=PIPE, stderr=PIPE)
+ result = p.stdout.read().decode("utf-8", errors="replace")
+
+ return [result, p.wait()]
+
+ def gitpath(self, file):
+ return "%s%s.md" % (self.pages, file)
+
+ def init(self):
+ self.git(["init"])
+
+ def add(self, file):
+ self.git(["add", file])
+
+ def rm(self, file):
+ self.git(["rm", file])
+
+ def mv(self, old, new):
+ self.git(["mv", old, new])
+
+ def commit(self, msg):
+ self.git(["commit", "--allow-empty", "--no-verify",
+ "--message=%s" % msg, "--author=psw <psw@psw>"])
+ self.git(["gc"])
+
+ def log(self, page):
+ changes = []
+ if page == "":
+ extra = []
+ else:
+ extra = ["--", self.gitpath(page)]
+ sep = "\x01"
+ (result, status) = self.git(
+ ["log", "--pretty=format:%%H%s%%T%s%%an%s%%ae%s%%aD%s%%s" % ((sep,) * 5)] + extra
+ )
+ for line in result.splitlines():
+ if not line.strip():
+ continue
+ entries = line.split(sep)
+ if len(entries) < 6:
+ continue
+ change = {}
+ change["commit"] = entries[0]
+ change["author"] = entries[2]
+ change["email"] = entries[3]
+ change["date"] = entries[4]
+ change["message"] = entries[5]
+ try:
+ (task, cpage) = entries[5].split(" ", 1)
+ except ValueError:
+ cpage = page
+ change["page"] = cpage
+ changes.append(change)
+
+ return changes
+
+ def showcommit(self, page, commit):
+ (file, status) = self.git(["cat-file", "-p", "%s:%s.md" % (commit, page)])
+ return file
+
+ """ Dictionary abstraction functions. """
+ def __setitem__(self, page, value):
+ file = self.gitpath(page)
+ needadd = False
+ if os.path.exists(file) == False:
+ needadd = True
+ self.putfile(file, value)
+
+ self.add(file)
+ if needadd:
+ self.commit("Added: %s" % (page))
+ else:
+ self.commit("Changed: %s" % (page))
+
+ def __delitem__(self, page):
+ file = self.gitpath(page)
+ os.remove(file)
+
+ self.rm(file)
+ self.commit("Deleted: %s" % (page))
+
+ def __getitem__(self, page):
+ try:
+ return self.getfile(self.gitpath(page))
+ except IOError as err:
+ return ""
+
+ def getlog(self, page):
+ log = self.log(page)
+ ret = ""
+ for i in log:
+ ret += "%s %s %s %s %s %s\n" % (i["commit"],
+ i["author"],
+ i["email"], i["date"], i["page"],
+ i["message"])
+ return ret
+
+ def mkkeycache(self):
+ if self.keycache == None:
+ self.keycache = self.makesearchlist(self.recursedir,
+ self.pages)
+
+ def keys(self):
+ self.mkkeycache()
+ return self.keycache
+
+ def __contains__(self, item):
+ return item in list(self.keys())
+
+ def search(self, query):
+ try:
+ pattern = re.compile(query)
+ except re.error as e:
+ sys.stderr.write("Invalid regex: %s\n" % e)
+ return []
+
+ name_hits = []
+ content_hits = []
+ seen = set()
+
+ for page in list(self.keys()):
+ if pattern.search(page):
+ name_hits.append(page)
+ seen.add(page)
+
+ for page in list(self.keys()):
+ if page in seen:
+ continue
+ try:
+ content = self.getfile(self.gitpath(page))
+ except OSError:
+ continue
+ for line in content.splitlines():
+ if pattern.search(line):
+ content_hits.append("%s: %s" % (page, line.strip()))
+ seen.add(page)
+ break
+
+ return name_hits + content_hits
+
+ def move(self, old, new):
+ opath = self.gitpath(old)
+ npath = self.gitpath(new)
+ self.mv(opath, npath)
+ self.commit("Moved: %s -> %s" % (old, new))
+
+def editor(content):
+ try:
+ data = click.edit(content, require_save=True, extension='.md')
+ except click.UsageError:
+ return (1, content)
+ if data == None:
+ return (1, content)
+
+ return (0, data)
+
+def usage(app):
+ app = os.path.basename(app)
+ sys.stderr.write("usage: %s [-oh] [-b base] [[-d|-e|-c|-s|-p] item" \
+ "|-l|-r old new]\n" % (app))
+ sys.exit(1)
+
+def main(args):
+ try:
+ opts, largs = getopt.getopt(args[1:], "hosplb:sdecr")
+ except getopt.GetoptError as err:
+ print(str(err))
+ usage(args[0])
+
+ dorm = False
+ doedit = False
+ docommit = False
+ dosearch = False
+ dolist = False
+ dorename = False
+ tostdout = False
+ base = DEFAULTBASE
+ for o, a in opts:
+ if o == "-h":
+ usage(args[0])
+ elif o == "-b":
+ base = a
+ elif o == "-c":
+ docommit = True
+ elif o == "-d":
+ dorm = True
+ elif o == "-e":
+ doedit = True
+ elif o == "-l":
+ dolist = True
+ elif o == "-o":
+ doedit = True
+ tostdout = True
+ elif o == "-p":
+ doedit = True
+ tostdout = True
+ elif o == "-r":
+ dorename = True
+ elif o == "-s":
+ dosearch = True
+ else:
+ assert False, "unhandled option"
+
+ val = ""
+ if doedit == True or dosearch == True or dorm == True or docommit == True:
+ if len(largs) < 1 and not docommit:
+ usage(args[0])
+ val = "_".join(largs)
+ elif dorename == True:
+ if len(largs) < 2:
+ usage(args[0])
+
+ lgit = git(base)
+
+ if doedit == True:
+ content = lgit[val]
+ if tostdout == True:
+ sys.stdout.write(content)
+ else:
+ (sts, data) = editor(content)
+ if data == content:
+ print("No changes made. Quitting.")
+ else:
+ print("Some changes made. Committing.")
+ lgit[val] = data
+ elif dorename == True:
+ lgit.move(largs[0], largs[1])
+ elif dorm == True:
+ del lgit[val]
+ elif docommit == True:
+ commits = lgit.getlog(val)
+ if tostdout == True:
+ sys.stdout.write(commits)
+ else:
+ p = Popen(["less"], stdin=PIPE)
+ p.communicate(input=commits.encode("utf-8"))
+ elif dosearch == True:
+ results = lgit.search(val)
+ for r in results:
+ print(r)
+ elif dolist == True:
+ for k in list(lgit.keys()):
+ print(k)
+ else:
+ usage(args[0])
+
+ return 0
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv))
+