Exemple #1
0
class DirItem(e):
    def __init__(self, obj):
        super().__init__("div")
        self.container = Div("diritem")
        for field in DIR_ITEM_FIELDS:
            self[field[1]] = obj[field[0]]
            fdiv = Div(field[1])
            self[field[1] + "div"] = fdiv
            self.container.a(fdiv)
        if self.isdir:
            self.container.ac("isdir")
        self.filenamelabel = Div().html(self.filename)
        self.filenamediv.a([self.filenamelabel])
        self.deletebutton = None
        if self.filename == "..":
            self.filenamediv.ac("parent")
        else:
            self.deletebutton = Button("Delete").ac("delete")
            self.isdirdiv.a(self.deletebutton)
            self.mtimediv.html(
                __new__(Date(self.mtime * 1000)).toLocaleString())
        if self.isdir:
            self.sizediv.html("dir")
        else:
            self.editbutton = Button("Edit")
            self.filenamediv.a(self.editbutton)
            self.sizediv.html(self.size)
        if self.rwx:
            self.rwxdiv.html(self.rwx)
        self.a(self.container)
 def setstore(self, store):
     self.store = store
     self.container.x()
     self.pieces = {}        
     for pieceletter in self.store.split(""):
         p = piecelettertopiece(pieceletter)
         if p.color == self.color:
             if p.kind in self.pieces:
                 self.pieces[p.kind]["mul"] += 1
             else:
                 pcdiv = Div().pr().w(self.piecesize).h(self.piecesize)
                 pdiv = Div().pa().cp().ac(getclassforpiece(p, self.parent.piecestyle)).w(self.piecesize).h(self.piecesize)
                 pdivcopy = Div().pa().cp().ac(getclassforpiece(p, self.parent.piecestyle)).w(self.piecesize).h(self.piecesize)
                 pdiv.t(0).l(0).sa("draggable", True).ae("dragstart", self.dragstartfactory(p, pdiv, pdivcopy))                
                 pcdiv.a(pdiv)
                 self.pieces[p.kind] = {
                     "mul": 1,
                     "p": p,
                     "pcdiv": pcdiv
                 }        
     for pkind, pdesc in self.pieces.items():
         muldiv = Div().pa().w(self.muldivsize).h(self.muldivsize).fs(self.muldivsize * 1.3).html("{}".format(pdesc["mul"]))
         muldiv.l(self.piecesize - self.muldivsize).t(0).ac("storemuldiv")
         pdesc["pcdiv"].a(muldiv)
         self.container.a(pdesc["pcdiv"])            
     return self
Exemple #3
0
class LogItem(e):
    def __init__(self, args = {}):        
        super().__init__("div")        
        self.text = args.get("text", "")
        self.kind = args.get("kind", "normal")
        self.prompt = args.get("prompt", None)
        self.container = Div("logitem")
        self.container.ac(self.kind)
        self.promptspan = Span().ac("prompt")
        if self.prompt:
            self.promptspan.html(self.prompt)
        self.textspan = Span().html(escapeHTML(self.text)).ac(self.kind)
        self.container.a([self.promptspan, self.textspan])
        self.a(self.container)
Exemple #4
0
class SplitPane(e):
    def resize(self, width = None, height = None):
        if not ( width is None ):
            self.width = max(width, self.minwidth)
        if not ( height is None ):
            self.height = height
        self.contentheight = max(self.height - self.controlheight, self.mincontentheight)
        self.height = self.controlheight + self.contentheight
        self.container.w(self.width).h(self.height)
        self.controlpanel.w(self.width).h(self.controlheight)
        self.contentdiv.w(self.width).h(self.contentheight)
        sbw = getScrollBarWidth()
        self.contentinnerwidth = self.width - sbw
        self.contentinnerheight = self.contentheight - sbw        
        self.contentdiv.x().a(self.contentelement)
        try:
            self.contentelement.resize(self.contentinnerwidth, self.contentinnerheight)
        except:
            pass
        return self

    def setcontentelement(self, contentelement):
        self.contentelement = contentelement
        self.resize(self.width, self.height)
        return self

    def resizetowindow(self):
        self.resize(window.innerWidth, window.innerHeight)
        return self

    def __init__(self, args = {}):
        super().__init__("div")
        self.controlheight = args.get("controlheight", 100)
        self.container = Div(["splitpane", "container"])
        self.controlpanel = Div(["splitpane", "controlpanel"])
        self.contentdiv = Div(["splitpane", "contentdiv"])
        self.container.a([self.controlpanel, self.contentdiv])        
        self.contentelement = Div()
        self.minwidth = args.get("minwidth", 400)        
        self.mincontentheight = args.get("mincontentheight", 200)
        self.resize(args.get("width", 600), args.get("height", 400))
        self.fillwindow = args.get("fillwindow", False)
        if self.fillwindow:
            window.addEventListener("resize", self.resizetowindow)
            self.resizetowindow()
        self.a(self.container)
 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)
Exemple #6
0
class ProcessInput(e):    
    def onenter(self):
        self.textinput.rc("textinputediting")
        if self.entercallback:
            self.entercallback()

    def getText(self):
        return self.textinput.getText()

    def setText(self, content):
        self.textinput.setText(content)
        return self

    def __init__(self, args = {}):
        super().__init__("div")
        self.container = Div("processinput")
        self.buttonlabel = args.get("buttonlabel", "Submit")        
        self.entercallback = args.get("entercallback", None)
        self.textinput = TextInput().setentercallback(self.entercallback)
        self.submitbutton = Button(self.buttonlabel, self.onenter)
        self.container.a([self.textinput, self.submitbutton])
        self.a(self.container)
Exemple #7
0
class Log(e):
    def __init__(self, args = {}):        
        super().__init__("div")        
        self.items = []
        self.container = Div()
        self.a(self.container)

    def build(self):
        self.container.x()
        for item in self.items:
            self.container.a(item)

    def log(self, item):
        newitems = [item]
        i = 1
        for olditem in self.items:
            if i < MAX_LOGITEMS:
                newitems.append(olditem)
                i += 1
            else:
                break
        self.items = newitems
        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()
