예제 #1
0
 def get_client_info(self, ci):
     #version info:
     ctype = ci.strget("type", "unknown")
     title = "%s client version" % ctype
     title += caps_to_version(ci)
     chost = ci.strget("hostname")
     conn_info = ""
     if chost:
         conn_info = "connected from %s " % chost
     cinfo = ci.dictget("connection")
     if cinfo:
         cinfo = typedict(cinfo)
         conn_info += "using %s %s" % (cinfo.strget("type"),
                                       cinfo.strget("protocol-type"))
         conn_info += ", with %s and %s" % (cinfo.strget("encoder"),
                                            cinfo.strget("compressor"))
     gl_info = self.get_gl_info(ci.dictget("opengl"))
     #audio
     audio_info = []
     for mode in ("speaker", "microphone"):
         audio_info.append(self._audio_info(ci, mode))
     audio_info.append(self._avsync_info(ci))
     #batch delay / latency:
     b_info = typedict(ci.dictget("batch", {}))
     bi_info = typedict(b_info.dictget("delay", {}))
     bcur = bi_info.intget("cur")
     bavg = bi_info.intget("avg")
     batch_info = "batch delay: %i (%i)" % (
         bcur,
         bavg,
     )
     #client latency:
     pl = self.slidictget("connection", "client", "ping_latency")
     lcur = pl.intget("cur")
     lavg = pl.intget("avg")
     lmin = pl.intget("min")
     bl_color = GREEN
     if bcur > 50 or (lcur > 20 and lcur > 2 * lmin):
         bl_color = YELLOW
     elif bcur > 100 or (lcur > 20 and lcur > 3 * lmin):
         bl_color = RED
     batch_latency = batch_info.ljust(24) + "latency: %i (%i)" % (lcur,
                                                                  lavg)
     #speed / quality:
     edict = typedict(ci.dictget("encoding") or {})
     qs_info = ""
     qs_color = GREEN
     if edict:
         sinfo = typedict(edict.dictget("speed") or {})
         if sinfo:
             cur = sinfo.intget("cur")
             avg = sinfo.intget("avg")
             qs_info = "speed: %s%% (avg: %s%%)" % (cur, avg)
         qinfo = typedict(edict.dictget("quality") or {})
         if qinfo:
             qs_info = qs_info.ljust(24)
             cur = qinfo.intget("cur")
             avg = qinfo.intget("avg")
             qs_info += "quality: %s%% (avg: %s%%)" % (cur, avg)
             if avg < 70:
                 qs_color = YELLOW
             if avg < 50:
                 qs_color = RED
     return tuple((s, c) for s, c in (
         (title, WHITE),
         (conn_info, WHITE),
         (gl_info, WHITE),
         (csv(audio_info), WHITE),
         (batch_latency, bl_color),
         (qs_info, qs_color),
     ) if s)
