class PgnInfo(e): def __init__(self, parent, pgnlistparent): super().__init__("div") self.headers = [] self.parent = parent self.pgnlistparent = pgnlistparent def getheader(self, key, default): for header in self.headers: if header[0] == key: return header[1] return default def playerlink(self, username): return "<a href='https://lichess.org/@/{}' target='_blank' rel='noopener noreferrer'>{}</a>".format(username, username) def parsecontent(self): lines = self.content.split("\n") self.headers = [] for line in lines: if line[0] == "[": parts = line[1:].split("\"") key = parts[0].split(" ")[0] value = parts[1].split("\"")[0] self.headers.append((key, value)) self.white = self.getheader("White", "?") self.black = self.getheader("Black", "?") self.result = self.getheader("Result", "?") self.site = self.getheader("Site", "") self.whiteelo = self.getheader("WhiteElo", "?") self.whiteratingdiff = self.getheader("WhiteRatingDiff", "?") self.blackelo = self.getheader("BlackElo", "?") self.blackratingdiff = self.getheader("BlackRatingDiff", "?") self.variant = self.getheader("Variant", "Standard") self.timecontrol = self.getheader("TimeControl", "?") self.utcdate = self.getheader("UTCDate", "?") self.id = self.site.split("/")[-1:][0] def idclicked(self): self.parent.loadedgameid = self.id self.parent.loadedgameside = "white" if self.meblack(): self.parent.loadedgameside = "black" self.parent.pgntext.setpgn(self.content) self.bds("dotted").bdw("6").bdc("#00f") localStorage.setItem("pgninfo/idclicked", self.id) self.pgnlistparent.bookmarkedpi = self getconn().sioreq({ "kind": "parsepgn", "owner": self.parent.id, "data": self.content }) def mecolor(self): if self.white == self.parent.username: return WHITE if self.black == self.parent.username: return BLACK return None def mewhite(self): return self.mecolor() == WHITE def meblack(self): return self.mecolor() == BLACK def hasme(self): return not ( self.mecolor() is None ) def score(self): if self.result == "1-0": return 1 if self.result == "0-1": return 0 return 0.5 def mescore(self): if self.hasme(): if self.mewhite(): return self.score() return 1 - self.score() return self.score() def meratinginfo(self): if self.hasme(): if self.mewhite(): return [ self.whiteelo, self.whiteratingdiff ] return [ self.blackelo, self.blackratingdiff ] return None def build(self): self.x().ac("pgninfocontainer") self.tcdiv = Div().ac("pgninfotcdiv").html("{} {}".format(self.timecontrol, self.variant)) self.whitediv = Div().ac("pgninfoplayerdiv").html(self.playerlink(self.white)) self.whiteelodiv = Div().ac("pgninfoplayerelodiv").html("{} {}".format(self.whiteelo, self.whiteratingdiff)) if self.meblack(): self.whitediv.ac("pgninfotheyplayerdiv") self.blackdiv = Div().ac("pgninfoplayerdiv").html(self.playerlink(self.black)) self.blackelodiv = Div().ac("pgninfoplayerelodiv").html("{} {}".format(self.blackelo, self.blackratingdiff)) if self.mewhite(): self.blackdiv.ac("pgninfotheyplayerdiv") self.resultdiv = Div().ac("pgninforesultdiv").html(self.result) self.iddiv = Div().ac("pgninfoiddiv").html(self.id) self.iddiv.ae("mousedown", self.idclicked) mescore = self.mescore() if mescore == 1: self.ac("pgninfowhitewin") elif mescore == 0: self.ac("pgninfoblackwin") else: self.ac("pgninfodraw") self.a([self.tcdiv, self.whitediv, self.whiteelodiv, self.blackdiv, self.blackelodiv, self.resultdiv, self.iddiv]) if self.id == localStorage.getItem("pgninfo/idclicked"): self.bds("dashed").bdw("6").bdc("#00f") return self def setcontent(self, content): self.content = content self.parsecontent() return self.build()
class MultipvInfo(e): def bestmovesanclickedfactory(self, moveuci, dostore = False): def bestmovesanclicked(): if not ( self.bestmovesanclickedcallback is None ): self.bestmovesanclickedcallback(moveuci, dostore) return bestmovesanclicked def scorebonus(self): if "scorebonus" in self.infoi: try: scorebonus = int(self.infoi["scorebonus"]) return scorebonus except: pass return 0 def effscore(self): return self.scorenumerical + self.scorebonus() def bonussliderchanged(self): self.infoi["scorebonus"] = self.bonusslider.v() self.build() if not ( self.bonussliderchangedcallback is None ): self.bonussliderchangedcallback() def traincombochanged(self): self.infoi["metrainweight"] = self.metraincombo.v() self.infoi["opptrainweight"] = self.opptraincombo.v() self.build() def build(self, gamesan = None): self.bestmoveuci = self.infoi["bestmoveuci"] self.bestmovesan = self.infoi["bestmovesan"] self.scorenumerical = self.infoi["scorenumerical"] self.pvsan = self.infoi["pvsan"] self.pvsans = self.pvsan.split(" ") if len(self.pvsans) > ( self.pvlength + 1 ): self.pvsans = self.pvsans[0:self.pvlength + 1] if len(self.pvsans) > 1: self.pvsans = self.pvsans[1:] self.showpv = " ".join(self.pvsans) self.pvpgn = self.infoi["pvpgn"] self.depth = self.infoi["depth"] self.nps = self.infoi["nps"] self.container = Div().ac("multipvinfocontainer") self.idiv = Div().ac("multipvinfoi").html("{}.".format(self.i)) self.bestmovesandiv = Div().ac("multipvinfobestmovesan").html(self.bestmovesan) if gamesan == self.bestmovesan: self.bestmovesandiv.bc("#fbf") self.bestmovesandiv.ae("mousedown", self.bestmovesanclickedfactory(self.bestmoveuci)) self.scorenumericaldiv = Div().ac("multipvinfoscorenumerical").html("{}".format(scoreverbal(self.effscore()))).cp() self.scorenumericaldiv.ae("mousedown", self.bestmovesanclickedfactory(self.bestmoveuci, True)) self.bonussliderdiv = Div().ac("multipvinfobonussliderdiv") self.bonusslider = Slider().setmin(-500).setmax(500).ac("multipvinfobonusslider").sv(self.scorebonus()) self.bonusslider.ae("change", self.bonussliderchanged) self.bonussliderdiv.a(self.bonusslider) self.depthdiv = Div().ac("multipvinfodepth").html("{}".format(self.depth)) self.miscdiv = Div().ac("multipvinfomisc").html("nps {}".format(self.nps)) self.traindiv = Div().ac("multipvinfomisc").w(100) metrainweight = self.infoi["metrainweight"] hasmetrain = False if not metrainweight: metrainweight = "0" opptrainweight = self.infoi["opptrainweight"] hasopptrain = False if not opptrainweight: opptrainweight = "0" try: if int(metrainweight) > 0: hasmetrain = True if int(opptrainweight) > 0: hasopptrain = True except: pass if hasmetrain and hasopptrain: self.trainbc = "#00f" elif hasmetrain: self.trainbc = "#0f0" elif hasopptrain: self.trainbc = "#f00" else: self.trainbc = "inherit" self.metrainweight = int(metrainweight) self.opptrainweight = int(opptrainweight) self.avgtrainweight = ( self.metrainweight + self.opptrainweight ) / 2.0 self.trainop = self.avgtrainweight / 10.0 self.metraincombo = ComboBox().setoptions(TRAIN_OPTIONS, metrainweight, self.traincombochanged) self.opptraincombo = ComboBox().setoptions(TRAIN_OPTIONS, opptrainweight, self.traincombochanged) self.traindiv.a([self.metraincombo, self.opptraincombo]) self.pvdiv = Div().ac("multipvinfopv").html(self.showpv).c("#070").fw("bold") self.container.a([self.idiv, self.bestmovesandiv, self.scorenumericaldiv, self.bonussliderdiv, self.traindiv, self.depthdiv, self.pvdiv]) self.container.bc(self.trainbc) self.bestmovesandiv.c(scorecolor(self.effscore())) self.scorenumericaldiv.c(scorecolor(self.effscore())) self.x().a(self.container) def __init__(self, infoi, pvlength = 4): super().__init__("div") self.pvlength = pvlength self.bestmovesanclickedcallback = None self.bonussliderchangedcallback = None self.infoi = infoi self.i = self.infoi["i"] self.build()
class BasicBoard(e): def clearcanvases(self): self.movecanvas.clear() self.piececanvashook.x() self.arrowdiv.x() def ucitosquare(self, squci): try: file = squci.charCodeAt(0) - "a".charCodeAt(0) rank = self.lastrank - ( squci.charCodeAt(1) - "1".charCodeAt(0) ) return Square(file, rank) except: return None def ucitomove(self, moveuci): if "@" in moveuci: try: parts = moveuci.split("@") sq = self.ucitosquare(parts[1]) move = Move(sq, sq, Piece(parts[0].toLowerCase(), self.turn())) return move except: return None else: try: move = Move(self.ucitosquare(moveuci[0:2]), self.ucitosquare(moveuci[2:4])) try: if len(moveuci) > 4: move.prompiece = Piece(moveuci[4].toLowerCase(), self.turn()) except: print("could not parse prompiece") return move except: return None def resize(self, width, height): self.squaresize = 35 self.calcsizes() while self.totalheight() < height: self.squaresize += 1 self.calcsizes() self.squaresize -= 1 self.calcsizes() self.build() def totalheight(self): th = self.outerheight + cpick(self.showfen, self.fendivheight, 0) if self.variantkey == "crazyhouse": th += 2 * self.squaresize return th def squareuci(self, sq): fileletter = String.fromCharCode(sq.file + "a".charCodeAt(0)) rankletter = String.fromCharCode(self.lastrank - sq.rank + "1".charCodeAt(0)) return fileletter + rankletter def moveuci(self, move): fromuci = self.squareuci(move.fromsq) touci = self.squareuci(move.tosq) promuci = cpick(move.prompiece.isempty(), "", move.prompiece.kind) return fromuci + touci + promuci def islightfilerank(self, file, rank): return ( ( ( file + rank ) % 2 ) == 0 ) def islightsquare(self, sq): return self.islightfilerank(sq.file, sq.rank) def squarelist(self): squarelist = [] for file in range(self.numfiles): for rank in range(self.numranks): squarelist.append(Square(file, rank)) return squarelist def squarecoordsvect(self, sq): return Vect(sq.file * self.squaresize, sq.rank * self.squaresize) def squarecoordsmiddlevect(self, sq): return self.squarecoordsvect(sq).p(Vect(self.squaresize / 2, self.squaresize / 2)) def piececoordsvect(self, sq): return self.squarecoordsvect(sq).p(Vect(self.squarepadding, self.squarepadding)) def flipawaresquare(self, sq): if self.flip: return Square(self.lastfile - sq.file, self.lastrank - sq.rank) return sq def piecedragstartfactory(self, sq, pdiv): def piecedragstart(ev): if self.promoting or self.show: ev.preventDefault() return self.dragkind = "move" self.draggedsq = sq self.draggedpdiv = pdiv self.movecanvashook.x() pdiv.op(0.1) return piecedragstart def piecedragfactory(self): def piecedrag(ev): pass return piecedrag def piecedragendfactory(self, sq, pdiv): def piecedragend(ev): pdiv.op(0.5) return piecedragend def piecedragoverfactory(self, sq): def piecedragover(ev): ev.preventDefault() return piecedragover def ismovepromotion(self, move): fromp = self.getpieceatsquare(move.fromsq) if ( fromp.kind == "p" ) and ( fromp.color == self.turn() ): if self.iswhitesturn(): if move.tosq.rank == 0: return True else: if move.tosq.rank == self.lastrank: return True return False def piecedropfactory(self, sq): def piecedrop(ev): ev.preventDefault() self.draggedpdiv.pv(self.piececoordsvect(self.flipawaresquare(sq))) self.draggedpdiv.zi(100) if self.dragkind == "move": self.dragmove = Move(self.draggedsq, sq) if self.ismovepromotion(self.dragmove): self.promoting = True self.build() elif not ( self.movecallback is None ): self.movecallback(self.variantkey, self.fen, self.moveuci(self.dragmove)) elif self.dragkind == "set": self.container.a(self.draggedpdiv) if not ( self.movecallback is None ): setuci = "{}@{}".format(self.draggedsetpiece.kind, self.squareuci(sq)) self.movecallback(self.variantkey, self.fen, setuci) return piecedrop def buildsquares(self): self.container.x() self.sqdivs = {} self.sqhdivs = {} for sq in self.squarelist(): sqclass = cpick(self.islightsquare(sq), "boardsquarelight", "boardsquaredark") sqdiv = Div().ac(["boardsquare", sqclass]).w(self.squaresize).h(self.squaresize) sqhdiv = Div().pa().w(self.squaresize).h(self.squaresize) self.sqdivs[sq.hashkey()] = sqdiv self.sqhdivs[sq.hashkey()] = { "div": sqhdiv, "cumop": 0.0 } fasq = self.flipawaresquare(sq) sqdiv.pv(self.squarecoordsvect(fasq)) sqhdiv.pv(self.squarecoordsvect(fasq)) sqdiv.ae("dragover", self.piecedragoverfactory(sq)) sqdiv.ae("drop", self.piecedropfactory(sq)) sqhdiv.ae("dragover", self.piecedragoverfactory(sq)) sqhdiv.ae("drop", self.piecedropfactory(sq)) self.container.a([sqdiv, sqhdiv]) p = self.getpieceatsquare(sq) if p.ispiece(): pdiv = Div().ac("boardpiece").w(self.piecesize).h(self.piecesize).pv(self.piececoordsvect(fasq)) pdiv.ac(getclassforpiece(p, self.piecestyle)).sa("draggable", True) pdiv.ae("dragstart", self.piecedragstartfactory(sq, pdiv)) pdiv.ae("drag", self.piecedragfactory()) pdiv.ae("dragend", self.piecedragendfactory(sq, pdiv)) pdiv.ae("dragover", self.piecedragoverfactory(sq)) pdiv.ae("drop", self.piecedropfactory(sq)) pdiv.zi(10) if self.variantkey == "threeCheck": if ( p.kind == "k" ): mul = self.getthreelifesforcolor(p.color) lifesdiv = Div().pa().t(- self.squaresize / 10).l(self.squaresize / 2 + self.squaresize / 10).w(self.squaresize / 2).h(self.squaresize / 2) lifesdiv.ac("boardthreechecklifesdiv").fs(self.squaresize / 1.5).html("{}".format(mul)) lifesdiv.c(["#ff0", "#ff0"][p.color]) pdiv.a(lifesdiv) self.container.a(pdiv) def getthreelifesforcolor(self, color): parts = self.threefen.split("+") mul = 3 if color == WHITE: try: mul = int(parts[2]) except: print("warning, could not parse white lifes from", self.threefen) if color == BLACK: try: mul = int(parts[0]) except: print("warning, could not parse black lifes from", self.threefen) return mul def prompiececlickedfactory(self, prompiecekind): def prompiececlicked(): self.dragmove.prompiece = Piece(prompiecekind, self.turn()) self.movecallback(self.variantkey, self.fen, self.moveuci(self.dragmove)) return prompiececlicked def buildprominput(self): promkinds = prompiecekindsforvariantkey(self.variantkey) promsq = self.dragmove.tosq.copy() dir = cpick(promsq.rank >= ( self.numranks / 2 ), -1, 1) ppks = prompiecekindsforvariantkey(self.variantkey) for ppk in ppks: fapromsq = self.flipawaresquare(promsq) pp = Piece(ppk, self.turn()) psqdiv = Div().pa().cp().zi(150).w(self.squaresize).h(self.squaresize).ac("boardpromotionsquare") psqdiv.pv(self.squarecoordsvect(fapromsq)) ppdiv = Div().pa().cp().zi(200).w(self.piecesize).h(self.piecesize).ac(getclassforpiece(pp, self.piecestyle)) ppdiv.pv(self.piececoordsvect(fapromsq)).ae("mousedown", self.prompiececlickedfactory(ppk)) self.container.a([psqdiv, ppdiv]) promsq = promsq.p(Square(0, dir)) def promotecancelclick(self): self.promoting = False self.build() def drawmovearrow(self, move, args = {}): if move is None: return strokecolor = args.get("strokecolor", "#FFFF00") linewidth = args.get("linewidth", 0.2) * self.squaresize headwidth = args.get("headwidth", 0.2) * self.squaresize headheight = args.get("headheight", 0.2) * self.squaresize tomv = self.squarecoordsmiddlevect(self.flipawaresquare(move.tosq)) frommv = self.squarecoordsmiddlevect(self.flipawaresquare(move.fromsq)) if False: self.movecanvas.lineWidth(linewidth) self.movecanvas.strokeStyle(strokecolor) self.movecanvas.fillStyle(strokecolor) self.movecanvas.drawline(frommv, tomv) dv = Vect(headwidth, headheight) self.movecanvas.fillRect(tomv.m(dv), tomv.p(dv)) if not ( move.prompiece.isempty() ): pf = 4 dvp = Vect(linewidth * pf, linewidth * pf) move.prompiece.color = self.turn() ppdiv = Div().pa().cp().ac(getclassforpiece(move.prompiece, self.piecestyle)).w(linewidth * 2 * pf).h(linewidth * 2 * pf) ppdiv.pv(tomv.m(dvp)) self.piececanvashook.a(ppdiv) arrow = Arrow(frommv, tomv, { "linewidth": linewidth, "pointwidth": headheight * 4, "pointheight": headheight * 4, "color": strokecolor }) self.arrowdiv.a(arrow) def drawuciarrow(self, uci, args = {}): self.drawmovearrow(self.ucitomove(uci), args) def highlightsquare(self, sq, bc, op): if op == 0: return margin = self.squaresize * 0.1 hsize = self.squaresize - 2 * margin sqhdiv = self.sqhdivs[sq.hashkey()] if op > sqhdiv["cumop"]: sqhdiv["cumop"] = op sqhdiv["div"].x().a(Div().pa().t(margin).l(margin).w(hsize).h(hsize).bc(bc).op(sqhdiv["cumop"])) def highlightmove(self, move, bc, op): self.highlightsquare(move.fromsq, bc, op) self.highlightsquare(move.tosq, bc, op) def highlightucimove(self, uci, bc, op): self.highlightmove(self.ucitomove(uci), bc, op) def buildgenmove(self): if "genmove" in self.positioninfo: if not ( genmove == "reset" ): genmoveuci = self.positioninfo["genmove"]["uci"] genmove = self.ucitomove(genmoveuci) if not ( genmove is None ): genmove.prompiece = Piece() self.drawmovearrow(genmove) def fentextchanged(self): if self.fentextchangedcallback: self.fentextchangedcallback(self.fentext.getText()) def build(self): self.sectioncontainer = Div().ac("boardsectioncontainer").w(self.outerwidth) self.sectioncontainer.bci(self.background) self.outercontainer = Div().ac("boardoutercontainer").w(self.outerwidth).h(self.outerheight) self.outercontainer.bci(self.background) self.container = Div().ac("boardcontainer").w(self.width).h(self.height).t(self.margin).l(self.margin) self.container.bci(self.background) self.outercontainer.a(self.container) self.buildsquares() self.turndiv = Div().pa().w(self.turndivsize).h(self.turndivsize).bc(cpick(self.iswhitesturn(), "#fff", "#000")) if self.variantkey == "racingKings": self.turndiv.t(cpick(self.flip, 0, self.outerheight - self.turndivsize)) if xor(self.isblacksturn(), self.flip): self.turndiv.l(0) else: self.turndiv.l(self.outerwidth - self.turndivsize) else: self.turndiv.l(self.outerwidth - self.turndivsize).t(cpick(xor(self.isblacksturn(), self.flip), 0, self.outerheight - self.turndivsize)) self.outercontainer.a(self.turndiv) if self.promoting: self.buildprominput() self.container.ae("mousedown", self.promotecancelclick) self.fentext = TextInput({}).w(self.width).fs(10).setText(self.fen) self.fentext.changecallback = self.fentextchanged self.fendiv = Div().ac("boardfendiv").h(self.fendivheight).a(self.fentext) if self.variantkey == "crazyhouse": self.whitestorediv = Div().ac("boardstorediv").h(self.squaresize).w(self.outerwidth) self.whitestorediv.bci(self.background) self.blackstorediv = Div().ac("boardstorediv").h(self.squaresize).w(self.outerwidth) self.blackstorediv.bci(self.background) self.whitestore = PieceStore({ "show": self.show, "parent": self, "color": WHITE, "store": self.crazyfen, "containerdiv": self.whitestorediv }) self.blackstore = PieceStore({ "show": self.show, "parent": self, "color": BLACK, "store": self.crazyfen, "containerdiv": self.blackstorediv }) if self.flip: self.sectioncontainer.a([self.whitestorediv, self.outercontainer, self.blackstorediv]) else: self.sectioncontainer.a([self.blackstorediv, self.outercontainer, self.whitestorediv]) else: self.sectioncontainer.a([self.outercontainer]) if self.showfen: self.sectioncontainer.a(self.fendiv) self.x().a(self.sectioncontainer) self.movecanvas = Canvas(self.width, self.height).pa().t(0).l(0) self.movecanvashook = Div().pa().t(0).l(0).zi(5).op(0.5) self.piececanvashook = Div().pa().t(0).l(0).zi(11).op(0.5) self.arrowdiv = Div().pa() self.container.a([self.movecanvashook, self.arrowdiv, self.piececanvashook]) self.movecanvashook.a(self.movecanvas) self.buildgenmove() return self def setflip(self, flip): self.flip = flip self.build() def calcsizes(self): self.lastfile = self.numfiles - 1 self.lastrank = self.numranks - 1 self.area = self.numfiles * self.numranks self.width = self.numfiles * self.squaresize self.height = self.numranks * self.squaresize self.avgsize = ( self.width + self.height ) / 2 self.margin = self.marginratio * self.avgsize self.squarepadding = self.squarepaddingratio * self.squaresize self.piecesize = self.squaresize - 2 * self.squarepadding self.outerwidth = self.width + 2 * self.margin self.outerheight = self.height + 2 * self.margin self.turndivsize = self.margin self.fendivheight = 25 def parseargs(self, args): self.fentextchangedcallback = args.get("fentextchangedcallback", None) self.positioninfo = args.get("positioninfo", {}) self.show = args.get("show", False) self.showfen = args.get("showfen", True) self.squaresize = args.get("squaresize", 45) self.squarepaddingratio = args.get("squarepaddingratio", 0.04) self.marginratio = args.get("marginratio", 0.02) self.numfiles = args.get("numfiles", 8) self.numranks = args.get("numranks", 8) self.piecestyle = args.get("piecestyle", "alpha") self.flip = args.get("flip", False) self.movecallback = args.get("movecallback", None) self.background = "/static/img/backgrounds/" + args.get("background", "wood.jpg") self.calcsizes() def setpieceati(self, i, p): if ( i >= 0 ) and ( i < self.area ): self.rep[i] = p else: print("warning, rep index out of range", i) def getpieceati(self, i): if ( i >= 0 ) and ( i < self.area ): return self.rep[i] return Piece() def getpieceatfilerank(self, file, rank): i = rank * self.numfiles + file return self.getpieceati(i) def getpieceatsquare(self, sq): return self.getpieceatfilerank(sq.file, sq.rank) def setrepfromfen(self, fen): self.fen = fen self.crazyfen = None self.threefen = None self.rep = [Piece() for i in range(self.area)] fenparts = self.fen.split(" ") self.rawfen = fenparts[0] rawfenparts = self.rawfen.split("/") if self.variantkey == "crazyhouse": self.crazyfen = "" if "[" in self.rawfen: cfenparts = self.rawfen.split("[") self.rawfen = cfenparts[0] rawfenparts = self.rawfen.split("/") cfenparts = cfenparts[1].split("]") self.crazyfen = cfenparts[0] i = 0 for rawfenpart in rawfenparts: pieceletters = rawfenpart.split("") for pieceletter in pieceletters: if isvalidpieceletter(pieceletter): self.setpieceati(i, piecelettertopiece(pieceletter)) i+=1 else: mul = 0 try: mul = int(pieceletter) except: print("warning, multiplicity could not be parsed from", pieceletter) for j in range(mul): self.setpieceati(i, Piece()) i += 1 if i < self.area: print("warning, raw fen did not fill board") elif i > self.area: print("warning, raw fen exceeded board") self.turnfen = "w" if len(fenparts) > 1: self.turnfen = fenparts[1] else: print("warning, no turn fen") self.castlefen = "-" if len(fenparts) > 2: self.castlefen = fenparts[2] else: print("warning, no castle fen") self.epfen = "-" if len(fenparts) > 3: self.epfen = fenparts[3] else: print("warning, no ep fen") moveclocksi = cpick(self.variantkey == "threeCheck", 5, 4) self.halfmoveclock = 0 if len(fenparts) > moveclocksi: try: self.halfmoveclock = int(fenparts[moveclocksi]) except: print("warning, half move clock could not be parsed from", fenparts[4]) else: print("warning, no half move fen") self.fullmovenumber = 1 if len(fenparts) > ( moveclocksi + 1 ): try: self.fullmovenumber = int(fenparts[moveclocksi + 1]) except: print("warning, full move number could not be parsed from", fenparts[5]) else: print("warning, no full move fen") if self.variantkey == "threeCheck": if len(fenparts) > 4: self.threefen = fenparts[4] self.promoting = False def turn(self): if self.turnfen == "w": return WHITE return BLACK def iswhitesturn(self): return self.turn() == WHITE def isblacksturn(self): return self.turn() == BLACK def initrep(self, args): self.variantkey = args.get("variantkey", "standard") self.setrepfromfen(args.get("fen", getstartfenforvariantkey(self.variantkey))) def setfromfen(self, fen, positioninfo = {}): self.positioninfo = positioninfo self.setrepfromfen(fen) self.build() def reset(self): self.setfromfen(getstartfenforvariantkey(self.variantkey)) def __init__(self, args): super().__init__("div") self.positioninfo = {} self.parseargs(args) self.initrep(args) self.build()
def buildsquares(self): self.container.x() self.sqdivs = {} self.sqhdivs = {} for sq in self.squarelist(): sqclass = cpick(self.islightsquare(sq), "boardsquarelight", "boardsquaredark") sqdiv = Div().ac(["boardsquare", sqclass]).w(self.squaresize).h(self.squaresize) sqhdiv = Div().pa().w(self.squaresize).h(self.squaresize) self.sqdivs[sq.hashkey()] = sqdiv self.sqhdivs[sq.hashkey()] = { "div": sqhdiv, "cumop": 0.0 } fasq = self.flipawaresquare(sq) sqdiv.pv(self.squarecoordsvect(fasq)) sqhdiv.pv(self.squarecoordsvect(fasq)) sqdiv.ae("dragover", self.piecedragoverfactory(sq)) sqdiv.ae("drop", self.piecedropfactory(sq)) sqhdiv.ae("dragover", self.piecedragoverfactory(sq)) sqhdiv.ae("drop", self.piecedropfactory(sq)) self.container.a([sqdiv, sqhdiv]) p = self.getpieceatsquare(sq) if p.ispiece(): pdiv = Div().ac("boardpiece").w(self.piecesize).h(self.piecesize).pv(self.piececoordsvect(fasq)) pdiv.ac(getclassforpiece(p, self.piecestyle)).sa("draggable", True) pdiv.ae("dragstart", self.piecedragstartfactory(sq, pdiv)) pdiv.ae("drag", self.piecedragfactory()) pdiv.ae("dragend", self.piecedragendfactory(sq, pdiv)) pdiv.ae("dragover", self.piecedragoverfactory(sq)) pdiv.ae("drop", self.piecedropfactory(sq)) pdiv.zi(10) if self.variantkey == "threeCheck": if ( p.kind == "k" ): mul = self.getthreelifesforcolor(p.color) lifesdiv = Div().pa().t(- self.squaresize / 10).l(self.squaresize / 2 + self.squaresize / 10).w(self.squaresize / 2).h(self.squaresize / 2) lifesdiv.ac("boardthreechecklifesdiv").fs(self.squaresize / 1.5).html("{}".format(mul)) lifesdiv.c(["#ff0", "#ff0"][p.color]) pdiv.a(lifesdiv) self.container.a(pdiv)
class FileUploader(e): def fileinputchanged(self): self.files = self.fileinput.files() self.handlefiles() def preventdefaults(self, ev): ev.preventDefault() ev.stopPropagation() def highlight(self): self.droparea.ac("highlight") def unhighlight(self): self.droparea.rc("highlight") def log(self, html): self.infoitems.append(html) self.infoitems.reverse() self.info.html("<br>".join(self.infoitems)) self.infoitems.reverse() def loginfo(self, content): try: json = JSON.parse(content) if json["success"]: if self.dirbrowseruploadedcallback: self.dirbrowseruploadedcallback() self.log("Uploaded <span class='fileuploadfilename'>{}</span> .".format(json["filename"])) else: path = "/uploads/{}".format(json["savefilename"]) self.log("uploaded <span class='fileuploadfilename'>{}</span> <a href='{}' target='_blank' rel='noopener noreferrer'>{}</a> <br> <font size='2'> media link <a href='{}' target='_blank' rel='noopener noreferrer'>{}</a> </font>".format(json["filename"], path, path, json["medialink"], json["medialink"])) else: self.log("<span class='fileuploaderror'>File upload failed. Status: {} .</span>".format(json["status"])) except: self.log("Error parsing response as JSON.") def uploadfile(self, file): if self.url is None: print("no upload url") return formdata = __new__ (FormData()) formdata.append('files', file) formdata.append('drive', self.drive) if self.getuid: formdata.append('uid', self.getuid()) if self.dirbrowsergetpathcallback: formdata.append("dirpath", self.dirbrowsergetpathcallback()) __pragma__("jsiter") args = { "method": 'POST', "body": formdata } __pragma__("nojsiter") fetch(self.url, args).then( lambda response: response.text().then( lambda content: self.loginfo(content), lambda err: self.loginfo(err) ), lambda err: self.loginfo(err) ) def handlefiles(self, files = self.files): for i in range(files.length): print("uploading file {}".format(i)) self.uploadfile(files.item(i)) def handledrop(self, ev): self.dt = ev.dataTransfer self.files = self.dt.files self.handlefiles() def build(self): self.x() self.droparea = Div("fileuploaddroparea") self.form = Form().ac("fileuploadform") self.desc = P().ac("fileuploadp").html("Upload {}s with the file dialog or by dragging and dropping them onto the dashed region".format(self.acceptdisplay)) self.fileinput = FileInput().ac("fileuploadfileelem").setmultiple(self.multiple).setaccept(self.accept) self.fileinput.sa("id", "fileinputelement") self.fileinput.ae("change", self.fileinputchanged) self.button = Label().ac("fileuploadbutton").sa("for", "fileinputelement").html("Select some {}s".format(self.acceptdisplay)) self.form.a([self.desc, self.fileinput, self.button]) self.droparea.a(self.form) for eventname in ["dragenter", "dragover", "dragleave", "drop"]: self.droparea.ae(eventname, self.preventdefaults) for eventname in ["dragenter", "dragover"]: self.droparea.ae(eventname, self.highlight) for eventname in ["dragleave", "drop"]: self.droparea.ae(eventname, self.unhighlight) self.droparea.ae("drop", self.handledrop) self.info = Div("fileuploadinfo") self.infoitems = [] self.a([self.droparea, self.info]) def __init__(self, args = {}): super().__init__("div") self.url = args.get("url", None) self.multiple = args.get("multiple", True) self.accept = args.get("accept", "image/*") self.acceptdisplay = args.get("acceptdisplay", "image") self.drive = args.get("drive", False) self.dirbrowseruploadedcallback = args.get("dirbrowseruploadedcallback", None) self.dirbrowsergetpathcallback = args.get("dirbrowsergetpathcallback", None) self.getuid = args.get("getuid", None) self.build()