Mercurial > hg > python
view repair.py @ 66:53c37a02d471
working, I think/hope
author | Henry S. Thompson <ht@inf.ed.ac.uk> |
---|---|
date | Thu, 14 Dec 2023 20:17:48 +0000 |
parents | 5e5feacb730d |
children |
line wrap: on
line source
#!/usr/bin/python3 import sys import lisparser def readAlist(fn): with open(fn,'r') as f: sline = f.readline() alines = (l for l in f if (L:=l).startswith("(")) return sline, alist(alines), L # alist fields are: group, rank, read, [marks, [method, [params]]] # string int [list] [plist] expr plist def alist(lines): res = {} for l in lines: ll = lisparser.get_ast(lisparser.normalize_str(l))[0] k = ll.pop(0) n = int(ll.pop(0)) res[eval(k)]=[n]+al2p(ll) return res def al2p(ll): '''handle read (list or nil), maybe marks (plist or nil), usually method, maybe params (plist)''' res=[ll.pop(0)] # read if ll: marks = ll.pop(0) if marks != 'nil': marks = dict((e[0],e[1:]) for e in marks) res.append(marks) else: return res if ll: res.append(ll.pop(0)) # method else: return res if ll: params = ll.pop(0) if params == 'nil': res.append(params) else: res.append(dict((e[0],e[1:]) for e in params)) # params else: return res if ll: raise ValueError("too many args: %s"%ll) return res def p2l(pl, f): if isinstance(pl,list) or isinstance(pl,tuple): if len(pl) == 0: f.write('nil') else: f.write('(') space = False for e in pl: if space: f.write(' ') p2l(e,f) else: p2l(e,f) space = True f.write(')') elif isinstance(pl,dict): f.write('(') space = False for k, v in pl.items(): if space: f.write(' (') else: f.write('(') space = True f.write(k) for e in v: f.write(' ') p2l(e,f) f.write(')') f.write(')') # elif isinstance(pl,str): # if pl in ['.','nil']: # f.write(pl) # else: # try: # int(pl) # f.write(pl) # except ValueError: # f.write(pl) else: f.write(pl) def mergeOne(gv,mv): '''rank: deeper in gnus wins read: if unequal if mail is nil, use gnus otherwise use mail marks: merge unseen keys, unequal values for same key prefer gnus EXCEPT bogus, w3c-ac-forum, handle by hand DONE method: change "ht" to "nnml+ht" FIX group-2002-07 in gnus by hand DONE params: merge by keys ''' res = mv.copy() if gv[0] > res[0]: # rank res[0] = gv[0] if res[1] == 'nil': # read res[1] = gv[1] if res[2] != gv[2]: # marks if res[2] == 'nil': res[2] = gv[2] else: for k, v in gv[2].items(): # fill in missing, override unequal, if equal no harm done res[2][k] = v # we prefer m to g for method if len(res) == 4: # no params if len(gv) == 5: res.append(gv[4]) elif len(gv) == 5: if res[4] != gv[4]: for k, v in gv[4].items(): # fill in missing, override unequal, if equal no harm done res[4][k] = v return res def lineout(k,res,outf): outf.write('("%s" '%k) outf.write(str(res[0])) # rank for v in res[1:]: outf.write(' ') p2l(v,outf) outf.write(')\n') def merge(gnus, mail, out): ''' rank, read, marks, method, params read is everything that is unmarked (nothing in left column) marks.seen is everything that has ever been looked it and not DELETED marks.tick is a !, marks.forward is F, marks.reply is A. ''' # ' global g, m g1, g, g2 = readAlist(gnus) _, m, _ = readAlist(mail) with open(out, "w") as outf: outf.write(g1) for k, v in g.items(): if k in m: res = mergeOne(v, m[k]) else: res = v lineout(k,res,outf) for k, v in m.items(): if k not in g: lineout(k,v,outf) outf.write(g2) def stale(): ''' Comparison tool: Watch out for tabs! To look for overlap, change 2nd \n in printf to \t export T=$'\t' export B1="(\(\([^()]\+\|([^)]*)\) \?\)*)" export P1="\(nil\|$B1\)" export P2="\(nil\|\((\($B1 \?\)*)\)\)" export MA='\("[^"]*"\|(nndraft "")\)' fgrep -hf shared {gnus,mail}/alist.fixed | sed 's/ \([0-9]\) '"$P1 $P2 / \1 \2 \5 /;s/\(.*${T}.*${T}.*${T}\)$MA $P2/\1\2${T}\4/" paste <(cat shared) <(fgrep -f shared mail/alist.fixed | sed 's/ \([0-9]\) '"$P $P/ \1 \2 \5 /g" | cut -f 3) <(fgrep -f shared gnus/alist.fixed | sed 's/ \([0-9]\) '"$P $P/ \1 \2 \5 /g" | cut -f 3) | { IFS=' ' ; while read gn g m; do if [ "$g" != "$m" ]; then printf "=----%s------\n%s\n%s\n" "$gn" "$g" "$m"; fi; done ; } | less ''' if __name__ == '__main__': merge(*sys.argv[1:])