Example #1
0
    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)
Example #2
0
    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()
Example #3
0
    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)
Example #4
0
    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()