Exemple #10
0
class Client:
    def __init__(self):
        self.socket = None
        self.root = ge("clientroot")

    def signincallback(self):
        email = self.emailinput.getText()
        password = self.passwordinput.getText()
        print("signing in user with", email, password)
        firebase.auth().signInWithEmailAndPassword(email, password).then(
            lambda: print("ok"),
            lambda error: window.alert("{}".format(error))
        )

    def signoutcallback(self):
        if firebase.auth().currentUser:            
            print("signing out")
            firebase.auth().signOut()
        else:
            window.alert("Already signed out.")

    def signupcallback(self):
        email = self.emailinput.getText()
        password = self.passwordinput.getText()
        print("signing up user with", email, password)
        firebase.auth().createUserWithEmailAndPassword(email, password).then(
            lambda: print("ok"),
            lambda error: window.alert("{}".format(error))
        )

    def sendverificationcallback(self):
        email = self.emailinput.getText()
        firebase.auth().currentUser.sendEmailVerification().then(
            lambda: window.alert("Verification email has been sent to {} !".format(email)),
            lambda error: window.alert("{}".format(error))
        )

    def resetpasswordcallback(self):
        email = self.emailinput.getText()
        firebase.auth().sendPasswordResetEmail(email).then(
            lambda: window.alert("Password reset email has been sent to {} !".format(email)),
            lambda error: window.alert("{}".format(error))
        )

    def updatedetailscallback(self):
        userdetails = {
            "displayname": self.displaynameinput.getText(),
            "photourl": self.photourlinput.getText()
        }
        self.sioreq({
            "kind": "updateuserdetails",
            "uid": self.uid,
            "userdetails": userdetails
        })

    def buildsignupdiv(self):
        self.signupdiv = Div()
        self.signupmaildiv = Div("signupmaildiv")
        self.emaillabel = Span().html("Email:")
        self.emailinput = TextInput().ac("profiletextinput").w(250)
        self.passwordlabel = Span().html("Password:"******"profiletextinput").w(100)
        self.signinbutton = Button("Sign in", self.signincallback)
        self.signoutbutton = Button("Sign out", self.signoutcallback)
        self.signupbutton = Button("Sign up", self.signupcallback)
        self.sendverificationbutton = Button("Send verification", self.sendverificationcallback)
        self.resetpasswordbutton = Button("Reset password", self.resetpasswordcallback)
        self.userinfodiv = Div("userinfodiv")
        self.signupmaildiv.a([self.emaillabel, self.emailinput, self.passwordlabel, self.passwordinput, self.signinbutton, self.signoutbutton, self.signupbutton, self.sendverificationbutton, self.resetpasswordbutton])        
        self.userdetailsdiv = Div("userdetailsdiv")
        self.displaynamelabel = Span().html("Display name:")
        self.displaynameinput = TextInput().ac("profiletextinput").w(250)
        self.photourllabel = Span().html("Photo url:")        
        self.photourlinput = TextInput().ac("profiletextinput").w(250)
        self.updatedetailsbutton = Button("Update details", self.updatedetailscallback)
        self.userdetailsdiv.a([self.displaynamelabel, self.displaynameinput, self.photourllabel, self.photourlinput, self.updatedetailsbutton])
        self.photodiv = Div("photodiv")
        self.signupdiv.a([self.signupmaildiv, self.userdetailsdiv, self.userinfodiv, self.photodiv])                
        self.firebaseuidiv = Div().sa("id", "firebaseuidiv")        
        self.signupdiv.a(self.firebaseuidiv)

    def serializeconfig(self):
        self.sioreq({
            "kind": "serializeconfig",
            "data": self.configschema.toargs()
        })

    def storecloud(self):
        self.sioreq({
            "kind": "storecloudconfig",
            "data": self.configschema.toargs()
        })

    def retrievecloud(self):
        self.sioreq({
            "kind": "retrievecloudconfig"
        })

    def buildconfigdiv(self):
        self.configdiv = Div()
        self.configdiv.a(Button("Serialize", self.serializeconfig))        
        self.configdiv.a(Button("Store cloud", self.storecloud))        
        self.configdiv.a(Button("Retrieve cloud", self.retrievecloud))        
        self.configschema = Schema(self.schemaconfig)
        self.configdiv.a(self.configschema)

    def build(self):        
        self.root.innerHTML = ""        
        self.buildconfigdiv()
        self.signupdiv = Div()        
        if self.authenabled:
            self.buildsignupdiv()        
        self.profiletab = Tab("profile", "Profile", self.signupdiv)
        self.mainelement = TabPane({
            "id": "maintabpane",
            "fillwindow": True,
            "tabs": [
                Tab("main", "Main", Div("contentplaceholder").html("Main.")),
                Tab("config", "Config", self.configdiv),
                Tab("upload", "Upload", FileUploader({"url": "/upload"})),
                Tab("log", "Log", Div("contentplaceholder").html("Log.")),
                self.profiletab,
                Tab("about", "About", Div("contentplaceholder").html("About."))
            ],
            "selected": "upload"
        })        
        self.root.appendChild(self.mainelement.e)

    def onconnect(self):
        self.sioreq({"kind": "connected"})

    def sioreq(self, obj):
        print("->", obj)
        self.socket.emit("sioreq", obj)    

    def getuserdisplayname(self):
        if self.user:
            if self.displayName:
                return self.displayName
            return self.email
        return None

    def setprofiletab(self):
        self.profiletab.rc(["profilelogged", "profileanon"])
        dn = self.getuserdisplayname()
        if dn:
            self.profiletab.container.html(dn)
            self.profiletab.ac("profilelogged")
        else:
            if self.user:
                self.profiletab.container.html("Anonymous")
                self.profiletab.ac("profileanon")
            else:
                self.profiletab.container.html("Profile")

    def signinanonymously(self):
        firebase.auth().signInAnonymously().then(
            lambda: print("ok"),
            lambda error: print(error)
        )

    def userstatusverbal(self):
        if not self.user:
            return "[logged out]"
        if self.user.isAnonymous:
            return "anonymous"
        return cpick(self.emailVerified, "verified", "not verified")

    def userverified(self):
        if not self.user:
            return False
        if self.user.isAnonymous:
            return False
        return self.user.emailVerified

    def authstatechanged(self, user):        
        self.user = user
        self.passwordinput.setText("")
        if user:        
            self.displayName = user.displayName
            self.email = user.email
            self.emailVerified = user.emailVerified
            self.photoURL = user.photoURL
            self.isAnonymous = user.isAnonymous
            self.uid = user.uid
            self.providerData = user.providerData        
            print("user", self.displayName, self.email)
            print(self.providerData)
            self.nameinfodiv = Div().html("name : <span class='{}'>{}</span>".format(cpick(self.displayName, "uiinfo", "uiinfored"), getelse(self.displayName,"&lt;NA&gt;"))).pt(5)
            self.emailinfodiv = Div().html("email : <span class='{}'>{}</span>".format(cpick(self.email, "uiinfo", "uiinfored"), getelse(self.email, "&lt;NA&gt;")))
            self.verifiedinfodiv = Div().html("status : <span class='{}'>{}</span>".format(cpick(self.userverified(), "uiinfo", "uiinfored"), self.userstatusverbal()))            
            self.photourldiv = Div().html("photo url : <span class='{}'>{}</span>".format(cpick(self.photoURL, "uiinfo", "uiinfored"), getelse(self.photoURL,"&lt;NA&gt;")))
            self.uidinfodiv = Div().html("uid : <span class='uiinfo'>{}</span>".format(self.uid)).pb(8)
            self.userinfodiv.x().a([self.nameinfodiv, self.emailinfodiv, self.verifiedinfodiv, self.photourldiv, self.uidinfodiv])
            self.emailinput.setText(self.email)        
            self.displaynameinput.setText(self.displayName)                
            self.photourlinput.setText(self.photoURL)                
            self.photodiv.x()
            if self.photoURL:
                self.photodiv.html("<img src='{}'></img>".format(self.photoURL))
        else:
            print("no user")
            self.userinfodiv.x().a([
                Div().html("Please sign up or sign in !"),
                Button("Sign in anonymously", self.signinanonymously())
            ])
        self.setprofiletab()
        self.userinfodiv.fs(cpick(self.user, 10, 14))

    def getschemaconfigfromobj(self, obj):
        self.schemaconfig = {
            "kind": "collection",
            "disposition": "dict"
        }
        if "schemaconfig" in obj:
            self.schemaconfig = obj["schemaconfig"]            
        self.authenabled = ( getrec("global/auth/enabled", self.schemaconfig) == "true" )

    def initializefirebase(self):
        print("initializing firebase from", self.firebaseconfig)
        firebase.initializeApp(self.firebaseconfig)                    
        firebase.auth().onAuthStateChanged(self.authstatechanged)                    

    def initializefirebaseui(self):
        self.uiConfig = {
            "signInSuccessUrl": '/',
            "signInOptions": [            
                firebase.auth.GoogleAuthProvider.PROVIDER_ID,
                #firebase.auth.FacebookAuthProvider.PROVIDER_ID,
                #firebase.auth.TwitterAuthProvider.PROVIDER_ID,
                #firebase.auth.GithubAuthProvider.PROVIDER_ID,
                firebase.auth.EmailAuthProvider.PROVIDER_ID,
                #firebase.auth.PhoneAuthProvider.PROVIDER_ID
            ],        
           "tosUrl": '/tos'
        }
        print("initializing firebase ui from", self.uiConfig)
        self.ui = __new__(firebaseui.auth.AuthUI(firebase.auth()))                
        self.ui.start(self.firebaseuidiv.e, self.uiConfig)

    def startfirebase(self):
        self.initializefirebase()
        self.initializefirebaseui()

    def siores(self, obj):
        print("<-", obj)
        if "kind" in obj:
            kind = obj["kind"]
            if kind == "connectedack":
                self.getschemaconfigfromobj(obj)
                self.build()
                if self.authenabled:                
                    self.firebaseconfig = obj["firebaseconfig"]
                    setTimeout(self.startfirebase, 50)
            elif kind == "configsaved":
                window.alert("Config saved, {} characters".format(obj["size"]))
            elif kind == "setcloudconfig":
                self.getschemaconfigfromobj(obj)
                self.build()
                setTimeout(lambda: window.alert("Config set from cloud."), 10)
            elif kind == "alert":
                window.alert(obj["data"])
                if obj["reload"]:
                    location.reload()

    def startup(self):
        print("creating socket {}".format(SUBMIT_URL))

        self.socket = io.connect(SUBMIT_URL)

        print("socket created ok")        

        self.socket.on('connect', self.onconnect)
        self.socket.on('siores', self.siores)
