# Copyright (c) 2014-2017 esotericnonsense (Daniel Edgecumbe) # Distributed under the MIT software license, see the accompanying # file COPYING or https://opensource.org/licenses/mit-license.php import math import curses import asyncio import view class NetView(view.View): _mode_name = "net" def __init__(self): self._nettotals_history = [] super().__init__() async def _draw(self): self._clear_init_pad() deltas = [] if self._nettotals_history: hist = self._nettotals_history i = 1 while i < len(hist): prev = hist[i-1] current = hist[i] seconds = (current["timemillis"] - prev["timemillis"]) / 1000 if seconds <= 0: continue up = current["totalbytessent"] - prev["totalbytessent"] down = current["totalbytesrecv"] - prev["totalbytesrecv"] deltas.append( (up/seconds, down/seconds), ) i += 1 if not self._nettotals_history or len(deltas) < 1: await self._draw_no_chart() else: await self._draw_chart(deltas) self._draw_pad_to_screen() async def _draw_no_chart(self): CRED = curses.color_pair(3) CBOLD = curses.A_BOLD self._pad.addstr(0, 1, "no network information yet", CRED + CBOLD) self._pad.addstr(1, 1, "please wait a few seconds...", CRED) async def _draw_chart(self, deltas): ph, pw = 20, 100 plot_height = (ph-3) // 2 plot_offset = plot_height chart_offset = 13 chart_width = pw - chart_offset CGREEN = curses.color_pair(1) CCYAN = curses.color_pair(2) CBOLD = curses.A_BOLD CREVERSE = curses.A_REVERSE if deltas: if len(deltas) > chart_width: deltas = deltas[-chart_width:] up_str = "Up: {: 9.2f}kB/s".format(deltas[-1][1]/1024).rjust(10) down_str = "Down: {: 9.2f}kB/s".format(deltas[-1][0]/1024).rjust(10) total_str = "Total: {: 9.2f}kB/s".format((deltas[-1][0] + deltas[-1][1])/1024).rjust(10) self._pad.addstr(ph-2, pw-62, up_str, CBOLD + CCYAN) self._pad.addstr(ph-2, pw-42, down_str, CBOLD + CGREEN) self._pad.addstr(ph-2, pw-20, total_str, CBOLD) max_up = max(delta[0] for delta in deltas) max_down = max(delta[1] for delta in deltas) max_total = max(max_up, max_down) if max_total > 0: if max_up > 0: height = int(math.ceil((1.0 * plot_height * max_up) / max_total)) self._pad.addstr(plot_offset-height, 1, "{: 5.0f}kB/s".format(max_up//1024).rjust(10), CBOLD) if max_down > 0: height = int(math.ceil((1.0 * plot_height * max_down) / max_total)) self._pad.addstr(plot_offset-1+height, 1, "{: 5.0f}kB/s".format(max_down//1024).rjust(10), CBOLD) for i, delta in enumerate(deltas): if i > chart_width: break height = int(math.ceil((1.0 * plot_height * deltas[i][0]) / max_total)) for y in range(0, height): self._pad.addstr(plot_offset-1-y, i+12, " ", CCYAN + CREVERSE) height = int(math.ceil((1.0 * plot_height * deltas[i][1]) / max_total)) for y in range(0, height): self._pad.addstr(plot_offset+y, i+12, " ", CGREEN + CREVERSE) async def on_nettotals(self, key, obj): try: self._nettotals_history.append(obj["result"]) except KeyError: pass # Avoid memory leak. if len(self._nettotals_history) > 500: self._nettotals_history = self._nettotals_history[:300] await self._draw_if_visible()