def show_info(self, torrent_id, status, verbose=False): """ Writes out the torrents information to the screen. :param torrent_id: str, the torrent_id :param status: dict, the torrents status, this should have the same keys as status_keys :param verbose: bool, if true, we print out more information about the the torrent """ self.console.set_batch_write(True) self.console.write(" ") self.console.write("{!info!}Name: {!input!}%s" % (status["name"])) self.console.write("{!info!}ID: {!input!}%s" % (torrent_id)) s = "{!info!}State: %s%s" % (colors.state_color[status["state"]], status["state"]) # Only show speed if active if status["state"] in ("Seeding", "Downloading"): if status["state"] != "Seeding": s += " {!info!}Down Speed: {!input!}%s" % common.fspeed( status["download_payload_rate"]) s += " {!info!}Up Speed: {!input!}%s" % common.fspeed( status["upload_payload_rate"]) if common.ftime(status["eta"]): s += " {!info!}ETA: {!input!}%s" % common.ftime(status["eta"]) self.console.write(s) if status["state"] in ("Seeding", "Downloading", "Queued"): s = "{!info!}Seeds: {!input!}%s (%s)" % (status["num_seeds"], status["total_seeds"]) s += " {!info!}Peers: {!input!}%s (%s)" % (status["num_peers"], status["total_peers"]) s += " {!info!}Availability: {!input!}%.2f" % status[ "distributed_copies"] self.console.write(s) s = "{!info!}Size: {!input!}%s/%s" % (common.fsize( status["total_done"]), common.fsize(status["total_size"])) s += " {!info!}Ratio: {!input!}%.3f" % status["ratio"] self.console.write(s) s = "{!info!}Seed time: {!input!}%s" % format_time( status["seeding_time"]) s += " {!info!}Active: {!input!}%s" % format_time( status["active_time"]) self.console.write(s) self.console.write("{!info!}Tracker status: {!input!}%s" % status["tracker_status"]) if not status["is_finished"]: if hasattr(self.console, "screen"): cols = self.console.screen.cols else: cols = 80 pbar = format_progressbar( status["progress"], cols - (13 + len("%.2f%%" % status["progress"]))) s = "{!info!}Progress: {!input!}%.2f%% %s" % (status["progress"], pbar) self.console.write(s) if verbose: self.console.write(" {!info!}::Files") for i, f in enumerate(status["files"]): s = " {!input!}%s (%s)" % (f["path"], common.fsize( f["size"])) s += " {!info!}Progress: {!input!}%.2f%%" % ( status["file_progress"][i] * 100) s += " {!info!}Priority:" fp = common.FILE_PRIORITY[status["file_priorities"] [i]].replace("Priority", "") if fp == "Do Not Download": s += "{!error!}" else: s += "{!success!}" s += " %s" % (fp) # Check if this is too long for the screen and reduce the path # if necessary if hasattr(self.console, "screen"): cols = self.console.screen.cols slen = colors.get_line_length(s, self.console.screen.encoding) if slen > cols: s = s.replace(f["path"], f["path"][slen - cols + 1:]) self.console.write(s) self.console.write(" {!info!}::Peers") if len(status["peers"]) == 0: self.console.write(" None") else: s = "" for peer in status["peers"]: if peer["seed"]: s += "%sSeed\t{!input!}" % colors.state_color["Seeding"] else: s += "%sPeer\t{!input!}" % colors.state_color[ "Downloading"] s += peer["country"] + "\t" if peer["ip"].count(":") == 1: # IPv4 s += peer["ip"] else: # IPv6 s += "[%s]:%s" % (":".join(peer["ip"].split(":")[:-1]), peer["ip"].split(":")[-1]) c = peer["client"] s += "\t" + c if len(c) < 16: s += "\t\t" else: s += "\t" s += "%s%s\t%s%s" % (colors.state_color["Seeding"], common.fspeed(peer["up_speed"]), colors.state_color["Downloading"], common.fspeed(peer["down_speed"])) s += "\n" self.console.write(s[:-1]) self.console.set_batch_write(False)
def add_line(self, text, refresh=True): """ Add a line to the screen. This will be showed between the two bars. The text can be formatted with color using the following format: "{!fg, bg, attributes, ...!}" See: http://docs.python.org/library/curses.html#constants for attributes. Alternatively, it can use some built-in scheme for coloring. See colors.py for built-in schemes. "{!scheme!}" Examples: "{!blue, black, bold!}My Text is {!white, black!}cool" "{!info!}I am some info text!" "{!error!}Uh oh!" :param text: the text to show :type text: string :param refresh: if True, the screen will refresh after the line is added :type refresh: bool """ def get_line_chunks(line): """ Returns a list of 2-tuples (color string, text) """ chunks = [] num_chunks = line.count("{!") for i in range(num_chunks): # Find the beginning and end of the color tag beg = line.find("{!") end = line.find("!}") + 2 color = line[beg:end] line = line[end:] # Check to see if this is the last chunk if i + 1 == num_chunks: text = line else: # Not the last chunk so get the text up to the next tag # and remove the text from line text = line[:line.find("{!")] line = line[line.find("{!"):] chunks.append((color, text)) return chunks for line in text.splitlines(): # We need to check for line lengths here and split as necessary try: line_length = colors.get_line_length(line) except colors.BadColorString: log.error("Passed a bad colored string..") line_length = len(line) if line_length >= (self.cols - 1): s = "" # The length of the text without the color tags s_len = 0 # We need to split this over multiple lines for chunk in get_line_chunks(line): if (len(chunk[1]) + s_len) < (self.cols - 1): # This chunk plus the current string in 's' isn't over # the maximum width, so just append the color tag and text s += chunk[0] + chunk[1] s_len += len(chunk[1]) else: # The chunk plus the current string in 's' is too long. # We need to take as much of the chunk and put it into 's' # with the color tag. remain = (self.cols - 1) - s_len s += chunk[0] + chunk[1][:remain] # We append the line since it's full self.lines.append(s) # Start a new 's' with the remainder chunk s = chunk[0] + chunk[1][remain:] s_len = len(chunk[1][remain:]) # Append the final string which may or may not be the full width if s: self.lines.append(s) else: self.lines.append(line) while len(self.lines) > LINES_BUFFER_SIZE: # Remove the oldest line if the max buffer size has been reached del self.lines[0] if refresh: self.refresh()
def show_info(self, torrent_id, status, verbose=False): """ Writes out the torrents information to the screen. :param torrent_id: str, the torrent_id :param status: dict, the torrents status, this should have the same keys as status_keys :param verbose: bool, if true, we print out more information about the the torrent """ self.console.set_batch_write(True) self.console.write(" ") self.console.write("{!info!}Name: {!input!}%s" % (status["name"])) self.console.write("{!info!}ID: {!input!}%s" % (torrent_id)) s = "{!info!}State: %s%s" % (colors.state_color[status["state"]], status["state"]) # Only show speed if active if status["state"] in ("Seeding", "Downloading"): if status["state"] != "Seeding": s += " {!info!}Down Speed: {!input!}%s" % common.fspeed(status["download_payload_rate"]) s += " {!info!}Up Speed: {!input!}%s" % common.fspeed(status["upload_payload_rate"]) if common.ftime(status["eta"]): s += " {!info!}ETA: {!input!}%s" % common.ftime(status["eta"]) self.console.write(s) if status["state"] in ("Seeding", "Downloading", "Queued"): s = "{!info!}Seeds: {!input!}%s (%s)" % (status["num_seeds"], status["total_seeds"]) s += " {!info!}Peers: {!input!}%s (%s)" % (status["num_peers"], status["total_peers"]) s += " {!info!}Availibility: {!input!}%.2f" % status["distributed_copies"] self.console.write(s) s = "{!info!}Size: {!input!}%s/%s" % (common.fsize(status["total_done"]), common.fsize(status["total_size"])) s += " {!info!}Ratio: {!input!}%.3f" % status["ratio"] self.console.write(s) if not status["is_finished"]: if hasattr(self.console, "screen"): cols = self.console.screen.cols else: cols = 80 pbar = format_progressbar(status["progress"], cols - (13 + len("%.2f%%" % status["progress"]))) s = "{!info!}Progress: {!input!}%.2f%% %s" % (status["progress"], pbar) self.console.write(s) if verbose: self.console.write(" {!info!}::Files") for i, f in enumerate(status["files"]): s = " {!input!}%s (%s)" % (f["path"], common.fsize(f["size"])) s += " {!info!}Progress: {!input!}%.2f%%" % (status["file_progress"][i] * 100) s += " {!info!}Priority:" fp = common.FILE_PRIORITY[status["file_priorities"][i]].replace("Priority", "") if fp == "Do Not Download": s += "{!error!}" else: s += "{!success!}" s += " %s" % (fp) # Check if this is too long for the screen and reduce the path # if necessary if hasattr(self.console, "screen"): cols = self.console.screen.cols slen = colors.get_line_length(s, self.console.screen.encoding) if slen > cols: s = s.replace(f["path"], f["path"][slen - cols + 1:]) self.console.write(s) self.console.write(" {!info!}::Peers") if len(status["peers"]) == 0: self.console.write(" None") else: s = "" for peer in status["peers"]: if peer["seed"]: s += "%sSeed\t{!input!}" % colors.state_color["Seeding"] else: s += "%sPeer\t{!input!}" % colors.state_color["Downloading"] s += peer["country"] + "\t" s += peer["ip"] c = peer["client"] s += "\t" + c if len(c) < 16: s += "\t\t" else: s += "\t" s += "%s%s\t%s%s" % ( colors.state_color["Seeding"], common.fspeed(peer["up_speed"]), colors.state_color["Downloading"], common.fspeed(peer["down_speed"])) s += "\n" self.console.write(s[:-1]) self.console.set_batch_write(False)
def add_line(self, text, refresh=True): """ Add a line to the screen. This will be showed between the two bars. The text can be formatted with color using the following format: "{!fg, bg, attributes, ...!}" See: http://docs.python.org/library/curses.html#constants for attributes. Alternatively, it can use some built-in scheme for coloring. See colors.py for built-in schemes. "{!scheme!}" Examples: "{!blue, black, bold!}My Text is {!white, black!}cool" "{!info!}I am some info text!" "{!error!}Uh oh!" :param text: the text to show :type text: string :param refresh: if True, the screen will refresh after the line is added :type refresh: bool """ def get_line_chunks(line): """ Returns a list of 2-tuples (color string, text) """ chunks = [] num_chunks = line.count("{!") for i in range(num_chunks): # Find the beginning and end of the color tag beg = line.find("{!") end = line.find("!}") + 2 color = line[beg:end] line = line[end:] # Check to see if this is the last chunk if i + 1 == num_chunks: text = line else: # Not the last chunk so get the text up to the next tag # and remove the text from line text = line[: line.find("{!")] line = line[line.find("{!") :] chunks.append((color, text)) return chunks for line in text.splitlines(): # We need to check for line lengths here and split as necessary try: line_length = colors.get_line_length(line) except colors.BadColorString: log.error("Passed a bad colored string..") line_length = len(line) if line_length >= (self.cols - 1): s = "" # The length of the text without the color tags s_len = 0 # We need to split this over multiple lines for chunk in get_line_chunks(line): if (len(chunk[1]) + s_len) < (self.cols - 1): # This chunk plus the current string in 's' isn't over # the maximum width, so just append the color tag and text s += chunk[0] + chunk[1] s_len += len(chunk[1]) else: # The chunk plus the current string in 's' is too long. # We need to take as much of the chunk and put it into 's' # with the color tag. remain = (self.cols - 1) - s_len s += chunk[0] + chunk[1][:remain] # We append the line since it's full self.lines.append(s) # Start a new 's' with the remainder chunk s = chunk[0] + chunk[1][remain:] s_len = len(chunk[1][remain:]) # Append the final string which may or may not be the full width if s: self.lines.append(s) else: self.lines.append(line) while len(self.lines) > LINES_BUFFER_SIZE: # Remove the oldest line if the max buffer size has been reached del self.lines[0] if refresh: self.refresh()