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, "<NA>"))).pt(5) self.emailinfodiv = Div().html( "email : <span class='{}'>{}</span>".format( cpick(self.email, "uiinfo", "uiinfored"), getelse(self.email, "<NA>"))) 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, "<NA>"))) 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)
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)
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,"<NA>"))).pt(5) self.emailinfodiv = Div().html("email : <span class='{}'>{}</span>".format(cpick(self.email, "uiinfo", "uiinfored"), getelse(self.email, "<NA>"))) 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,"<NA>"))) 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) ######################################################
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()