######################################################
Exemple #11
0
class Config(e):
    def serializeconfig(self):
        getconn().sioreq({
            "kind": "serializeconfig",
            "data": self.configschema.toargs(),
            "owner": self.id
        })

    def serializelocalstorage(self):
        getconn().sioreq({
            "kind": "serializelocalstorage",
            "data": JSON.stringify(localStorage),
            "owner": self.id
        })

    def synclocalstorage(self):
        getconn().sioreq({"kind": "synclocalstorage", "owner": self.id})

    def siores(self, response):
        try:
            kind = response["kind"]
            if kind == "localstoragesaved":
                window.alert("Local storage saved. Size {} characters.".format(
                    response["size"]))
            elif kind == "synclocalstorage":
                obj = response["data"]
                i = 0
                __pragma__("jsiter")
                for key in obj:
                    localStorage.setItem(key, obj[key])
                    i += 1
                __pragma__("nojsiter")
                window.alert(
                    "Setting {} key(s) in localstorage done. Press ok to reload."
                    .format(i))
                document.location.reload()
        except:
            print("there was a problem processing config siores")

    def resize(self, width, height):
        self.configsplitpane.resize(width, height)

    def build(self):
        self.configsplitpane = SplitPane({"controlheight": 50})
        self.configdiv = Div("largesheet")
        self.configsplitpane.controlpanel.a([
            Button("Serialize config",
                   self.serializeconfig).ac("controlbutton"),
            Button("Serialize localstorage",
                   self.serializelocalstorage).ac("controlbutton"),
            Button("Sync localstorage",
                   self.synclocalstorage).ac("controlbutton")
        ])
        self.configsplitpane.controlpanel.ac("subcontrolpanel")
        self.configschema = Schema(self.schemaconfig)
        self.configdiv.a(self.configschema)
        self.configsplitpane.setcontentelement(self.configdiv)
        self.x().a(self.configsplitpane)

    def setschemaconfig(self, schemaconfig):
        self.schemaconfig = schemaconfig
        self.build()

    def get(self, path, default):
        return getrecm(path, self.configschema, default)

    def getpath(self, path):
        return self.configschema.getpath(path)

    def __init__(self, args={}):
        super().__init__("div")
        self.id = args.get("id", "config")
        self.schemaconfig = {"kind": "collection", "disposition": "dict"}
        self.build()
Exemple #12
0
class Schema(e):
    def copydivclicked(self):
        global clipboard
        clipboard = self.toargs()

    def openbuttonclicked(self):
        self.childsopened = not self.childsopened
        self.build()

    def createcombochanged(self, v):
        if v == "scalar":
            sch = Schema({"parent": self, "kind": "scalar"})
        elif v == "dict":
            sch = Schema({
                "parent": self,
                "kind": "collection",
                "disposition": "dict"
            })
        elif v == "list":
            sch = Schema({
                "parent": self,
                "kind": "collection",
                "disposition": "list"
            })
        self.childs.append(sch)
        self.build()

    def stringvalueinputchanged(self):
        self.value = self.stringvalueinput.getText()

    def keyinputchanged(self):
        self.key = self.keyinput.getText()

    def deletechild(self, child):
        global clipboard
        newchilds = []
        for currchild in self.childs:
            if not (currchild == child):
                newchilds.append(currchild)
            else:
                clipboard = child.toargs()
        self.childs = newchilds
        self.build()

    def deletedivclicked(self):
        self.parent.deletechild(self)

    def pastebuttonpushed(self):
        global clipboard
        if clipboard:
            clipboard["parent"] = self
            sch = Schema(clipboard)
            self.childs.append(sch)
            self.build()

    def build(self):
        self.x().ac("schema")
        self.itemdiv = Div(["item", self.disposition])
        self.valuediv = Div(["value", self.disposition])
        if self.kind == "scalar":
            if self.disposition == "string":
                self.stringvalueinput = TextInput().ac("string").setText(
                    self.value)
                self.stringvalueinput.ae("keyup", self.stringvalueinputchanged)
                self.valuediv.a(self.stringvalueinput)
        self.helpdiv = Div(["box", "help"]).html("?")
        self.copydiv = Div(["box",
                            "copy"]).html("C").ae("mousedown",
                                                  self.copydivclicked)
        if isdict(self.parent):
            self.keydiv = Div("key")
            self.keyinput = TextInput().ac("key").setText(self.key)
            self.keyinput.ae("keyup", self.keyinputchanged)
            self.keydiv.a(self.keyinput)
            self.itemdiv.a(self.keydiv)
        self.itemdiv.a([self.valuediv, self.helpdiv, self.copydiv])
        if self.parent:
            self.deletediv = Div(["box", "delete"
                                  ]).html("X").ae("mousedown",
                                                  self.deletedivclicked)
            self.itemdiv.a(self.deletediv)
        if iscollection(self):
            self.openbutton = Div("openbutton").ae("mousedown",
                                                   self.openbuttonclicked)
            self.valuediv.a(self.openbutton)
        self.childsdiv = Div("childs")
        if self.childsopened:
            self.creatediv = Div("create")
            cc = self.createcombo
            self.createcombo = ComboBox().setoptions(
                [["create", "Create new"], ["scalar", "Scalar"],
                 ["dict", "Dict"], ["list", "List"]], "create",
                self.createcombochanged).ac("createcombo")
            self.creatediv.a(self.createcombo)
            self.pastebutton = Button("Paste",
                                      self.pastebuttonpushed).ac("pastebutton")
            self.creatediv.a(self.pastebutton)
            self.childsdiv.a(self.creatediv)
            for child in self.childs:
                self.childsdiv.a(child)
        self.container = Div("container")
        self.container.a([self.itemdiv, self.childsdiv])
        self.a(self.container)
        return self

    def tojsontext(self):
        return JSON.stringify(self.toargs(), None, 2)

    def toargs(self):
        args = {}
        for arg in SCHEMA_DEFAULT_ARGS:
            args[arg[0]] = self[arg[0]]
        args["childsarg"] = []
        for child in self.childs:
            args["childsarg"].append(child.toargs())
        return args

    def __init__(self, args={}):
        super().__init__("div")
        self.parent = getitem(args, "parent", None)
        for arg in SCHEMA_DEFAULT_ARGS:
            self[arg[0]] = getitem(args, arg[0], arg[1])
        self.childs = []
        for childarg in self.childsarg:
            childarg["parent"] = self
            child = Schema(childarg)
            self.childs.append(child)
        self.build()
