add torrentdetails state, allow state switching, move some formating to format_utils

This commit is contained in:
Nick 2011-02-01 17:23:15 +01:00
parent 007dd67ea1
commit 5d46d2aee5
6 changed files with 501 additions and 69 deletions

View File

@ -48,6 +48,7 @@ import deluge.component as component
from deluge.ui.client import client
import deluge.common
from deluge.ui.coreconfig import CoreConfig
from deluge.ui.sessionproxy import SessionProxy
from deluge.ui.console.statusbars import StatusBars
from deluge.ui.console.eventlog import EventLog
import screen
@ -156,7 +157,10 @@ class ConsoleUI(component.Component):
log.debug("Using encoding: %s", self.encoding)
# Load all the commands
self._commands = load_commands(os.path.join(UI_PATH, 'commands'))
#self._commands = load_commands(os.path.join(UI_PATH, 'commands'))
# start up the session proxy
self.sessionproxy = SessionProxy()
client.set_disconnect_callback(self.on_client_disconnect)
@ -213,9 +217,9 @@ class ConsoleUI(component.Component):
# We want to do an interactive session, so start up the curses screen and
# pass it the function that handles commands
colors.init_colors()
self.statusbars = StatusBars()
from modes.alltorrents import AllTorrents
self.screen = AllTorrents(stdscr, self.coreconfig, self.encoding)
self.statusbars = StatusBars()
self.eventlog = EventLog()
self.screen.topbar = "{!status!}Deluge " + deluge.common.get_version() + " Console"
@ -264,6 +268,12 @@ class ConsoleUI(component.Component):
if not batch and self.interactive:
self.screen.refresh()
def set_mode(self, mode):
reactor.removeReader(self.screen)
self.screen = mode
self.statusbars.screen = self.screen
reactor.addReader(self.screen)
def write(self, line):
"""
Writes a line out depending on if we're in interactive mode or not.

View File

@ -46,7 +46,9 @@ from deluge.ui.sessionproxy import SessionProxy
from popup import Popup,SelectablePopup,MessagePopup
from add_util import add_torrent
from input_popup import InputPopup
from torrentdetail import TorrentDetail
import format_utils
try:
import curses
@ -146,7 +148,7 @@ class StateUpdater(component.Component):
self._status_cb(state,refresh)
class AllTorrents(BaseMode, component.Component):
class AllTorrents(BaseMode):
def __init__(self, stdscr, coreconfig, encoding=None):
self.formatted_rows = None
self.cursel = 1
@ -166,7 +168,6 @@ class AllTorrents(BaseMode, component.Component):
BaseMode.__init__(self, stdscr, encoding)
curses.curs_set(0)
self.stdscr.notimeout(0)
self.sessionproxy = SessionProxy()
self._status_fields = ["queue","name","total_wanted","state","progress","num_seeds","total_seeds",
"num_peers","total_peers","download_payload_rate", "upload_payload_rate"]
@ -180,21 +181,21 @@ class AllTorrents(BaseMode, component.Component):
self._info_fields = [
("Name",None,("name",)),
("State", None, ("state",)),
("Down Speed", self._format_speed, ("download_payload_rate",)),
("Up Speed", self._format_speed, ("upload_payload_rate",)),
("Progress", self._format_progress, ("progress",)),
("Down Speed", format_utils.format_speed, ("download_payload_rate",)),
("Up Speed", format_utils.format_speed, ("upload_payload_rate",)),
("Progress", format_utils.format_progress, ("progress",)),
("ETA", deluge.common.ftime, ("eta",)),
("Path", None, ("save_path",)),
("Downloaded",deluge.common.fsize,("all_time_download",)),
("Uploaded", deluge.common.fsize,("total_uploaded",)),
("Share Ratio", lambda x:x < 0 and "" or "%.3f"%x, ("ratio",)),
("Seeders",self._format_seeds_peers,("num_seeds","total_seeds")),
("Peers",self._format_seeds_peers,("num_peers","total_peers")),
("Seeders",format_utils.format_seeds_peers,("num_seeds","total_seeds")),
("Peers",format_utils.format_seeds_peers,("num_peers","total_peers")),
("Active Time",deluge.common.ftime,("active_time",)),
("Seeding Time",deluge.common.ftime,("seeding_time",)),
("Date Added",deluge.common.fdate,("time_added",)),
("Availability", lambda x:x < 0 and "" or "%.3f"%x, ("distributed_copies",)),
("Pieces", self._format_pieces, ("num_pieces","piece_length")),
("Pieces", format_utils.format_pieces, ("num_pieces","piece_length")),
]
self._status_keys = ["name","state","download_payload_rate","upload_payload_rate",
@ -203,6 +204,11 @@ class AllTorrents(BaseMode, component.Component):
"seeding_time","time_added","distributed_copies", "num_pieces",
"piece_length","save_path"]
def resume(self):
component.start(["AllTorrentsStateUpdater"])
self.refresh()
def _update_columns(self):
self.column_widths = [5,-1,15,13,10,10,10,15,15]
req = sum(filter(lambda x:x >= 0,self.column_widths))
@ -220,18 +226,6 @@ class AllTorrents(BaseMode, component.Component):
self.column_string = "{!header!}%s"%("".join(["%s%s"%(self.column_names[i]," "*(self.column_widths[i]-len(self.column_names[i]))) for i in range(0,len(self.column_names))]))
def _trim_string(self, string, w):
return "%s... "%(string[0:w-4])
def _format_column(self, col, lim):
size = len(col)
if (size >= lim - 1):
return self._trim_string(col,lim)
else:
return "%s%s"%(col," "*(lim-size))
def _format_row(self, row):
return "".join([self._format_column(row[i],self.column_widths[i]) for i in range(0,len(row))])
def set_state(self, state, refresh):
self.curstate = state # cache in case we change sort order
@ -239,16 +233,16 @@ class AllTorrents(BaseMode, component.Component):
self._sorted_ids = self._sort_torrents(self.curstate)
for torrent_id in self._sorted_ids:
ts = self.curstate[torrent_id]
newrows.append((self._format_row([self._format_queue(ts["queue"]),
ts["name"],
"%s"%deluge.common.fsize(ts["total_wanted"]),
ts["state"],
self._format_progress(ts["progress"]),
self._format_seeds_peers(ts["num_seeds"],ts["total_seeds"]),
self._format_seeds_peers(ts["num_peers"],ts["total_peers"]),
self._format_speed(ts["download_payload_rate"]),
self._format_speed(ts["upload_payload_rate"])
]),ts["state"]))
newrows.append((format_utils.format_row([self._format_queue(ts["queue"]),
ts["name"],
"%s"%deluge.common.fsize(ts["total_wanted"]),
ts["state"],
format_utils.format_progress(ts["progress"]),
format_utils.format_seeds_peers(ts["num_seeds"],ts["total_seeds"]),
format_utils.format_seeds_peers(ts["num_peers"],ts["total_peers"]),
format_utils.format_speed(ts["download_payload_rate"]),
format_utils.format_speed(ts["upload_payload_rate"])
],self.column_widths),ts["state"]))
self.numtorrents = len(state)
self.formatted_rows = newrows
if refresh:
@ -328,27 +322,12 @@ class AllTorrents(BaseMode, component.Component):
"sorts by queue #"
return sorted(state,cmp=self._queue_sort,key=lambda s:state.get(s)["queue"])
def _format_speed(self, speed):
if (speed > 0):
return deluge.common.fspeed(speed)
else:
return "-"
def _format_queue(self, qnum):
if (qnum >= 0):
return "%d"%(qnum+1)
else:
return ""
def _format_seeds_peers(self, num, total):
return "%d (%d)"%(num,total)
def _format_pieces(self, num, size):
return "%d (%s)"%(num,deluge.common.fsize(size))
def _format_progress(self, perc):
return "%.2f%%"%perc
def _action_error(self, error):
rerr = error.value
self.report_message("An Error Occurred","%s got error %s: %s"%(rerr.method,rerr.exception_type,rerr.exception_msg))
@ -475,6 +454,9 @@ class AllTorrents(BaseMode, component.Component):
self.messages.append((title,message))
def refresh(self,lines=None):
#log.error("ref")
#import traceback
#traceback.print_stack()
# Something has requested we scroll to the top of the list
if self._go_top:
self.cursel = 1
@ -491,12 +473,12 @@ class AllTorrents(BaseMode, component.Component):
# Update the status bars
if self._curr_filter == None:
self.add_string(0,self.topbar)
self.add_string(0,self.statusbars.topbar)
else:
self.add_string(0,"%s {!filterstatus!}Current filter: %s"%(self.topbar,self._curr_filter))
self.add_string(0,"%s {!filterstatus!}Current filter: %s"%(self.statusbars.topbar,self._curr_filter))
self.add_string(1,self.column_string)
hstr = "%sPress [h] for help"%(" "*(self.cols - len(self.bottombar) - 10))
self.add_string(self.rows - 1, "%s%s"%(self.bottombar,hstr))
hstr = "%sPress [h] for help"%(" "*(self.cols - len(self.statusbars.bottombar) - 10))
self.add_string(self.rows - 1, "%s%s"%(self.statusbars.bottombar,hstr))
# add all the torrents
if self.formatted_rows == []:
@ -621,6 +603,15 @@ class AllTorrents(BaseMode, component.Component):
elif c == curses.KEY_NPAGE:
self._scroll_down(int(self.rows/2))
elif c == curses.KEY_RIGHT:
# We enter a new mode for the selected torrent here
if not self.marked:
component.stop(["AllTorrentsStateUpdater"])
self.stdscr.clear()
td = TorrentDetail(self,self._current_torrent_id(),self.stdscr,self.encoding)
component.get("ConsoleUI").set_mode(td)
return
# Enter Key
elif c == curses.KEY_ENTER or c == 10:
self.marked.append(self.cursel)

View File

@ -43,6 +43,7 @@ try:
except ImportError:
pass
import deluge.component as component
import deluge.ui.console.colors as colors
try:
import signal
@ -98,8 +99,7 @@ class BaseMode(CursesStdIO):
self.stdscr.nodelay(1)
# Strings for the 2 status bars
self.topbar = ""
self.bottombar = ""
self.statusbars = component.get("StatusBars")
# Keep track of the screen size
self.rows, self.cols = self.stdscr.getmaxyx()
@ -182,6 +182,10 @@ class BaseMode(CursesStdIO):
screen.addstr(row, col, s, color)
col += len(s)
def draw_statusbars(self):
self.add_string(0, self.statusbars.topbar)
self.add_string(self.rows - 1, self.statusbars.bottombar)
def refresh(self):
"""
Refreshes the screen.
@ -189,10 +193,9 @@ class BaseMode(CursesStdIO):
attribute and the status bars.
"""
self.stdscr.clear()
self.draw_statusbars()
# Update the status bars
self.add_string(0, self.topbar)
self.add_string(self.rows - 1, self.bottombar)
self.add_string(1,"{!info!}Base Mode (or subclass hasn't overridden refresh)")
self.stdscr.redrawwin()

View File

@ -0,0 +1,70 @@
# format_utils.py
#
# Copyright (C) 2011 Nick Lanham <nick@afternight.org>
#
# Deluge is free software.
#
# You may redistribute it and/or modify it under the terms of the
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# exception, you may extend this exception to your version of the file(s),
# but you are not obligated to do so. If you do not wish to do so, delete
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
#
#
import deluge.common
def format_speed(speed):
if (speed > 0):
return deluge.common.fspeed(speed)
else:
return "-"
def format_seeds_peers(num, total):
return "%d (%d)"%(num,total)
def format_progress(perc):
return "%.2f%%"%perc
def format_pieces(num, size):
return "%d (%s)"%(num,deluge.common.fsize(size))
def format_priority(prio):
pstring = deluge.common.FILE_PRIORITY[prio]
if prio > 0:
return pstring[:pstring.index("Priority")-1]
else:
return pstring
def trim_string(string, w):
return "%s... "%(string[0:w-4])
def format_column(col, lim):
size = len(col)
if (size >= lim - 1):
return trim_string(col,lim)
else:
return "%s%s"%(col," "*(lim-size))
def format_row(row,column_widths):
return "".join([format_column(row[i],column_widths[i]) for i in range(0,len(row))])

View File

@ -0,0 +1,357 @@
# -*- coding: utf-8 -*-
#
# torrentdetail.py
#
# Copyright (C) 2011 Nick Lanham <nick@afternight.org>
#
# Deluge is free software.
#
# You may redistribute it and/or modify it under the terms of the
# GNU General Public License, as published by the Free Software
# Foundation; either version 3 of the License, or (at your option)
# any later version.
#
# deluge is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with deluge. If not, write to:
# The Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301, USA.
#
# In addition, as a special exception, the copyright holders give
# permission to link the code of portions of this program with the OpenSSL
# library.
# You must obey the GNU General Public License in all respects for all of
# the code used other than OpenSSL. If you modify file(s) with this
# exception, you may extend this exception to your version of the file(s),
# but you are not obligated to do so. If you do not wish to do so, delete
# this exception statement from your version. If you delete this exception
# statement from all source files in the program, then also delete it here.
#
#
import deluge.component as component
from basemode import BaseMode
import deluge.common
from deluge.ui.client import client
from sys import maxint
from deluge.ui.sessionproxy import SessionProxy
from popup import Popup,SelectablePopup,MessagePopup
from add_util import add_torrent
from input_popup import InputPopup
import format_utils
try:
import curses
except ImportError:
pass
import logging
log = logging.getLogger(__name__)
class TorrentDetail(BaseMode, component.Component):
def __init__(self, alltorrentmode, torrentid, stdscr, encoding=None):
self.alltorrentmode = alltorrentmode
self.torrentid = torrentid
self.torrent_state = None
self._status_keys = ["files", "name","state","download_payload_rate","upload_payload_rate",
"progress","eta","all_time_download","total_uploaded", "ratio",
"num_seeds","total_seeds","num_peers","total_peers", "active_time",
"seeding_time","time_added","distributed_copies", "num_pieces",
"piece_length","save_path","file_progress","file_priorities"]
self._info_fields = [
("Name",None,("name",)),
("State", None, ("state",)),
("Down Speed", format_utils.format_speed, ("download_payload_rate",)),
("Up Speed", format_utils.format_speed, ("upload_payload_rate",)),
("Progress", format_utils.format_progress, ("progress",)),
("ETA", deluge.common.ftime, ("eta",)),
("Path", None, ("save_path",)),
("Downloaded",deluge.common.fsize,("all_time_download",)),
("Uploaded", deluge.common.fsize,("total_uploaded",)),
("Share Ratio", lambda x:x < 0 and "" or "%.3f"%x, ("ratio",)),
("Seeders",format_utils.format_seeds_peers,("num_seeds","total_seeds")),
("Peers",format_utils.format_seeds_peers,("num_peers","total_peers")),
("Active Time",deluge.common.ftime,("active_time",)),
("Seeding Time",deluge.common.ftime,("seeding_time",)),
("Date Added",deluge.common.fdate,("time_added",)),
("Availability", lambda x:x < 0 and "" or "%.3f"%x, ("distributed_copies",)),
("Pieces", format_utils.format_pieces, ("num_pieces","piece_length")),
]
self.file_list = None
self.current_file = None
self.current_file_idx = 0
self.file_limit = maxint
self.file_off = 0
self.more_to_draw = False
self.column_string = ""
BaseMode.__init__(self, stdscr, encoding)
component.Component.__init__(self, "TorrentDetail", 1, depend=["SessionProxy"])
self.column_names = ["Filename", "Size", "Progress", "Priority"]
self._update_columns()
component.start(["TorrentDetail"])
curses.curs_set(0)
self.stdscr.notimeout(0)
# component start/update
def start(self):
component.get("SessionProxy").get_torrent_status(self.torrentid, self._status_keys).addCallback(self.set_state)
def update(self):
component.get("SessionProxy").get_torrent_status(self.torrentid, self._status_keys).addCallback(self.set_state)
def set_state(self, state):
log.debug("got state")
if not self.file_list:
# don't keep getting the files once we've got them once
self.file_list,self.file_dict = self.build_file_list(state["files"],state["file_progress"],state["file_priorities"])
self._status_keys.remove("files")
self._fill_progress(self.file_list,state["file_progress"])
for i,prio in enumerate(state["file_priorities"]):
self.file_dict[i][6] = format_utils.format_priority(prio)
del state["file_progress"]
del state["file_priorities"]
self.torrent_state = state
self.refresh()
# split file list into directory tree. this function assumes all files in a
# particular directory are returned together. it won't work otherwise.
# returned list is a list of lists of the form:
# [file/dir_name,index,size,children,expanded,progress,priority]
# for directories index will be -1, for files the value returned in the
# state object for use with other libtorrent calls (i.e. setting prio)
#
# Also returns a dictionary that maps index values to the file leaves
# for fast updating of progress and priorities
def build_file_list(self, file_tuples,prog,prio):
ret = []
retdict = {}
for f in file_tuples:
cur = ret
ps = f["path"].split("/")
fin = ps[-1]
for p in ps:
if not cur or p != cur[-1][0]:
cl = []
if p == fin:
ent = [p,f["index"],f["size"],cl,False,
format_utils.format_progress(prog[f["index"]]*100),
format_utils.format_priority(prio[f["index"]])]
retdict[f["index"]] = ent
else:
ent = [p,-1,-1,cl,False,"-","-"]
cur.append(ent)
cur = cl
else:
cur = cur[-1][3]
self._build_sizes(ret)
self._fill_progress(ret,prog)
return (ret,retdict)
# fill in the sizes of the directory entries based on their children
def _build_sizes(self, fs):
ret = 0
for f in fs:
if f[2] == -1:
val = self._build_sizes(f[3])
ret += val
f[2] = val
else:
ret += f[2]
return ret
# fills in progress fields in all entries based on progs
# returns the # of bytes complete in all the children of fs
def _fill_progress(self,fs,progs):
tb = 0
for f in fs:
if f[3]: # dir, has some children
bd = self._fill_progress(f[3],progs)
f[5] = format_utils.format_progress((bd/f[2])*100)
else: # file, update own prog and add to total
bd = f[2]*progs[f[1]]
f[5] = format_utils.format_progress(progs[f[1]]*100)
tb += bd
return tb
def _update_columns(self):
self.column_widths = [-1,15,15,20]
req = sum(filter(lambda x:x >= 0,self.column_widths))
if (req > self.cols): # can't satisfy requests, just spread out evenly
cw = int(self.cols/len(self.column_names))
for i in range(0,len(self.column_widths)):
self.column_widths[i] = cw
else:
rem = self.cols - req
var_cols = len(filter(lambda x: x < 0,self.column_widths))
vw = int(rem/var_cols)
for i in range(0, len(self.column_widths)):
if (self.column_widths[i] < 0):
self.column_widths[i] = vw
self.column_string = "{!header!}%s"%("".join(["%s%s"%(self.column_names[i]," "*(self.column_widths[i]-len(self.column_names[i]))) for i in range(0,len(self.column_names))]))
def draw_files(self,files,depth,off,idx):
for fl in files:
# kick out if we're going to draw too low on the screen
if (off >= self.rows-1):
self.more_to_draw = True
return -1,-1
self.file_limit = idx
if idx >= self.file_off:
# set fg/bg colors based on if we are selected or not
if idx == self.current_file_idx:
self.current_file = fl
fc = "{!black,white!}"
else:
fc = "{!white,black!}"
#actually draw the dir/file string
if fl[3] and fl[4]: # this is an expanded directory
xchar = 'v'
elif fl[3]: # collapsed directory
xchar = '>'
else: # file
xchar = '-'
r = format_utils.format_row(["%s%s %s"%(" "*depth,xchar,fl[0]),
deluge.common.fsize(fl[2]),fl[5],fl[6]],
self.column_widths)
self.add_string(off,"%s%s"%(fc,r),trim=False)
off += 1
if fl[3] and fl[4]:
# recurse if we have children and are expanded
off,idx = self.draw_files(fl[3],depth+1,off,idx+1)
if off < 0: return (off,idx)
else:
idx += 1
return (off,idx)
def refresh(self,lines=None):
# Update the status bars
self.stdscr.clear()
self.add_string(0,self.statusbars.topbar)
hstr = "%sPress [h] for help"%(" "*(self.cols - len(self.statusbars.bottombar) - 10))
self.add_string(self.rows - 1, "%s%s"%(self.statusbars.bottombar,hstr))
self.stdscr.hline((self.rows/2)-1,0,"_",self.cols)
off = 1
if self.torrent_state:
for f in self._info_fields:
if off >= (self.rows/2): break
if f[1] != None:
args = []
try:
for key in f[2]:
args.append(self.torrent_state[key])
except:
log.debug("Could not get info field: %s",e)
continue
info = f[1](*args)
else:
info = self.torrent_state[f[2][0]]
self.add_string(off,"{!info!}%s: {!input!}%s"%(f[0],info))
off += 1
else:
self.add_string(1, "Waiting for torrent state")
off = self.rows/2
self.add_string(off,self.column_string)
if self.file_list:
off += 1
self.more_to_draw = False
self.draw_files(self.file_list,0,off,0)
#self.stdscr.redrawwin()
self.stdscr.noutrefresh()
curses.doupdate()
# expand or collapse the current file
def expcol_cur_file(self):
self.current_file[4] = not self.current_file[4]
self.refresh()
def file_list_down(self):
if (self.current_file_idx + 1) > self.file_limit:
if self.more_to_draw:
self.current_file_idx += 1
self.file_off += 1
else:
return
else:
self.current_file_idx += 1
self.refresh()
def file_list_up(self):
self.current_file_idx = max(0,self.current_file_idx-1)
self.file_off = min(self.file_off,self.current_file_idx)
self.refresh()
def back_to_overview(self):
component.stop(["TorrentDetail"])
component.deregister("TorrentDetail")
self.stdscr.clear()
component.get("ConsoleUI").set_mode(self.alltorrentmode)
self.alltorrentmode.resume()
def _doRead(self):
c = self.stdscr.getch()
if c > 31 and c < 256:
if chr(c) == 'Q':
from twisted.internet import reactor
if client.connected():
def on_disconnect(result):
reactor.stop()
client.disconnect().addCallback(on_disconnect)
else:
reactor.stop()
return
elif chr(c) == 'q':
self.back_to_overview()
return
if c == 27:
self.back_to_overview()
return
# Navigate the torrent list
if c == curses.KEY_UP:
self.file_list_up()
elif c == curses.KEY_PPAGE:
pass
elif c == curses.KEY_DOWN:
self.file_list_down()
elif c == curses.KEY_NPAGE:
pass
# Enter Key
elif c == curses.KEY_ENTER or c == 10:
pass
# space
elif c == 32:
self.expcol_cur_file()
self.refresh()

View File

@ -41,7 +41,6 @@ class StatusBars(component.Component):
def __init__(self):
component.Component.__init__(self, "StatusBars", 2, depend=["CoreConfig"])
self.config = component.get("CoreConfig")
self.screen = component.get("ConsoleUI").screen
# Hold some values we get from the core
self.connections = 0
@ -49,6 +48,10 @@ class StatusBars(component.Component):
self.upload = ""
self.dht = 0
# Default values
self.topbar = "{!status!}Deluge %s Console - " % deluge.common.get_version()
self.bottombar = "{!status!}C: %s" % self.connections
def start(self):
self.update()
@ -77,30 +80,28 @@ class StatusBars(component.Component):
def update_statusbars(self):
# Update the topbar string
self.screen.topbar = "{!status!}Deluge %s Console - " % deluge.common.get_version()
self.topbar = "{!status!}Deluge %s Console - " % deluge.common.get_version()
if client.connected():
info = client.connection_info()
self.screen.topbar += "%s@%s:%s" % (info[2], info[0], info[1])
self.topbar += "%s@%s:%s" % (info[2], info[0], info[1])
else:
self.screen.topbar += "Not Connected"
self.topbar += "Not Connected"
# Update the bottombar string
self.screen.bottombar = "{!status!}C: %s" % self.connections
self.bottombar = "{!status!}C: %s" % self.connections
if self.config["max_connections_global"] > -1:
self.screen.bottombar += " (%s)" % self.config["max_connections_global"]
self.bottombar += " (%s)" % self.config["max_connections_global"]
self.screen.bottombar += " D: %s/s" % self.download
self.bottombar += " D: %s/s" % self.download
if self.config["max_download_speed"] > -1:
self.screen.bottombar += " (%s KiB/s)" % self.config["max_download_speed"]
self.bottombar += " (%s KiB/s)" % self.config["max_download_speed"]
self.screen.bottombar += " U: %s/s" % self.upload
self.bottombar += " U: %s/s" % self.upload
if self.config["max_upload_speed"] > -1:
self.screen.bottombar += " (%s KiB/s)" % self.config["max_upload_speed"]
self.bottombar += " (%s KiB/s)" % self.config["max_upload_speed"]
if self.config["dht"]:
self.screen.bottombar += " DHT: %s" % self.dht
self.screen.refresh()
self.bottombar += " DHT: %s" % self.dht