예제 #2
0
    def do_update_screen(self):
        self.log("do_update_screen()")
        #c = self.stdscr.getch()
        #if c==curses.KEY_RESIZE:
        height, width = self.stdscr.getmaxyx()
        #log.info("update_screen() %ix%i", height, width)
        title = get_title()
        sli = self.server_last_info

        def _addstr(pad, y, x, s, *args):
            if len(s) + x >= width - pad:
                s = s[:max(0, width - x - 2 - pad)] + ".."
            self.stdscr.addstr(y, x, s, *args)

        def addstr_main(y, x, s, *args):
            _addstr(0, y, x, s, *args)

        def addstr_box(y, x, s, *args):
            _addstr(2, y, x, s, *args)

        try:
            x = max(0, width // 2 - len(title) // 2)
            addstr_main(0, x, title, curses.A_BOLD)
            if height <= 1:
                return
            server_info = self.slidictget("server")
            build = self.slidictget("server", "build")
            vstr = caps_to_version(build)
            mode = server_info.strget("mode", "server")
            python_info = typedict(server_info.dictget("python", {}))
            bits = python_info.intget("bits", 32)
            server_str = "Xpra %s server version %s %i-bit" % (mode, vstr,
                                                               bits)
            proxy_info = self.slidictget("proxy")
            if proxy_info:
                proxy_platform_info = typedict(
                    proxy_info.dictget("platform", {}))
                proxy_platform = proxy_platform_info.strget("")
                proxy_release = proxy_platform_info.strget("release")
                proxy_build_info = typedict(proxy_info.dictget("build", {}))
                proxy_version = proxy_build_info.strget("version")
                proxy_distro = proxy_info.strget("linux_distribution")
                server_str += " via: %s proxy version %s" % (platform_name(
                    proxy_platform, proxy_distro
                    or proxy_release), std(proxy_version or "unknown"))
            addstr_main(1, 0, server_str)
            if height <= 2:
                return
            #load and uptime:
            now = datetime.now()
            uptime = ""
            elapsed_time = server_info.intget("elapsed_time")
            if elapsed_time:
                td = timedelta(seconds=elapsed_time)
                uptime = " up %s" % str(td).lstrip("0:")
            clients_info = self.slidictget("clients")
            nclients = clients_info.intget("")
            load_average = ""
            load = sli.inttupleget("load")
            if load and len(load) == 3:
                float_load = tuple(v / 1000.0 for v in load)
                load_average = ", load average: %1.2f, %1.2f, %1.2f" % float_load
            addstr_main(
                2, 0, "xpra top - %s%s, %2i users%s" %
                (now.strftime("%H:%M:%S"), uptime, nclients, load_average))
            if height <= 3:
                return
            thread_info = self.slidictget("threads")
            rinfo = "%i threads" % thread_info.intget("count")
            server_pid = server_info.intget("pid", 0)
            if server_pid:
                rinfo += ", pid %i" % server_pid
                machine_id = server_info.get("machine-id")
                if machine_id is None or machine_id == get_machine_id():
                    try:
                        process = self.psprocess.get(server_pid)
                        if not process:
                            import psutil
                            process = psutil.Process(server_pid)
                            self.psprocess[server_pid] = process
                        else:
                            cpu = process.cpu_percent()
                            rinfo += ", %i%% CPU" % (cpu)
                    except Exception:
                        pass
            cpuinfo = self.slidictget("cpuinfo")
            if cpuinfo:
                rinfo += ", %s" % cpuinfo.strget("hz_actual")
            elapsed = monotonic_time() - self.server_last_info_time
            color = WHITE
            if self.server_last_info_time == 0:
                rinfo += " - no server data"
            elif elapsed > 2:
                rinfo += " - last updated %i seconds ago" % elapsed
                color = RED
            addstr_main(3, 0, rinfo, curses.color_pair(color))
            if height <= 4:
                return
            #display:
            dinfo = []
            server = self.slidictget("server")
            rws = server.intpair("root_window_size", None)
            if rws:
                sinfo = "%ix%i display" % (rws[0], rws[1])
                mds = server.intpair("max_desktop_size")
                if mds:
                    sinfo += " (max %ix%i)" % (mds[0], mds[1])
                dinfo.append(sinfo)
            cursor_info = self.slidictget("cursor")
            if cursor_info:
                cx, cy = cursor_info.inttupleget("position", (0, 0))
                dinfo.append("cursor at %ix%i" % (cx, cy))
            display_info = self.slidictget("display")
            pid = display_info.intget("pid")
            if pid:
                dinfo.append("pid %i" % pid)
            addstr_main(4, 0, csv(dinfo))
            if height <= 5:
                return
            hpos = 5
            gl_info = self.get_gl_info(display_info.dictget("opengl"))
            if gl_info:
                addstr_main(5, 0, gl_info)
                hpos += 1

            if hpos < height - 3:
                hpos += 1
                if nclients == 0:
                    addstr_main(hpos, 0, "no clients connected")
                else:
                    addstr_main(
                        hpos, 0,
                        "%i client%s connected:" % (nclients, engs(nclients)))
                hpos += 1
            client_info = self.slidictget("client")
            client_no = 0
            while True:
                ci = client_info.dictget(client_no)
                if not ci:
                    break
                client_no += 1
                ci = typedict(ci)
                session_id = ci.strget("session-id")
                if session_id:
                    #don't show ourselves:
                    if session_id == self.session_id:
                        continue
                elif not ci.boolget("windows", True):
                    #for older servers, hide any client that doesn't display windows:
                    continue
                ci = self.get_client_info(ci)
                l = len(ci)
                if hpos + 2 + l > height:
                    if hpos < height:
                        more = nclients - client_no
                        addstr_box(
                            hpos, 0,
                            "%i client%s not shown" % (more, engs(more)),
                            curses.A_BOLD)
                    break
                self.box(1, hpos, width - 2, 2 + l)
                for i, info in enumerate(ci):
                    info_text, color = info
                    cpair = curses.color_pair(color)
                    addstr_box(hpos + i + 1, 2, info_text, cpair)
                hpos += 2 + l

            windows = self.slidictget("windows")
            if hpos < height - 3:
                hpos += 1
                addstr_main(hpos, 0,
                            "%i window%s:" % (len(windows), engs(windows)))
                hpos += 1
            wins = tuple(windows.values())
            nwindows = len(wins)
            for win_no, win in enumerate(wins):
                wi = self.get_window_info(typedict(win))
                l = len(wi)
                if hpos + 2 + l > height:
                    if hpos < height:
                        more = nwindows - win_no
                        addstr_main(hpos, 0, "terminal window is too small: %i window%s not shown" % \
                                           (more, engs(more)), curses.A_BOLD)
                    break
                self.box(1, hpos, width - 2, 2 + l)
                for i, info in enumerate(wi):
                    info_text, color = info
                    cpair = curses.color_pair(color)
                    addstr_box(hpos + i + 1, 2, info_text, cpair)
                hpos += 2 + l
        except Exception as e:
            self.err(e)