Exemple #13
0
class Forumnode(e):
    def __init__(self, root, args={}):
        super().__init__("div")
        self.root = root
        self.move = args["move"]
        self.uci = args["uci"]
        self.comment = args["comment"]
        if not self.comment:
            self.comment = ""
        self.owner = args["owner"]
        self.fen = args["fen"]
        self.parent = args["parent"]
        self.isadmin = args["isadmin"]
        self.halfmoveno = args["halfmoveno"]
        if not self.halfmoveno:
            self.halfmoveno = -1
        self.childs = []
        self.build()

    def toobj(self):
        moveobjs = {}
        for child in self.childs:
            moveobjs[child.move] = child.toobj()
        return {
            "uci": self.uci,
            "comment": self.comment,
            "owner": self.owner,
            "fen": self.fen,
            "moves": moveobjs
        }

    def appendchild(self, node):
        node.halfmoveno = self.halfmoveno + 1
        node.build()
        self.childs.append(node)
        self.containerdiv.a(node)
        if len(self.childs) > 1:
            rgb = "rgb({},{},{})".format(int(random() * 128 + 127),
                                         int(random() * 128 + 127),
                                         int(random() * 128 + 127))
            self.containerdiv.bc(rgb).bds("solid").bdw(10).bdr(20).bdc(rgb)

    def addnode(self):
        input = window.prompt("Move:uci:owner:fen", "")
        if input:
            self.root.shift()
            parts = input.split(":")
            self.appendchild(
                Forumnode(
                    self.root, {
                        "move": parts[0],
                        "uci": None,
                        "comment": "",
                        "uci": parts[0],
                        "owner": parts[2],
                        "fen": parts[2],
                        "parent": self,
                        "isadmin": self.isadmin
                    }))
            self.root.parse()

    def edituci(self):
        input = window.prompt("Uci", "")
        if input:
            self.uci = input
            self.setboard()
            self.ucidiv.html(self.uci)
            self.root.parse()

    def editfen(self):
        input = window.prompt("Fen", "")
        if input:
            self.fen = input
            self.setboard()
            self.root.parse()

    def setmovelabel(self):
        if self.halfmoveno < 0:
            moveno = ""
        elif (self.halfmoveno % 2) == 0:
            moveno = ((self.halfmoveno + 2) / 2) + ". "
        else:
            moveno = ((self.halfmoveno + 1) / 2) + ".. "
        self.movelabeldiv.html("{}{}".format(moveno, self.move))

    def editsan(self):
        input = window.prompt("San", "")
        if input:
            self.move = input
            self.setmovelabel()
            self.root.parse()

    def editcomment(self):
        input = window.prompt("Comment", self.comment)
        if input:
            self.comment = input
            self.commentdiv.html(self.comment)
            self.root.parse()

    def editowner(self):
        input = window.prompt("Owner", "")
        if input:
            self.owner = input
            self.ownerdiv.html(self.owner)
            self.root.parse()

    def movecallback(self, variantkey, fen, uci):
        if self.reqfenunderway:
            print("a fen request is in progress, cannot start a new one")
            return
        self.root.shift()
        self.root.reqfenunderway = True
        self.root.reqnode = self
        getconn().sioreq({
            "kind": "forumgamemove",
            "owner": "forumgame",
            "moveuci": uci,
            "variantkey": variantkey,
            "fen": fen
        })

    def bbdragstart(self, ev):
        ev.stopPropagation()

    def setboard(self):
        initobj = {
            "fen": self.fen,
            "squaresize": 20,
            "showfen": False,
            "movecallback": self.movecallback,
            "variantkey": "atomic"
        }
        if self.uci:
            initobj["positioninfo"] = {"genmove": {"uci": self.uci}}
        b = BasicBoard(initobj)
        b.cp().ae("dragstart", self.bbdragstart)
        self.boarddiv.x().a(b)

    def analyzelocal(self):
        try:
            self.root.mainboard.variantchanged("atomic", self.fen)
            self.root.parenttabpane.selectbykey("board")
        except:
            pass

    def analyzelichess(self):
        window.open("https://lichess.org/analysis/atomic/" + self.fen,
                    "_blank")

    def delchilds(self):
        self.childs = []
        self.root.rebuild(mainseed)

    def delme(self):
        parent = self.parent
        if parent:
            newchilds = []
            for child in parent.childs:
                print("child", child.move, child.uci)
                if not (child == self):
                    newchilds.append(child)
            parent.childs = newchilds
            self.root.rebuild(mainseed)

    def serializefunc(self):
        self.root.rebuild(mainseed + 1)
        self.root.store()

    def serialize(self):
        self.infohook.html("serializing")
        setTimeout(self.serializefunc, 100)

    def copysrc(self):
        self.root.copysrc()

    def copylink(self):
        ti = TextInput()
        self.linktexthook.a(ti)
        ti.setText("https://fbserv.herokuapp.com/analysis/atomic/" +
                   self.fen.replace(" ", "%20"))
        ti.e.select()
        document.execCommand("copy")
        self.linktexthook.x()

    def build(self):
        self.movediv = Div().disp("flex").fd("row").ai("center")
        self.movedescdiv = Div().bc("#eee").w(110).maw(110).pad(3)
        self.movelabeldiv = Div().fw("bold").pad(3).ff("monospace")
        self.setmovelabel()
        self.ownerdiv = Div().html(
            self.owner).ff("monospace").fs("10").c("#007")
        self.ucidiv = Div().ff("monospace").fs("12").pad(3)
        self.commentdiv = Div().fs("12").pad(5).html(self.comment)
        if self.uci:
            self.ucidiv.html(self.uci)
        self.movedescdiv.a([self.movelabeldiv, self.ownerdiv, self.commentdiv])
        self.movedescdiv.a(Button("Analyze local", self.analyzelocal).mar(2))
        self.movedescdiv.a(
            Button("Analyze lichess", self.analyzelichess).mar(2))
        self.infohook = Div().ff("monospace").pad(3).c("#007").fw("bold").html(
            "built")
        if self.isadmin:
            self.movedescdiv.a(self.infohook)
            self.linktexthook = Div()
            self.movedescdiv.a(self.ucidiv)
            self.movedescdiv.a(Button("+", self.addnode).pad(5))
            self.movedescdiv.a(Button("san", self.editsan).pad(5))
            self.movedescdiv.a(Button("uci", self.edituci).pad(5))
            self.movedescdiv.a(Button("fen", self.editfen).pad(5))
            self.movedescdiv.a(Button("comment", self.editcomment).pad(5))
            self.movedescdiv.a(Button("owner", self.editowner).pad(5))
            self.movedescdiv.a(
                Button("serialize", self.serialize).pad(5).bc("#ffa"))
            self.movedescdiv.a(Button("copy", self.copysrc).pad(5).bc("#afa"))
            self.movedescdiv.a(self.linktexthook)
            self.movedescdiv.a(Button("link", self.copylink).pad(5).bc("#aff"))
            self.movedescdiv.a(
                Button("delchilds", self.delchilds).pad(5).bc("#faa"))
            self.movedescdiv.a(Button("delme", self.delme).pad(5).bc("#faa"))
        self.boarddiv = Div().pad(2)
        self.movecontainerdiv = Div().disp("flex").fd("row").ai("center")
        self.movecontainerdiv.a([self.movedescdiv, self.boarddiv])
        self.containerdiv = Div().disp("flex").fd("column").ai("flex-start")
        self.movediv.a([self.movecontainerdiv, self.containerdiv])
        self.setboard()
        self.x().a(self.movediv)
        self.mw(600)
Exemple #14
0
class Forumgame(e):
    def __init__(self):
        super().__init__("div")
        self.messagediv = Div().disp("inline-block").pad(3).ff("monospace")
        self.contentdiv = Div()
        self.a([self.messagediv, self.contentdiv])
        self.reqfenunderway = False
        self.reqnode = None
        self.requestforumgame()
        self.ae("mousemove", self.mousemove)
        self.ae("mouseup", self.mouseup)
        self.ae("mouseleave", self.mouseleave)

    def copysrc(self):
        self.textarea.e.select()
        document.execCommand("copy")
        window.alert("Copied source to clipboard, {} characters.".format(
            len(self.textarea.getText())))

    def mousemove(self, ev):
        if self.dragunderway:
            dx = ev.clientX - self.dragstartx
            dy = ev.clientY - self.dragstarty
            self.parenttabpane.contentdiv.e.scrollTop = self.scrolltop + 20 * dy
            self.parenttabpane.contentdiv.e.scrollLeft = self.scrollleft + 20 * dx

    def mouseup(self, ev):
        self.dragunderway = False

    def mouseleave(self, ev):
        self.dragunderway = False

    def parse(self):
        obj = self.rootnode.toobj()
        text = JSON.stringify(obj, None, 2)
        self.textarea.setText(text)
        return text

    def store(self):
        self.parenttabpane.contentdiv.bc("#faa")
        self.messagediv.html("Parsing JSON")
        try:
            obj = JSON.parse(self.textarea.getText())
            self.messagediv.html("Storing JSON")
            getconn().sioreq({
                "kind": "setforumgame",
                "owner": "forumgame",
                "forumgame": obj
            })
        except:
            self.messagediv.html("Error: could not parse JSON")
            return

    def requestforumgame(self):
        getconn().sioreq({"kind": "getforumgame", "owner": "forumgame"})

    def buildrec(self, parentnode, tree):
        __pragma__("jsiter")
        if not tree["moves"]:
            return
        for move in tree["moves"]:
            moveobj = tree["moves"][move]
            node = Forumnode(
                self, {
                    "move": move,
                    "uci": moveobj["uci"],
                    "comment": moveobj["comment"],
                    "owner": moveobj["owner"],
                    "fen": moveobj["fen"],
                    "parent": parentnode,
                    "isadmin": self.isadmin
                })
            parentnode.appendchild(node)
            self.buildrec(node, moveobj)
        __pragma__("nojsiter")

    def build(self, text, seed):
        setseed(seed)
        self.contentdiv.x().pad(3)
        self.textarea = TextArea().w(1000).h(200)
        self.textarea.setText(text)
        self.controlpanel = Div()
        self.controlpanel.a(Button("Store", self.store))
        if self.isadmin:
            self.contentdiv.a(self.textarea)
            self.contentdiv.a(self.controlpanel)
        self.rootnode = Forumnode(
            self, {
                "move": "startpos",
                "uci": None,
                "owner": "Wolfram_EP",
                "comment": "Forum game",
                "fen":
                "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
                "parent": None,
                "isadmin": self.isadmin
            })
        self.contentdiv.a(self.rootnode)
        self.buildrec(self.rootnode, self.forumgame)
        #self.rootnode.e.scrollIntoView(True)
        self.parenttabpane.setscroll()
        self.contentdiv.sa("draggable", True).cm().ae("dragstart",
                                                      self.dragstart)

    def dragstart(self, ev):
        ev.preventDefault()
        self.dragstartx = ev.clientX
        self.dragstarty = ev.clientY
        self.scrolltop = self.parenttabpane.contentdiv.e.scrollTop
        self.scrollleft = self.parenttabpane.contentdiv.e.scrollLeft
        self.dragunderway = True

    def rebuild(self, seed):
        text = self.parse()
        self.forumgame = JSON.parse(text)
        self.build(text, seed)

    def shift(self):
        sl = self.parenttabpane.contentdiv.e.scrollLeft
        self.parenttabpane.contentdiv.e.scrollLeft = sl + 300

    def siores(self, response):
        if response["kind"] == "setforumgame":
            self.forumgame = response["forumgame"]
            self.messagediv.html("Forumgame loaded")
            self.isadmin = response["isadmin"]
            if queryparams.get("noadmin", "false") == "true":
                self.isadmin = False
            self.build(JSON.stringify(self.forumgame, None, 2), mainseed)
            self.parenttabpane.contentdiv.bc("#def")
        if response["kind"] == "setforumgamedone":
            self.messagediv.html("Stored, refreshing")
            self.requestforumgame()
        if response["kind"] == "setforumgamefen":
            posinfo = response["positioninfo"]
            fen = response["fen"]
            san = posinfo["genmove"]["san"]
            uci = posinfo["genmove"]["uci"]
            rp = self.reqnode.parent
            owner = None
            if rp:
                owner = rp.owner
            if not owner:
                owner = window.prompt("Owner", "?")
            if not owner:
                owner = "?"
            self.reqnode.appendchild(
                Forumnode(
                    self, {
                        "move": san,
                        "uci": uci,
                        "comment": "",
                        "owner": owner,
                        "fen": fen,
                        "parent": self.reqnode,
                        "isadmin": self.isadmin
                    }))
            self.parse()
