initial
This commit is contained in:
commit
7a08a7fef2
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
output/*
|
||||||
|
graphs/*
|
||||||
|
network.json
|
||||||
|
__pycache__/*
|
||||||
|
.tags
|
||||||
|
.vimwiki_tags
|
||||||
|
.vim/*
|
||||||
|
censor.py
|
68
TagHelper.py
Normal file
68
TagHelper.py
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
import ctags
|
||||||
|
from ctags import CTags, TagEntry
|
||||||
|
import sys
|
||||||
|
from icecream import ic
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import fileinput
|
||||||
|
|
||||||
|
def loadTagFile(path='.vimwiki_tags'):
|
||||||
|
# Available file information keys:
|
||||||
|
# opened - was the tag file successfully opened?
|
||||||
|
# error_number - errno value when 'opened' is false
|
||||||
|
# format - format of tag file (1 = original, 2 = extended)
|
||||||
|
# sort - how is the tag file sorted?
|
||||||
|
# author - name of author of generating program (may be empy string)
|
||||||
|
# name - name of program (may be empy string)
|
||||||
|
# url - URL of distribution (may be empy string)
|
||||||
|
# version - program version (may be empty string)
|
||||||
|
try:
|
||||||
|
tagFile = CTags(path)
|
||||||
|
return tagFile
|
||||||
|
except:
|
||||||
|
print("No tagfile at {}".farmat(path))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def makeSetFromTags(tagFile, key='file'):
|
||||||
|
# Available TagEntry keys:
|
||||||
|
# name - name of tag
|
||||||
|
# file - path of source file containing definition of tag
|
||||||
|
# pattern - pattern for locating source line (None if no pattern)
|
||||||
|
# lineNumber - line number in source file of tag definition (may be zero if not known)
|
||||||
|
# kind - kind of tag (none if not known)
|
||||||
|
# fileScope - is tag of file-limited scope?
|
||||||
|
|
||||||
|
# Note: other keys will be assumed as an extension key and will
|
||||||
|
# return None if no such key is found
|
||||||
|
entry = TagEntry()
|
||||||
|
tag = tagFile.next(entry)
|
||||||
|
AllFileList = set()
|
||||||
|
while tag:
|
||||||
|
AllFileList.add(entry[key].decode())
|
||||||
|
tag = tagFile.next(entry)
|
||||||
|
return AllFileList
|
||||||
|
|
||||||
|
def makeDictFromTags(tagFile, key='name', value='file'):
|
||||||
|
entry = TagEntry()
|
||||||
|
tag = tagFile.next(entry)
|
||||||
|
ret = {}
|
||||||
|
while tag:
|
||||||
|
# Not sure why they're being read as bytes now?
|
||||||
|
strKey = entry[key].decode()
|
||||||
|
strValue = entry[value].decode()
|
||||||
|
if strKey not in ret.keys():
|
||||||
|
ret[strKey] = set(strValue)
|
||||||
|
else:
|
||||||
|
ret[strKey].add(strValue)
|
||||||
|
tag = tagFile.next(entry)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def getAllFiles():
|
||||||
|
# Returns a set containing all the files we wish to make public
|
||||||
|
return makeSetFromTags(loadTagFile())
|
||||||
|
|
||||||
|
def getAllTags():
|
||||||
|
# Returns a dictionary with:
|
||||||
|
# - key as tag titles
|
||||||
|
# - values as files that have the key in their tags
|
||||||
|
return makeDictFromTags(loadTagFile())
|
21
flake.nix
Normal file
21
flake.nix
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
{
|
||||||
|
description = "Sketches in Quil";
|
||||||
|
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.url = "github:nixos/nixpkgs";
|
||||||
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
|
};
|
||||||
|
|
||||||
|
outputs = { self, nixpkgs, flake-utils }:
|
||||||
|
flake-utils.lib.eachDefaultSystem (system:
|
||||||
|
let pkgs = nixpkgs.legacyPackages.${system};
|
||||||
|
in {
|
||||||
|
devShell = pkgs.mkShell {
|
||||||
|
buildInputs = [
|
||||||
|
pkgs.leiningen
|
||||||
|
pkgs.jdk11
|
||||||
|
pkgs.clojure
|
||||||
|
];
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
100
makePublic.py
Normal file
100
makePublic.py
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
#! /usr/bin/env python3
|
||||||
|
# Various methods of grabbing files from Kitaab based on their ctags as generated by vimwiki
|
||||||
|
# censor - burn all mentions of this word wherever it appears in Kitaab
|
||||||
|
# filter - leave names in tact but do not link to relevant documents
|
||||||
|
# create - list in an index file for website
|
||||||
|
from os import listdir, mkdir
|
||||||
|
from os.path import isfile, join
|
||||||
|
import shutil
|
||||||
|
import random
|
||||||
|
import TagHelper
|
||||||
|
import censor as cen
|
||||||
|
from icecream import ic
|
||||||
|
|
||||||
|
## TODO: generalize based on headings(?) in index.wiki
|
||||||
|
|
||||||
|
censor = cen.listBad
|
||||||
|
filter = ["Dream", "Gratitude", "Review", "jrnl", "piracy", "work", "job", "debt", "people"]
|
||||||
|
#TODO create = ...
|
||||||
|
|
||||||
|
def loadNetwork(path='network.json'):
|
||||||
|
# Loads the network.json file
|
||||||
|
with open(path, 'r') as f:
|
||||||
|
everything = json.load(f)
|
||||||
|
return everything
|
||||||
|
|
||||||
|
def setNetwork(everything):
|
||||||
|
# Everything is loaded from the network.json file
|
||||||
|
keys = set(everything.network())
|
||||||
|
values = set(everything.values())
|
||||||
|
everything = network + values
|
||||||
|
return everything
|
||||||
|
|
||||||
|
def filterFiles(AllFileList):
|
||||||
|
toFilter = filter + censor
|
||||||
|
tagList = TagHelper.getAllTags()
|
||||||
|
doNotTakeFiles = set()
|
||||||
|
for mask in toFilter:
|
||||||
|
try:
|
||||||
|
doNotTakeFiles.update(tagList[mask])
|
||||||
|
except KeyError:
|
||||||
|
print("Key not found: {}".format(mask))
|
||||||
|
return AllFileList - doNotTakeFiles
|
||||||
|
|
||||||
|
def censorNetwork(network):
|
||||||
|
# Takes network as a set
|
||||||
|
for c in censor:
|
||||||
|
if c in network:
|
||||||
|
network.add(generateBlocks(len(c) + random.randint(0, 5)))
|
||||||
|
network.remove(c)
|
||||||
|
return network
|
||||||
|
|
||||||
|
def generateBlocks(size=1):
|
||||||
|
# Generates a length size unicode string that is formed from blocks:
|
||||||
|
charList = ['▐', '░', '▒', '▓', '▔', '▕', '▖▗', '▘▙', '▚', '▛', '▜', '▝', '▞', '▟']
|
||||||
|
ret = ""
|
||||||
|
while size > 0:
|
||||||
|
size = size - 1
|
||||||
|
rand = random.randint(0,13)
|
||||||
|
ret = ret + charList[rand]
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def createIndexNode(network):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def copyFiles(fileList):
|
||||||
|
baseFilePath = '/home/anish/vimwiki/'
|
||||||
|
try:
|
||||||
|
mkdir('output')
|
||||||
|
except FileExistsError:
|
||||||
|
pass
|
||||||
|
for f in fileList:
|
||||||
|
try:
|
||||||
|
shutil.copy(baseFilePath + f, './output/')
|
||||||
|
except FileNotFoundError:
|
||||||
|
print("Could not copy file {}:".format(baseFilePath + f))
|
||||||
|
|
||||||
|
def censorFiles():
|
||||||
|
outputBasePath = './output/'
|
||||||
|
for fileName in listdir(outputBasePath):
|
||||||
|
fileName = outputBasePath + fileName
|
||||||
|
newFile = ""
|
||||||
|
print("Censoring: {}".format(fileName))
|
||||||
|
with open(fileName, 'r') as f:
|
||||||
|
for line in f.readlines():
|
||||||
|
for c in censor:
|
||||||
|
line = line.replace(c, generateBlocks(len(c)))
|
||||||
|
newFile = newFile + line
|
||||||
|
with open(fileName, 'w') as f:
|
||||||
|
for line in newFile:
|
||||||
|
f.write(line)
|
||||||
|
|
||||||
|
if __name__=='__main__':
|
||||||
|
|
||||||
|
#network = loadNetwork()
|
||||||
|
#network = censorNetwork(network)
|
||||||
|
AllFiles = TagHelper.getAllFiles()
|
||||||
|
FilteredFiles = filterFiles(AllFiles)
|
||||||
|
copyFiles(FilteredFiles)
|
||||||
|
print("Censoring files...")
|
||||||
|
censorFiles()
|
25
network-builder.py
Normal file
25
network-builder.py
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
import json
|
||||||
|
import networkx as nx
|
||||||
|
import pygraphviz
|
||||||
|
|
||||||
|
def loadJson(file):
|
||||||
|
with open(file, 'r') as f:
|
||||||
|
return json.load(f)
|
||||||
|
|
||||||
|
def makeNetwork(json):
|
||||||
|
G = nx.DiGraph()
|
||||||
|
for (key, value) in json.items():
|
||||||
|
G.add_nodes_from([key] + value)
|
||||||
|
G.add_edges_from([(key, v) for v in value])
|
||||||
|
return G
|
||||||
|
|
||||||
|
def makeAGraph(graph):
|
||||||
|
G = nx.nx_agraph.to_agraph(graph)
|
||||||
|
G.draw("nop.png", prog="nop")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
OUTFILE = 'network.json'
|
||||||
|
json = loadJson('network.json')
|
||||||
|
graph = makeNetwork(json)
|
||||||
|
with open(OUTFILE, 'w') as f:
|
||||||
|
json.dump(f, makeAGraph(graph))
|
21
readme.md
Normal file
21
readme.md
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# Kitaab helper
|
||||||
|
|
||||||
|
Helps make my Kitaab public by grabbing Kitaab, filtering & censoring it, and then passing it through to an SSG to make HTML out of a markdown page.
|
||||||
|
|
||||||
|
### Files
|
||||||
|
makePublic.py
|
||||||
|
- the whole filter pipeline
|
||||||
|
|
||||||
|
TagHelper.py
|
||||||
|
- Reads the .vimwiki_tags file that is generated by vimwiki
|
||||||
|
|
||||||
|
tree.py
|
||||||
|
- builds a tree out of all the links using dfs
|
||||||
|
|
||||||
|
network-builder.py
|
||||||
|
- uses the network from tree.py to visualize links
|
||||||
|
|
||||||
|
tag-fixer.py
|
||||||
|
- old script used to fix problem tags (1 character tags)
|
||||||
|
- (TODO) tags that are case sensitive
|
||||||
|
|
20
shell.nix
Normal file
20
shell.nix
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
# shell.nix
|
||||||
|
{ pkgs ? import <nixpkgs> {} }:
|
||||||
|
let
|
||||||
|
my-python = pkgs.python3;
|
||||||
|
python-with-my-packages = my-python.withPackages (p: with p; [
|
||||||
|
icecream
|
||||||
|
# other python packages you want
|
||||||
|
]);
|
||||||
|
in
|
||||||
|
pkgs.mkShell {
|
||||||
|
buildInputs = [
|
||||||
|
python-with-my-packages
|
||||||
|
# other dependencies
|
||||||
|
];
|
||||||
|
shellHook = ''
|
||||||
|
PYTHONPATH=${python-with-my-packages}/${python-with-my-packages.sitePackages}
|
||||||
|
# maybe set more env-vars
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
|
100
tag-fixer.py
Normal file
100
tag-fixer.py
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
#! /usr/bin/env python3
|
||||||
|
|
||||||
|
import ctags
|
||||||
|
from ctags import CTags, TagEntry
|
||||||
|
import sys
|
||||||
|
from icecream import ic
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import fileinput
|
||||||
|
|
||||||
|
def loadTagFile(path='.vimwiki_tags'):
|
||||||
|
# Available file information keys:
|
||||||
|
# opened - was the tag file successfully opened?
|
||||||
|
# error_number - errno value when 'opened' is false
|
||||||
|
# format - format of tag file (1 = original, 2 = extended)
|
||||||
|
# sort - how is the tag file sorted?
|
||||||
|
# author - name of author of generating program (may be empy string)
|
||||||
|
# name - name of program (may be empy string)
|
||||||
|
# url - URL of distribution (may be empy string)
|
||||||
|
# version - program version (may be empty string)
|
||||||
|
try:
|
||||||
|
tagFile = CTags(path)
|
||||||
|
return tagFile
|
||||||
|
except:
|
||||||
|
print("No tagfile at {}".farmat(path))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
def loopThrough(tagFile):
|
||||||
|
# Available TagEntry keys:
|
||||||
|
# name - name of tag
|
||||||
|
# file - path of source file containing definition of tag
|
||||||
|
# pattern - pattern for locating source line (None if no pattern)
|
||||||
|
# lineNumber - line number in source file of tag definition (may be zero if not known)
|
||||||
|
# kind - kind of tag (none if not known)
|
||||||
|
# fileScope - is tag of file-limited scope?
|
||||||
|
|
||||||
|
# Note: other keys will be assumed as an extension key and will
|
||||||
|
# return None if no such key is found
|
||||||
|
''' Entries that are less than 1 character in length are errors
|
||||||
|
Returns a set containing of all the files with errors in their tags'''
|
||||||
|
entry = TagEntry()
|
||||||
|
tag = tagFile.next(entry)
|
||||||
|
tagErrors = set()
|
||||||
|
errorTagNames = set()
|
||||||
|
while tag:
|
||||||
|
if len(entry['name']) <= 1:
|
||||||
|
tagErrors.add(entry['file'])
|
||||||
|
errorTagNames.add(entry['name'])
|
||||||
|
else:
|
||||||
|
print("Good tag found: {}".format(entry['name']))
|
||||||
|
tag = tagFile.next(entry)
|
||||||
|
ic(errorTagNames)
|
||||||
|
return tagErrors
|
||||||
|
|
||||||
|
def fixErrors(errors):
|
||||||
|
''' Replaces :: with :, which seems to be the error for many of the tags '''
|
||||||
|
fileBase = '/home/anish/vimwiki/'
|
||||||
|
for v in errors:
|
||||||
|
print("Fixing {}...".format(v))
|
||||||
|
fileName = fileBase + getFileName(v)
|
||||||
|
newFile = ""
|
||||||
|
with open(fileName, 'r') as f:
|
||||||
|
for line in f.readlines():
|
||||||
|
line = line.replace("::", ":")
|
||||||
|
newFile = newFile + line
|
||||||
|
with open(fileName, 'w') as f:
|
||||||
|
for line in newFile:
|
||||||
|
f.write(line)
|
||||||
|
print("Written new file...")
|
||||||
|
print()
|
||||||
|
print(newFile)
|
||||||
|
|
||||||
|
def printErrors(errors):
|
||||||
|
fileBase = '/home/anish/vimwiki/'
|
||||||
|
for v in errors:
|
||||||
|
fileName = fileBase + getFileName(v)
|
||||||
|
print("Reading {}...".format(v))
|
||||||
|
with open(fileName, 'r') as f:
|
||||||
|
f.readline()
|
||||||
|
ic(f.readline())
|
||||||
|
|
||||||
|
def getFileName(f):
|
||||||
|
return str(f, encoding="utf-8")
|
||||||
|
|
||||||
|
def getBackupFiles(errors):
|
||||||
|
fileBase = '/home/anish/vimwiki/'
|
||||||
|
backupBase = '/home/anish/vimwiki/jrnl/'
|
||||||
|
for files in errors.values():
|
||||||
|
for f in files:
|
||||||
|
f = getFileName(f)
|
||||||
|
print("Moving {} from backup".format(f))
|
||||||
|
shutil.copy(backupBase + f, fileBase + f)
|
||||||
|
|
||||||
|
if __name__=='__main__':
|
||||||
|
tagFile = loadTagFile()
|
||||||
|
errors = loopThrough(tagFile)
|
||||||
|
printErrors(errors)
|
||||||
|
#ic(errors)
|
||||||
|
#getBackupFiles(errors)
|
||||||
|
#fixErrors(errors)
|
120
tree.py
Normal file
120
tree.py
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
#! /usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from icecream import ic
|
||||||
|
import json
|
||||||
|
|
||||||
|
"""network-vimwiki.py
|
||||||
|
Create site map for vimwiki.
|
||||||
|
Must run script under vimwiki directory.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
output network map to network.json
|
||||||
|
dfsvw.py
|
||||||
|
|
||||||
|
Python version: 3"""
|
||||||
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
|
linkRE = re.compile(r'\[\[([^\\\]|#]+)(?:#[^\\\]|]+)?(?:\|([^\\\]]+))?\]\]', re.UNICODE)
|
||||||
|
|
||||||
|
def probeLink(s):
|
||||||
|
"""
|
||||||
|
>>> probeLink(' abc')
|
||||||
|
[]
|
||||||
|
>>> probeLink(' [[]]')
|
||||||
|
[]
|
||||||
|
>>> probeLink(' [[abc]] [[abc|123]] ')
|
||||||
|
[('abc', ''), ('abc', '123')]
|
||||||
|
>>> a, b = probeLink(' [[中文1|中文2]]')[0]; print a, b
|
||||||
|
中文1 中文2
|
||||||
|
>>> probeLink(' [[abc|abc 123]]')
|
||||||
|
[('abc', 'abc 123')]
|
||||||
|
"""
|
||||||
|
ret = linkRE.findall(s)
|
||||||
|
return [(a, b) for a, b in ret]
|
||||||
|
|
||||||
|
|
||||||
|
def probeAllLink(fn):
|
||||||
|
"""extract all link in a wiki file"""
|
||||||
|
try:
|
||||||
|
lst = []
|
||||||
|
print(fn)
|
||||||
|
fp = open(fn)
|
||||||
|
for line in fp.readlines():
|
||||||
|
l = probeLink(line)
|
||||||
|
lst.extend(l)
|
||||||
|
except IOError:
|
||||||
|
print("cannot open",sys.stderr)
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
lst = []
|
||||||
|
fp = open(fn, encoding="utf-16BE")
|
||||||
|
for line in fp.readlines():
|
||||||
|
l = probeLink(line)
|
||||||
|
lst.extend(l)
|
||||||
|
return lst
|
||||||
|
|
||||||
|
|
||||||
|
def outputNode(link, name, level):
|
||||||
|
"""output one wiki node, level for vimwiki tree hierarchy"""
|
||||||
|
""" Unused """
|
||||||
|
prefix = " " * 4 * level
|
||||||
|
if not name:
|
||||||
|
name = link
|
||||||
|
dct = {"prefix":prefix, "link":link, "name":name}
|
||||||
|
if sys.stdout.isatty():
|
||||||
|
fmt = "{prefix}{name}"
|
||||||
|
else:
|
||||||
|
if link == name:
|
||||||
|
fmt = "{prefix}[[{name}]]"
|
||||||
|
else:
|
||||||
|
fmt = "{prefix}[[{link}|{name}]]"
|
||||||
|
print(fmt.format(**dct))
|
||||||
|
|
||||||
|
def addNode(link, node, name, graph):
|
||||||
|
""" adds a node to the dictionary that tracks edges"""
|
||||||
|
if name:
|
||||||
|
node = name
|
||||||
|
if link in graph.keys():
|
||||||
|
graph[link].add(node)
|
||||||
|
else:
|
||||||
|
graph[link] = {node}
|
||||||
|
|
||||||
|
def bfs(index):
|
||||||
|
"""breath first search on vimwiki
|
||||||
|
keep seen and unseen to track which files to search
|
||||||
|
ugly loops instead of recursive setup """
|
||||||
|
seen = set()
|
||||||
|
unseen = [index]
|
||||||
|
graph = {}
|
||||||
|
filecount = 0
|
||||||
|
while 1:
|
||||||
|
try:
|
||||||
|
link = unseen.pop(0)
|
||||||
|
except IndexError:
|
||||||
|
print("Search complete...")
|
||||||
|
ic(filecount)
|
||||||
|
return graph
|
||||||
|
seen.add(link)
|
||||||
|
ret = probeAllLink(link + '.wiki')
|
||||||
|
for (node, name) in ret:
|
||||||
|
addNode(link, node, name, graph)
|
||||||
|
if not node in seen:
|
||||||
|
unseen.append(node)
|
||||||
|
filecount = filecount + 1
|
||||||
|
ic(filecount)
|
||||||
|
ic(seen)
|
||||||
|
|
||||||
|
def transformGraph(graph):
|
||||||
|
for key, value in graph.items():
|
||||||
|
graph[key] = list(value)
|
||||||
|
return graph
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
graph = bfs('index')
|
||||||
|
print("Transforming Graph...")
|
||||||
|
graph = transformGraph(graph)
|
||||||
|
print("Transform Complete...")
|
||||||
|
ic(graph)
|
||||||
|
print("Outputting file")
|
||||||
|
with open('network.json', 'w+') as out:
|
||||||
|
json.dump(graph, out)
|
Loading…
Reference in a new issue