User:OrphicBot/data tables sharder.py

from utils import readFile, reGroups, listNameToLua, progress, hashListByKey, dictToList, flatten, txtToFile, unique
from functools import reduce
from orphicbot import load, login, saveMW
from getpass import getpass

def hash(N,s) : return sum([x for x in s.encode('utf-8')])%N

def shardTable(fH, N, t, n) : return reduce(lambda ts,y: [[t if H != h else ((t[0], t[1] + [y[0]]),progress(y[1]))[0] for (t,h) in zip(ts,range(0,N))] for H in [fH(N,y[0][0])]][0], zip(t,range(0, len(t))), [(n,[]) for _ in range(0,N)])

def printShard(s, n) : return listNameToLua(s, n)

def printShards(nss) : return "\n\n".join([printShard(s,n) for (n,s) in nss]) + "\n\n" + "return {{{}}}".format(','.join(['["{}"]={}'.format(n,n) for (n,ss) in nss]))

def loadShards(ls) : return [(reGroups("local ([A-Za-z_0-9]*?)\s?=", ls[n][0:500])[0][0], [(x[0],[x[1]]) for x in reGroups('\["(.*?)"\]=\{"(.*?)"\}', ls[n])]) for n in [n for n in range(0, len(ls)) if ls[n][0:6]=="local "]]

def loadLua(fL,fn) : return fL(fn).split('\n')

def rewriteMetadata(l1, s1, ts) : return 'local metadata = {{ ["shard_location_base"]={{"Module:data tables/{}"}}, '.format(l1) + '["shards"]={{{}}}, '.format(s1) + '["tables"] = {{{}}}'.format(', '.join(['"{}"'.format(t[0]) for t in ts])) + " } \n\nreturn metadata"

def reshard(l0, l1, s0, s1, u0, fS) :	# l0 : old base name; l1 : new base name (possibly same) ; s1 : old shard count; s2 : new shard count; u0 : old unsharded count
  fss = [["Module:data tables/{}{}".format(l0, i) for i in range(0,s0)]+["Module:data tables/dataUnsharded{}".format(n) for n in range(0, u0)]]
  shardsListOld = flatten(flatten([[loadShards(loadLua(load, f)) for f in fs] for fs in fss]))
  shardsListsNew = list(zip(*[shardTable(hash, s1, flatten(ss), n) for (n,ss) in dictToList(hashListByKey(shardsListOld, lambda x: x[0], lambda x: x[1]))]))
  filesNew = [printShards(s) for s in shardsListsNew]
  savelist = []
  for (f,n) in zip(filesNew, range(0, len(filesNew))) : 
    progress((n,savelist.append(fS("Module:data tables/{}{}".format(l1,n), f, "Sharding {} tables to {} tables".format(s0, s1))))[0])
    if n == s1 -1 :
       ts = dictToList(hashListByKey([(u, sum([len(l[1]) for l in shardsListOld if l[0] == u])) for u in unique([x[0] for x in shardsListOld])], lambda x: x[0], lambda x: x[1]))
       savelist.append(fS(["Module:data tables/metadata"], rewriteMetadata(l1, s1, ts), ""))
       #create: emptyUnsharded()
    else : txtToFile(f, "data{}Shards\\test\\{}{}.txt".format(s1,l1,n))
  return savelist

CT = login(input("Username: "), getpass("Password: "))

save = lambda w,x,c : saveMW(CT, w,x,c)

fakesave = lambda w,x,c : (print("Nullary save function called."), "Nullary save function called.")[1]   

#savelist = reshard("data", "dataM", 3, 1000, 1, fakesave)