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)