Exemple #15
0
class Schema(e):
    def copydivclicked(self):
        global clipboard
        clipboard = self.toargs()

    def openbuttonclicked(self):
        self.childsopened = not self.childsopened
        self.build()

    def createcombochanged(self, v):
        if v == "scalar":
            sch = Schema({
                "parent": self,
                "kind": "scalar",
                "disposition": "string"
            })
        elif v == "slider":
            sch = Schema({
                "parent": self,
                "kind": "scalar",
                "disposition": "slider"
            })
        elif v == "checkbox":
            sch = Schema({
                "parent": self,
                "kind": "scalar",
                "disposition": "checkbox"
            })
        elif v == "textarea":
            sch = Schema({
                "parent": self,
                "kind": "scalar",
                "disposition": "textarea"
            })
        elif v == "date":
            sch = Schema({
                "parent": self,
                "kind": "scalar",
                "disposition": "date",
                "value": dateToDateInputStr(__new__(Date()))
            })
        elif v == "color":
            sch = Schema({
                "parent": self,
                "kind": "scalar",
                "disposition": "color",
                "value": "#ffffff"
            })
        elif v == "dict":
            sch = Schema({
                "parent": self,
                "kind": "collection",
                "disposition": "dict"
            })
        elif v == "list":
            sch = Schema({
                "parent": self,
                "kind": "collection",
                "disposition": "list"
            })
        elif v == "combo":
            sch = Schema({
                "parent": self,
                "kind": "collection",
                "disposition": "combo"
            })
        elif v == "radio":
            sch = Schema({
                "parent": self,
                "kind": "collection",
                "disposition": "radio"
            })
        elif v == "process":
            sch = Schema({
                "parent":
                self,
                "kind":
                "collection",
                "disposition":
                "dict",
                "childsopened":
                True,
                "childsarg": [{
                    "kind": "scalar",
                    "disposition": "string",
                    "key": "key"
                }, {
                    "kind": "scalar",
                    "disposition": "string",
                    "key": "displayname"
                }, {
                    "kind": "scalar",
                    "disposition": "string",
                    "key": "command"
                }, {
                    "kind": "collection",
                    "disposition": "list",
                    "key": "command_args"
                }]
            })
        self.childs.append(sch)
        self.build()

    def stringvalueinputchanged(self):
        self.value = self.stringvalueinput.getText()

    def keyinputchanged(self):
        self.key = self.keyinput.getText()

    def deletechild(self, child):
        global clipboard
        newchilds = []
        for currchild in self.childs:
            if not (currchild == child):
                newchilds.append(currchild)
            else:
                clipboard = child.toargs()
        self.childs = newchilds
        self.build()

    def deletedivclicked(self):
        self.parent.deletechild(self)

    def pastebuttonpushed(self):
        global clipboard
        if clipboard:
            clipboard["parent"] = self
            sch = Schema(clipboard)
            self.childs.append(sch)
            self.build()

    def setslidervalue(self, value, doslider=True):
        self.value = float(value)
        if self.value < self.minvalue:
            self.value = self.minvalue
        if self.value > self.maxvalue:
            self.value = self.maxvalue
        if doslider:
            self.slider.sv(self.value)
        self.slidervalueinput.setText("{}".format(self.value))

    def minvalueinputchanged(self):
        self.minvalue = texttofloat(self.minvalueinput.getText(),
                                    self.minvalue)
        self.slider.setmin(self.minvalue)
        self.setslidervalue(self.value)

    def maxvalueinputchanged(self):
        self.maxvalue = texttofloat(self.maxvalueinput.getText(),
                                    self.maxvalue)
        self.slider.setmax(self.maxvalue)
        self.setslidervalue(self.value)

    def sliderstepinputhchanged(self):
        self.valuestep = texttofloat(self.sliderstepinput.getText(),
                                     self.valuestep)
        self.slider.setstep(self.valuestep)
        self.setslidervalue(self.value)

    def sliderchanged(self):
        self.setslidervalue(self.slider.v(), False)

    def slidervalueinputchanged(self):
        self.setslidervalue(
            texttofloat(self.slidervalueinput.getText(), self.value))

    def checkboxchanged(self):
        self.value = self.checkbox.getchecked()

    def combocheckboxchanged(self):
        self.selected = self.combocheckbox.getchecked()

    def radioradioclicked(self):
        for child in self.parent.childs:
            isme = (child == self)
            child.radioradio.setchecked(isme)
            child.selected = isme
            print(isme)

    def textareachanged(self):
        self.value = self.textarea.getText()

    def setdatelabel(self):
        self.datelabel.html("{}".format(
            dateInputStrToDate(self.value).getTime()))

    def datechanged(self):
        self.value = self.date.v()
        self.setdatelabel()

    def colorchanged(self):
        self.value = self.color.v()
        self.colorlabel.html(self.value)

    def build(self):
        self.x().ac("schema")
        self.itemdiv = Div(["item", self.disposition])
        self.valuediv = Div(["value", self.disposition])
        if self.kind == "scalar":
            if self.disposition == "dict":
                if type(self.value) == bool:
                    self.disposition = "checkbox"
                else:
                    self.disposition = "string"
            if self.disposition == "string":
                self.stringvalueinput = TextInput().ac("string").setText(
                    self.value)
                self.stringvalueinput.ae("keyup", self.stringvalueinputchanged)
                self.valuediv.a(self.stringvalueinput)
            elif self.disposition == "slider":
                self.slidervalueinput = TextInput().ac("slidervalue").setText(
                    self.value).setchangecallback(self.slidervalueinputchanged)
                self.minvalueinput = TextInput().ac("sliderminmax").setText(
                    self.minvalue).setchangecallback(self.minvalueinputchanged)
                self.slider = Slider().ac("sliderslider").ae(
                    "change", self.sliderchanged)
                self.maxvalueinput = TextInput().ac("sliderminmax").setText(
                    self.maxvalue).setchangecallback(self.maxvalueinputchanged)
                self.sliderstepinput = TextInput().ac("sliderstep").setText(
                    self.valuestep).setchangecallback(
                        self.sliderstepinputhchanged)
                self.valuediv.a([
                    self.slidervalueinput, self.minvalueinput, self.slider,
                    self.maxvalueinput, self.sliderstepinput
                ])
                self.slider.setmin(self.minvalue).setmax(
                    self.maxvalue).setstep(self.valuestep)
                self.setslidervalue(
                    texttofloat(self.value, SCHEMA_SLIDER_DEFAULT_VALUE))
            elif self.disposition == "checkbox":
                self.value = (self.value is True)
                self.checkbox = CheckBox().ac("checkbox").setchecked(
                    self.value).ae("change", self.checkboxchanged)
                self.valuediv.a(self.checkbox)
            elif self.disposition == "textarea":
                self.textarea = TextArea().ac("textarea").setText(self.value)
                self.textarea.ae(["keyup", "change"], self.textareachanged)
                self.valuediv.a(self.textarea)
            elif self.disposition == "date":
                self.date = DateInput().ac("date").sv(self.value)
                self.date.ae(["keyup", "change"], self.datechanged)
                self.datelabel = Label().ac("datelabel")
                self.setdatelabel()
                self.valuediv.a([self.date, self.datelabel])
            elif self.disposition == "color":
                self.color = ColorInput().ac("color").sv(self.value)
                self.color.ae(["keyup", "change"], self.colorchanged)
                self.colorlabel = Label().ac("colorlabel").html(self.value)
                self.valuediv.a([self.color, self.colorlabel])
        self.helpdiv = Div(["box", "help"]).html("?")
        self.copydiv = Div(["box",
                            "copy"]).html("C").ae("mousedown",
                                                  self.copydivclicked)
        if isdict(self.parent):
            self.keydiv = Div("key")
            self.keyinput = TextInput().ac("key").setText(self.key)
            self.keyinput.ae("keyup", self.keyinputchanged)
            self.keydiv.a(self.keyinput)
            self.itemdiv.a(self.keydiv)
        if iscombo(self.parent):
            self.combodiv = Div(["box", "combo"])
            self.combocheckbox = CheckBox().ac("checkbox").setchecked(
                self.selected).ae("change", self.combocheckboxchanged)
            self.combodiv.a(self.combocheckbox)
            self.itemdiv.a(self.combodiv)
        if isradio(self.parent):
            self.radiodiv = Div(["box", "radio"])
            self.radioradio = Radio().ac("radio").setchecked(self.selected).ae(
                "mousedown", self.radioradioclicked)
            self.radiodiv.a(self.radioradio)
            self.itemdiv.a(self.radiodiv)
        self.itemdiv.a([self.valuediv, self.helpdiv, self.copydiv])
        if self.parent:
            self.deletediv = Div(["box", "delete"
                                  ]).html("X").ae("mousedown",
                                                  self.deletedivclicked)
            self.itemdiv.a(self.deletediv)
        if iscollection(self):
            self.openbutton = Div("openbutton").ae("mousedown",
                                                   self.openbuttonclicked)
            self.valuediv.a(self.openbutton)
        self.childsdiv = Div("childs")
        if self.childsopened:
            self.creatediv = Div("create")
            cc = self.createcombo
            self.createcombo = ComboBox().setoptions(
                [["create", "Create new"], ["scalar", "Scalar"],
                 ["slider", "Slider"], ["checkbox", "Checkbox"],
                 ["textarea", "Textarea"], ["date", "Date"], [
                     "color", "Color"
                 ], ["dict", "Dict"], ["list", "List"], ["combo", "Combo"],
                 ["radio", "Radio"], ["process", "Process"]], "create",
                self.createcombochanged).ac("createcombo")
            self.creatediv.a(self.createcombo)
            self.pastebutton = Button("Paste",
                                      self.pastebuttonpushed).ac("pastebutton")
            self.creatediv.a(self.pastebutton)
            self.childsdiv.a(self.creatediv)
            for child in self.childs:
                self.childsdiv.a(child)
        self.container = Div("container")
        self.container.a([self.itemdiv, self.childsdiv])
        self.a(self.container)
        return self

    def tojsontext(self):
        return JSON.stringify(self.toargs(), None, 2)

    def toargs(self):
        args = {}
        for arg in SCHEMA_DEFAULT_ARGS:
            args[arg[0]] = self[arg[0]]
        args["childsarg"] = []
        for child in self.childs:
            args["childsarg"].append(child.toargs())
        return args

    def __init__(self, args={}):
        super().__init__("div")
        self.parent = getitem(args, "parent", None)
        for arg in SCHEMA_DEFAULT_ARGS:
            self[arg[0]] = getitem(args, arg[0], arg[1])
        self.childs = []
        for childarg in self.childsarg:
            childarg["parent"] = self
            child = Schema(childarg)
            self.childs.append(child)
        self.build()

    def getchildbykey(self, key):
        for child in self.childs:
            if child.key == key:
                return child
        return None

    def getpathrec(self, sch, pathparts):
        if not sch:
            return None
        if len(pathparts) == 0:
            return sch
        key = pathparts[0]
        pathparts = pathparts[1:]
        if self.disposition == "dict":
            return self.getpathrec(self.getchildbykey(key), pathparts)
        else:
            return None

    def getpath(self, path):
        if path == "":
            pathparts = []
        else:
            pathparts = path.split("/")
        return self.getpathrec(self, pathparts)
