diff --git a/README.rst b/README.rst index b0e09bb..ffa1340 100644 --- a/README.rst +++ b/README.rst @@ -429,7 +429,7 @@ Settings: :alert_format_title: The title of the notification, all formatters can be used (default: ``Low battery``) :alert_format_body: The body text of the notification, all formatters can be used (default: ``Battery {battery_ident} has only {percentage:.2f}% ({remaining:%E%hh:%Mm}) remaining!``) :path: Override the default-generated path (default: ``None``) -:status: A dictionary mapping ('DIS', 'CHR', 'FULL') to alternative names (default: ``{'DIS': 'DIS', 'FULL': 'FULL', 'CHR': 'CHR'}``) +:status: A dictionary mapping ('DIS', 'CHR', 'FULL') to alternative names (default: ``{'CHR': 'CHR', 'FULL': 'FULL', 'DIS': 'DIS'}``) :color: The text color (default: ``#ffffff``) :full_color: The full color (default: ``#00ff00``) :charging_color: The charging color (default: ``#00ff00``) @@ -501,18 +501,23 @@ cpu_usage Shows CPU usage. -The first output will be inacurate +The first output will be inacurate. + Linux only Available formatters: -* {usage} +* {usage} usage average of all cores +* {usage_cpu*} usage of one specific core. replace "*" by core number starting at 0 +* {usage_all} usage of all cores separate. usess natsort when available(relevant for more than 10 cores) Settings: -:format: format string (default: ``{usage:02}%``) +:format: format string. (default: ``{usage:02}%``) +:format_all: format string used for {usage_all} per core. Available formaters are {core} and {usage}. (default: ``{core}:{usage:02}%``) +:exclude_average: If True usage average of all cores will not be in format_all. (default: ``False``) :interval: (default: ``5``) @@ -522,12 +527,15 @@ cpu_usage_bar Shows CPU usage as a bar (made with unicode box characters). -The first output will be inacurate +The first output will be inacurate. + Linux only Available formatters: -* {usage_bar} +* {usage_bar} usage average of all cores +* {usage_bar_cpu*} usage of one specific core. replace "*" +by core number starting at 0 @@ -810,7 +818,7 @@ Settings: :host: (default: ``localhost``) :port: MPD port (default: ``6600``) :format: formatp string (default: ``{title} {status}``) -:status: Dictionary mapping pause, play and stop to output (default: ``{'pause': '▷', 'stop': '◾', 'play': '▶'}``) +:status: Dictionary mapping pause, play and stop to output (default: ``{'play': '▶', 'pause': '▷', 'stop': '◾'}``) :color: The color of the text (default: ``#FFFFFF``) :interval: (default: ``1``) @@ -852,6 +860,19 @@ Settings: +ngb ++++ + + + +Settings: + +:username: (required) +:password: (required) +:interval: (default: ``5``) + + + now_playing +++++++++++ @@ -877,7 +898,7 @@ Requires python-dbus available from every distros' package manager. Settings: :player: Player name (default: ``None``) -:status: Dictionary mapping pause, play and stop to output text (default: ``{'pause': '▷', 'stop': '◾', 'play': '▶'}``) +:status: Dictionary mapping pause, play and stop to output text (default: ``{'play': '▶', 'pause': '▷', 'stop': '◾'}``) :color: Text color (default: ``#FFFFFF``) :format: formatp string (default: ``{title} {status}``) :interval: (default: ``1``) diff --git a/i3pystatus/cpu_usage.py b/i3pystatus/cpu_usage.py index 96246cd..a1f8e82 100644 --- a/i3pystatus/cpu_usage.py +++ b/i3pystatus/cpu_usage.py @@ -1,58 +1,120 @@ # -*- coding:utf-8 -*- +from collections import defaultdict +from string import Formatter + from i3pystatus import IntervalModule +try: + from natsort import natsorted as sorted +except ImportError: + pass + class CpuUsage(IntervalModule): """ Shows CPU usage. - The first output will be inacurate + The first output will be inacurate. + Linux only Available formatters: - * {usage} + * {usage} usage average of all cores + * {usage_cpu*} usage of one specific core. replace "*" by core number starting at 0 + * {usage_all} usage of all cores separate. usess natsort when available(relevant for more than 10 cores) """ format = "{usage:02}%" + format_all = "{core}:{usage:02}%" + exclude_average = False settings = ( - ("format", "format string"), + ("format", "format string."), + ("format_all", ("format string used for {usage_all} per core. " + "Available formaters are {core} and {usage}. ")), + ("exclude_average", ("If True usage average of all cores will " + "not be in format_all.")) ) def init(self): - self.prev_idle = 0 - self.prev_busy = 0 + self.prev_total = defaultdict(int) + self.prev_busy = defaultdict(int) self.interval = 1 + self.formatter = Formatter() + + def get_cpu_timings(self): + """ + reads and parses /proc/stat + returns dictionary with all available cores including global average + """ + timings = {} + with open('/proc/stat', 'r') as file_obj: + for line in file_obj: + if 'cpu' in line: + line = line.strip().split() + timings[line[0]] = [int(x) for x in line[1:]] + + return timings + + def calculate_usage(self, cpu, total, busy): + """ + calculates usage + """ + diff_total = total - self.prev_total[cpu] + diff_busy = busy - self.prev_busy[cpu] + + self.prev_total[cpu] = total + self.prev_busy[cpu] = busy + + return int(diff_busy / diff_total * 100) + + def gen_format_all(self, usage): + """ + generates string for format all + """ + format_string = " " + core_strings = [] + for core, usage in usage.items(): + if core == 'usage_cpu' and self.exclude_average: + continue + elif core == 'usage': + continue + + core = core.replace('usage_', '') + string = self.formatter.format(format_string=self.format_all, + core=core, + usage=usage) + core_strings.append(string) + + core_strings = sorted(core_strings) + + return format_string.join(core_strings) def get_usage(self): """ parses /proc/stat and calcualtes total and busy time (more specific USER_HZ see man 5 proc for further informations ) """ - with open('/proc/stat', 'r') as file_obj: - stats = file_obj.readline().strip().split() + usage = {} - cpu_timings = [int(x) for x in stats[1:]] - cpu_total = sum(cpu_timings) - del cpu_timings[3:5] - cpu_busy = sum(cpu_timings) + for cpu, timings in self.get_cpu_timings().items(): + cpu_total = sum(timings) + del timings[3:5] + cpu_busy = sum(timings) + cpu_usage = self.calculate_usage(cpu, cpu_total, cpu_busy) - return cpu_total, cpu_busy + usage['usage_' + cpu] = cpu_usage + + return usage def run(self): - cpu_total, cpu_busy = self.get_usage() + usage = self.get_usage() + usage['format_all'] = self.gen_format_all(usage) - diff_cpu_total = cpu_total - self.prev_idle - diff_cpu_busy = cpu_busy - self.prev_busy - - self.prev_idle = cpu_total - self.prev_busy = cpu_busy - - cpu_busy_percentage = int(diff_cpu_busy / diff_cpu_total * 100) + # for backward compatibility + usage['usage'] = usage['usage_cpu'] self.output = { - "full_text": self.format.format( - usage=cpu_busy_percentage - ) + "full_text": self.format.format_map(usage) } diff --git a/i3pystatus/cpu_usage_bar.py b/i3pystatus/cpu_usage_bar.py index c40fe22..2c3b037 100644 --- a/i3pystatus/cpu_usage_bar.py +++ b/i3pystatus/cpu_usage_bar.py @@ -1,17 +1,20 @@ # -*- coding:utf-8 -*- -from i3pystatus import IntervalModule +from i3pystatus.cpu_usage import CpuUsage from i3pystatus.core.util import make_bar -class CpuUsageBar(IntervalModule): +class CpuUsageBar(CpuUsage): """ Shows CPU usage as a bar (made with unicode box characters). - The first output will be inacurate + The first output will be inacurate. + Linux only Available formatters: - * {usage_bar} + * {usage_bar} usage average of all cores + * {usage_bar_cpu*} usage of one specific core. replace "*" + by core number starting at 0 """ @@ -20,41 +23,21 @@ class CpuUsageBar(IntervalModule): ("format", "format string"), ) - def init(self): - self.prev_idle = 0 - self.prev_busy = 0 - self.interval = 1 - - def get_usage(self): - """ - parses /proc/stat and calcualtes total and busy time - (more specific USER_HZ see man 5 proc for further informations ) - """ - with open('/proc/stat', 'r') as file_obj: - stats = file_obj.readline().strip().split() - - cpu_timings = [int(x) for x in stats[1:]] - cpu_total = sum(cpu_timings) - del cpu_timings[3:5] - cpu_busy = sum(cpu_timings) - - return cpu_total, cpu_busy - def run(self): - cpu_total, cpu_busy = self.get_usage() + cpu_usage = self.get_usage() - diff_cpu_total = cpu_total - self.prev_idle - diff_cpu_busy = cpu_busy - self.prev_busy + cpu_usage_bar = {} - self.prev_idle = cpu_total - self.prev_busy = cpu_busy + for core, usage in cpu_usage.items(): + core = core.replace('usage', 'usage_bar') + cpu_usage_bar[core] = make_bar(usage) - cpu_busy_percentage = diff_cpu_busy / diff_cpu_total * 100 - cpu_busy_bar = make_bar(cpu_busy_percentage) + cpu_usage.update(cpu_usage_bar) + + # for backward compatibility + cpu_usage['usage_bar'] = cpu_usage['usage_bar_cpu'] self.output = { - "full_text": self.format.format( - usage_bar=cpu_busy_bar - ) + "full_text": self.format.format_map(cpu_usage) }