def set_auth_info_from_token(token): """Set the authentication by providing a TimeTagger webtoken.""" payload_base64 = token.split(".")[1].replace("_", "/") auth_info = JSON.parse( window.decodeURIComponent(window.escape(window.atob(payload_base64)))) auth_info.token = token localStorage.setItem("timetagger_auth_info", JSON.stringify(auth_info))
async def _push(self, kind, authtoken): # Build url url = location.protocol + "//" + location.hostname + ":" + location.port url = url.rstrip(":") + "/api/v1/" + kind # Take items, only proceed if nonempty items = self._to_push[kind] if len(items.keys()) == 0: return self._to_push[kind] = {} # Fetch and wait for response init = dict( method="PUT", body=JSON.stringify(items.values()), headers={"authtoken": authtoken}, ) try: res = await window.fetch(url, init) except Exception as err: res = dict(status=0, statusText=str(err), text=lambda: "") # Process response if res.status != 200: # The server was not able to process the request, maybe the # wifi is down or the server is restarting. # Put items back, but don't overwrite if the item was updated again. for key, item in items.items(): self._to_push[kind].setdefault(key, item) self._set_state( "error") # is usually less bad than the fail's below text = await res.text() console.warn(res.status + " (" + res.statusText + ") " + text) # Also notify the user for 402 errors if res.status == 402 and window.canvas: window.canvas.notify_once(text) else: # Success, but it can still mean that some records failed. In this # case these records are likely corrupt, so we delete them, and # will get the server's version back when we pull. d = JSON.parse(await res.text()) # d.accepted -> list of ok keys for key in d.fail: self[kind]._drop(key) for err in d.errors: self._set_state("warning") console.warn(f"Server dropped a {kind}: {err}")
def _receive_command(self, command): """ Process a command send from the server. """ cmd = command[0] if cmd == 'PING': # Used for roundtrip stuff, do at least one iter loop here ... window.setTimeout(self.send_command, 10, 'PONG', command[1]) elif cmd == 'INIT_DONE': window.flexx.spin(None) while len(self._pending_commands): self._receive_raw_command(self._pending_commands.pop(0)) self._pending_commands = None # print('init took', time() - self._init_time) elif cmd == 'PRINT': (window.console.ori_log or window.console.log)(command[1]) elif cmd == 'EXEC': eval(command[1]) elif cmd == 'EVAL': x = None if len(command) == 2: x = eval(command[1]) elif len(command) == 3: x = eval('this.instances.' + command[1] + '.' + command[2]) console.log(str(x)) # print (and thus also sends back result) elif cmd == 'EVALANDRETURN': try: x = eval(command[1]) except Exception as err: x = err try: sx = JSON.stringify(x) except Exception as err: sx = '"' + str(x) + '"' eval_id = command[2] # to identify the result in Python self.send_command("EVALRESULT", sx, eval_id) elif cmd == 'INVOKE': id, name, args = command[1:] ob = self.instances.get(id, None) if ob is None: console.warn('Cannot invoke %s.%s; ' 'session does not know it (anymore).' % (id, name)) elif ob._disposed is True: pass # deleted, but other end might not be aware when command was send else: ob[name](*args) elif cmd == 'INSTANTIATE': self.instantiate_component(*command[1:]) # module, cname, id, args, kwargs elif cmd == 'DISPOSE': id = command[1] c = self.instances.get(id, None) if c is not None and c._disposed is False: # else: no need to warn c._dispose() self.send_command('DISPOSE_ACK', command[1]) self.instances.pop(id, None) # Drop local reference now elif cmd == 'DISPOSE_ACK': self.instances.pop(command[1], None) # Drop reference elif cmd == 'DEFINE': #and command[1] == 'JS' or command[1] == 'DEFINE-JS-EVAL '): kind, name, code = command[1:] window.flexx.spin() address = window.location.protocol + '//' + self.ws_url.split('/')[2] code += '\n//# sourceURL=%s/flexx/assets/shared/%s\n' % (address, name) if kind == 'JS-EVAL': eval(code) elif kind == 'JS': # With this method, sourceURL does not work on Firefox, # but eval might not work for assets that don't "use strict" # (e.g. Bokeh). Note, btw, that creating links to assets does # not work because these won't be loaded on time. el = window.document.createElement("script") el.id = name el.innerHTML = code window.flexx.asset_node.appendChild(el) elif kind == 'CSS': el = window.document.createElement("style") el.type = "text/css" el.id = name el.innerHTML = code window.flexx.asset_node.appendChild(el) else: window.console.error('Dont know how to DEFINE ' + name + ' with "' + kind + '".') elif cmd == 'OPEN': window.win1 = window.open(command[1], 'new', 'chrome') else: window.console.error('Invalid command: "' + cmd + '"') return command
def _save_settings(self): x = JSON.stringify(self._cache) localStorage.setItem("timetagger_local_settings", x)