Exemple #16
0
class Client:
    def __init__(self):
        self.isadmin = False
        self.root = ge("clientroot")
        self.owners = {}
        self.config = Config()
        self.authdone = False
        self.connectdone = False

    def driveeditclickedcallback(self, dir):
        ext = getext(dir)
        if ext == "bin":
            self.mainboard.setbookpath(dir, True)
            self.mainboard.tabpane.selectbykey("book")
            self.tabs.selectbykey("board")
            self.mainboard.getbookpage()
            return True

    def requestbots(self):
        getconn().sioreq({"kind": "getmybots"})

    def createbotdiv(self):
        self.botdiv = Div()
        self.botresultdiv = Div()
        self.botdiv.a(Button("Request bots", self.requestbots).mar(10))
        self.botdiv.a(Hlink("/bots", "Bots page"))
        self.botdiv.a(self.botresultdiv)

    def build(self):
        self.root.innerHTML = ""

        self.owners["config"] = self.config

        if self.dodirbrowser:
            self.maindirbrowser = DirBrowser({"id": "maindirbrowser"})
            self.owners["maindirbrowser"] = self.maindirbrowser
        else:
            self.maindirbrowser = Div()

        if self.dodrive:
            self.drive = DirBrowser({
                "id":
                "drive",
                "drive":
                True,
                "editclickedcallback":
                self.driveeditclickedcallback
            })
            self.owners["drive"] = self.drive
        else:
            self.drive = Div()

        self.createbotdiv()

        if self.doboard:
            self.mainboard = Board({
                "dobook": self.dobook,
                "dostoredanalysis": self.dostoredanalysis,
                "dostoredauto": self.dostoredauto,
                "dogames": self.dogames,
                "setposinfo": self.setposinfo,
                "dogamepreview": self.dogamepreview,
                "background": self.boardbackground,
                "autoanalysisdelay": self.autoanalysisdelay,
                "maxgames": self.maxgames,
                "gamesfilter": self.gamesfilter,
                "analysispvlength": self.analysispvlength
            })
            self.mainboard.setusername(self.username, self.usertoken)
            self.mainboard.tabpane.controlpanel.ac("subcontrolpanel")
            self.owners["mainboard"] = self.mainboard
        else:
            self.mainboard = Div()

        if self.dodocs:
            self.doc = Doc()
            self.srcdiv = self.doc.srcdiv
            self.owners["doc"] = self.doc
        else:
            self.doc = Div()
            self.srcdiv = Div()

        if self.doabout:
            self.about = Doc({
                "id": "about",
                "startpage": "about",
                "showcontentslink": False
            })
            self.owners["about"] = self.about
        else:
            self.about = Div()

        if self.isadmin:
            self.processpane = ProcessPane(
                {"configsch": self.config.getpath("processes")})
            self.processpane.processtabpane.controlpanel.ac("subcontrolpanel")
        else:
            self.processpane = Div("featureplaceholder").html(
                "Admin only feature.")

        self.forumgametab = Tab(
            "forumgame", "Forum game",
            Div("featureplaceholder").html("Forum game disabled."))
        if self.doforumgame:
            self.forumgame = Forumgame()
            self.forumgame.mainboard = self.mainboard
            self.owners["forumgame"] = self.forumgame
            self.forumgametab = Tab("forumgame", "Forum game", self.forumgame)

        self.tabs = TabPane({
            "id":
            "maintabpane",
            "fillwindow":
            True,
            "tabs": [
                Tab("config", "Config", self.config),
                Tab("upload", "Upload", FileUploader({"url": "/upload"})),
                Tab("board", "Board", self.mainboard), self.forumgametab,
                Tab("process", "Process", self.processpane),
                Tab("dirbrowser", "Dirbrowser", self.maindirbrowser),
                Tab("drive", "Drive", self.drive),
                Tab("bots", "Bots", self.botdiv),
                Tab("doc", "Doc", self.doc),
                Tab("src", "Src", self.srcdiv),
                Tab("log", "Log",
                    getconn().log),
                getconn().profiletab,
                Tab("about", "About", self.about)
            ],
            "selected":
            "drive"
        })

        self.root.appendChild(self.tabs.e)

        qseltab = queryparams.get("tab", None)
        if qseltab:
            self.tabs.selectbykey(qseltab)

    def onready(self):
        getconn().sioreq({"kind": "connected", "queryparams": queryparams})

    def setloadinfo(self, content):
        ge("connectmsg").innerHTML = content

    def onconnect(self):
        self.connectdone = True
        if self.authdone:
            self.onready()
        else:
            self.setloadinfo("Authenticating, please wait ...")

    def onauth(self):
        self.authdone = True
        if self.connectdone:
            self.onready()
        else:
            self.setloadinfo(
                "Authenticated, connecting to server, please wait ...")

    def getschemaconfigfromobj(self, obj):
        self.config.setschemaconfig(obj["schemaconfig"])

        self.dodocs = self.config.get("global/dodocs", True)
        self.dobook = self.config.get("global/dobook", True)
        self.username = self.config.get("global/username")
        self.usertoken = self.config.get("global/usertoken")
        self.dostoredanalysis = self.config.get("global/dostoredanalysis",
                                                True)
        self.dodirbrowser = self.config.get("global/dodirbrowser", True)
        self.dodrive = self.config.get("global/dodrive", True)
        self.dogames = self.config.get("global/dogames", True)
        self.doboard = self.config.get("global/doboard", True)
        self.doabout = self.config.get("global/doabout", True)
        self.dogamepreview = self.config.get("global/dogamepreview", True)
        self.doforumgame = self.config.get("global/doforumgame", True)
        self.dostoredauto = self.config.get("global/dostoredauto", True)
        self.boardbackground = self.config.get("layout/boardbackground",
                                               "wood.jpg")
        self.autoanalysisdelay = self.config.get("global/autoanalysisdelay",
                                                 True)
        self.maxgames = self.config.get("global/maxgames", 25)
        self.gamesfilter = self.config.get("global/gamesfilter", "")
        self.analysispvlength = self.config.get("global/analysispvlength", 4)
        self.setposinfo = obj["setposinfo"]

    def buildfromconfiginobj(self, obj):
        self.getschemaconfigfromobj(obj)
        self.build()

    def setmybots(self, obj):
        botprofiles = obj["mybots"]
        self.botresultdiv.x()
        __pragma__("jsiter")
        for id in botprofiles:
            botprofile = botprofiles[id]
            self.botresultdiv.a(Div().html("{} {}".format(
                botprofile["username"],
                cpick(botprofile["online"], "online",
                      "offline"))).fs(25).pad(5))
            self.botresultdiv.a(Div().html(
                "follow {} games {} last move {}".format(
                    botprofile["nbFollowers"], botprofile["count"]["all"],
                    botprofile["lastmoveago"])).fs(20).pad(3))
            self.botresultdiv.a(Div().html("last players {}".format(
                botprofile["lastplayers"])).fs(20).pad(3))
        __pragma__("nojsiter")

    def siores(self, obj):
        self.isadmin = obj["isadmin"]
        if queryparams.get("noadmin", "false") == "true":
            self.isadmin = False
        if "kind" in obj:
            kind = obj["kind"]
            if kind == "buffered":
                for item in obj["items"]:
                    self.siores(item)
            elif kind == "connectedack":
                self.buildfromconfiginobj(obj)
            elif kind == "configsaved":
                window.alert("Config saved, {} characters".format(obj["size"]))
                location.reload()
            elif kind == "alert":
                window.alert(obj["data"])
                if obj["reload"]:
                    location.reload()
            elif kind == "proc":
                self.processpane.siores(obj)
            elif kind == "storedb":
                pass
            elif kind == "storedbfailed":
                pass
            elif kind == "retrievedbfailed":
                pass
            elif kind == "mybots":
                self.setmybots(obj)
            else:
                if IS_DEV():
                    self.owners[obj["owner"]].siores(obj)
                else:
                    try:
                        self.owners[obj["owner"]].siores(obj)
                    except:
                        print("could not handle", obj)

            if kind == "showdoc":
                if obj["switchtodoctab"]:
                    self.tabs.selectbykey("doc")

    def authtimeout(self):
        if not self.authdone:
            print("authtimeout")
            self.onauth()

    def startup(self):
        createconn({
            "connectcallback": self.onconnect,
            "authcallback": self.onauth,
            "siorescallback": self.siores
        })
        if IS_DEV():
            setTimeout(self.authtimeout, 3000)
Exemple #17
0
class Connection:
    def signincallback(self):
        email = self.emailinput.getText()
        password = self.passwordinput.getText()
        print("signing in user with", email, password)
        firebase.auth().signInWithEmailAndPassword(email, password).then(
            lambda: print("ok"),
            lambda error: window.alert("{}".format(error)))

    def signoutcallback(self):
        if firebase.auth().currentUser:
            print("signing out")
            firebase.auth().signOut()
        else:
            window.alert("Already signed out.")

    def signupcallback(self):
        email = self.emailinput.getText()
        password = self.passwordinput.getText()
        print("signing up user with", email, password)
        firebase.auth().createUserWithEmailAndPassword(email, password).then(
            lambda: print("ok"),
            lambda error: window.alert("{}".format(error)))

    def sendverificationcallback(self):
        email = self.emailinput.getText()
        firebase.auth().currentUser.sendEmailVerification().then(
            lambda: window.alert("Verification email has been sent to {} !".
                                 format(email)),
            lambda error: window.alert("{}".format(error)))

    def resetpasswordcallback(self):
        email = self.emailinput.getText()
        firebase.auth().sendPasswordResetEmail(email).then(
            lambda: window.alert("Password reset email has been sent to {} !".
                                 format(email)),
            lambda error: window.alert("{}".format(error)))

    def updatedisplaynamecallback(self):
        getconn().sioreq({
            "kind": "updateuserdisplayname",
            "displayname": self.displaynameinput.getText(),
            "uid": self.uid
        })

    def updatephotourlcallback(self):
        getconn().sioreq({
            "kind": "updateuserphotourl",
            "photourl": self.photourlinput.getText(),
            "uid": self.uid
        })

    def linkgoogleok(self, result):
        print(result)
        window.alert("Account linked with Google !")
        location.reload()

    def linkmailok(self, usercred):
        print(usercred)
        window.alert("Account linked with Email !")
        location.reload()

    def linkgooglecallback(self):
        provider = __new__(firebase.auth.GoogleAuthProvider())
        firebase.auth().currentUser.linkWithPopup(provider).then(
            self.linkgoogleok,
            lambda err: window.alert("Link Google failed: {}".format(err)))

    def linkmailcallback(self):
        credential = firebase.auth.EmailAuthProvider.credential(
            self.emailinput.getText(), self.passwordinput.getText())
        firebase.auth().currentUser.linkAndRetrieveDataWithCredential(
            credential).then(
                self.linkmailok,
                lambda err: window.alert("Link Email failed: {}".format(err)))

    def helpcallback(self):
        self.sioreq({"kind": "getdoc", "data": "profilehelp", "owner": "doc"})

    def buildsignupdiv(self):
        self.signupdiv = Div()
        self.signupmaildiv = Div("signupmaildiv")
        self.emaillabel = Span().html("Email:")
        self.emailinput = TextInput().ac("profiletextinput").w(250)
        self.passwordlabel = Span().html("Password:"******"profiletextinput").w(100)
        self.helpbutton = Button("Help", self.helpcallback).ac("helpbutton")
        self.signinbutton = Button("Sign in", self.signincallback)
        self.signoutbutton = Button("Sign out", self.signoutcallback)
        self.signupbutton = Button("Sign up", self.signupcallback)
        self.sendverificationbutton = Button("Send verification",
                                             self.sendverificationcallback)
        self.resetpasswordbutton = Button("Reset password",
                                          self.resetpasswordcallback)
        self.linkgooglebutton = Button("Link Google", self.linkgooglecallback)
        self.linkmailbutton = Button("Link Email", self.linkmailcallback)
        self.userinfodiv = Div("userinfodiv")
        self.signupmaildiv.a([
            self.helpbutton, self.emaillabel, self.emailinput,
            self.passwordlabel, self.passwordinput, self.signinbutton,
            self.signoutbutton, self.signupbutton, self.sendverificationbutton,
            self.resetpasswordbutton, self.linkgooglebutton,
            self.linkmailbutton
        ])
        self.userdetailsdiv = Div("userdetailsdiv")
        self.displaynamelabel = Span().html("Display name:")
        self.displaynameinput = TextInput().ac("profiletextinput").w(250)
        self.photourllabel = Span().html("Photo url:")
        self.photourlinput = TextInput().ac("profiletextinput").w(250)
        self.updatedisplaynamebutton = Button("Update display name",
                                              self.updatedisplaynamecallback)
        self.updatephotourlbutton = Button("Update photo url",
                                           self.updatephotourlcallback)
        self.userdetailsdiv.a([
            self.displaynamelabel, self.displaynameinput,
            self.updatedisplaynamebutton, self.photourllabel,
            self.photourlinput, self.updatephotourlbutton
        ])
        self.photodiv = Div("photodiv")
        self.signupdiv.a([
            self.signupmaildiv, self.userdetailsdiv, self.userinfodiv,
            self.photodiv
        ])
        self.firebaseuidiv = Div().sa("id", "firebaseuidiv")
        self.signupdiv.a(self.firebaseuidiv)

    def logobj(self, logkind, obj, prompt):
        objstr = JSON.stringify(obj)
        if self.log:
            li = LogItem({"text": objstr, "kind": logkind, "prompt": prompt})
            li.container.ac("socketlog")
            self.log.log(li)

    def emit(self, kind, obj):
        self.logobj("info", obj, "-> ")
        if self.rawsocket:
            self.rawsocket.emit(kind, obj)

    def sioreq(self, obj):
        obj["uid"] = self.getuid()
        #print("sioreq", obj)
        self.emit("sioreq", obj)

    def onconnect(self):
        if self.log:
            self.logobj("success", "socket connected ok", "socket message: ")
        if not self.configloaded:
            self.sioreq({"kind": "sendfirebaseconfig"})
        if self.connectcallback:
            self.connectcallback()

    def siores(self, obj):
        if self.log:
            self.logobj("normal", obj, "<- ")
        if self.configloaded:
            if self.siorescallback:
                self.siorescallback(obj)
        else:
            kind = obj["kind"]
            if kind == "firebaseconfig":
                self.configloaded = True
                self.startfirebase(obj["firebaseconfig"])

    def getuserdisplayname(self):
        if self.user:
            if self.displayName:
                return self.displayName
            return self.email
        return None

    def setprofiletab(self):
        self.profiletab.rc(["profilelogged", "profileanon"])
        dn = self.getuserdisplayname()
        if dn:
            self.profiletab.container.html(dn)
            self.profiletab.ac("profilelogged")
        else:
            if self.user:
                self.profiletab.container.html("Anonymous")
                self.profiletab.ac("profileanon")
            else:
                self.profiletab.container.html("Profile")

    def signinanonymously(self):
        firebase.auth().signInAnonymously().then(lambda: print("ok"),
                                                 lambda error: print(error))

    def userstatusverbal(self):
        if not self.user:
            return "[logged out]"
        if self.user.isAnonymous:
            return "anonymous"
        return cpick(self.emailVerified, "verified", "not verified")

    def userverified(self):
        if not self.user:
            return False
        if self.user.isAnonymous:
            return False
        return self.user.emailVerified

    def authstatechanged(self, user):
        self.user = user
        self.passwordinput.setText("")
        if user:
            self.displayName = user.displayName
            self.email = user.email
            self.emailVerified = user.emailVerified
            self.photoURL = user.photoURL
            self.isAnonymous = user.isAnonymous
            self.uid = user.uid
            self.providerData = user.providerData
            print("user:"******"name : <span class='{}'>{}</span>".format(
                    cpick(self.displayName, "uiinfo", "uiinfored"),
                    getelse(self.displayName, "&lt;NA&gt;"))).pt(5)
            self.emailinfodiv = Div().html(
                "email : <span class='{}'>{}</span>".format(
                    cpick(self.email, "uiinfo", "uiinfored"),
                    getelse(self.email, "&lt;NA&gt;")))
            self.verifiedinfodiv = Div().html(
                "status : <span class='{}'>{}</span>".format(
                    cpick(self.userverified(), "uiinfo", "uiinfored"),
                    self.userstatusverbal()))
            self.photourldiv = Div().html(
                "photo url : <span class='{}'>{}</span>".format(
                    cpick(self.photoURL, "uiinfo", "uiinfored"),
                    getelse(self.photoURL, "&lt;NA&gt;")))
            self.uidinfodiv = Div().html(
                "uid : <span class='uiinfo'>{}</span>".format(self.uid)).pb(8)
            self.userinfodiv.x().a([
                self.nameinfodiv, self.emailinfodiv, self.verifiedinfodiv,
                self.photourldiv, self.uidinfodiv
            ])
            self.emailinput.setText(self.email)
            self.displaynameinput.setText(self.displayName)
            self.photourlinput.setText(self.photoURL)
            self.photodiv.x()
            if self.photoURL:
                self.photodiv.html(
                    "<img src='{}' class='userphotoimg'></img>".format(
                        self.photoURL))
        else:
            print("no user")
            self.userinfodiv.x().a([
                Div().html("Please sign up or sign in !"),
                Button("Sign in anonymously", self.signinanonymously())
            ])
        self.setprofiletab()
        self.userinfodiv.fs(cpick(self.user, 10, 14))
        if user:
            if self.authcallback:
                self.authcallback()

    def initializefirebase(self):
        print("initializing firebase from", self.firebaseconfig)
        firebase.initializeApp(self.firebaseconfig)
        firebase.auth().onAuthStateChanged(self.authstatechanged)

    def initializefirebaseui(self):
        self.uiConfig = {
            "signInSuccessUrl":
            '/',
            "signInOptions": [
                firebase.auth.GoogleAuthProvider.PROVIDER_ID,
                #firebase.auth.FacebookAuthProvider.PROVIDER_ID,
                #firebase.auth.TwitterAuthProvider.PROVIDER_ID,
                #firebase.auth.GithubAuthProvider.PROVIDER_ID,
                firebase.auth.EmailAuthProvider.PROVIDER_ID,
                #firebase.auth.PhoneAuthProvider.PROVIDER_ID
            ],
            "tosUrl":
            '/tos'
        }
        print("initializing firebase ui from", self.uiConfig)
        self.ui = __new__(firebaseui.auth.AuthUI(firebase.auth()))
        self.ui.start(self.firebaseuidiv.e, self.uiConfig)

    def startfirebase(self, firebaseconfig):
        self.firebaseconfig = firebaseconfig
        self.initializefirebase()
        self.initializefirebaseui()

    def getuid(self):
        if self.user:
            return self.uid
        return "mockuser"

    def __init__(self, args={}):
        self.configloaded = False
        self.user = None
        if window.location.protocol == "https:":
            self.ws_scheme = "wss://"
        else:
            self.ws_scheme = "ws://"
        self.SUBMIT_URL = self.ws_scheme + window.location.host
        print("creating socket {}".format(self.SUBMIT_URL))
        self.rawsocket = io.connect(self.SUBMIT_URL)
        print("socket created ok")
        self.log = Log()
        self.connectcallback = args.get("connectcallback", None)
        self.authcallback = args.get("authcallback", None)
        self.siorescallback = args.get("siorescallback", None)
        self.buildsignupdiv()
        self.profiletab = Tab("profile", "Profile", self.signupdiv)
        if self.rawsocket:
            self.rawsocket.on("connect", self.onconnect)
            self.rawsocket.on("siores", self.siores)
Exemple #18
0
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()