コード例 #1
0
ファイル: s_tui.py プロジェクト: dvejmz/s-tui
    def main_window(self):

        user_config_path = None
        if not user_config_dir_exists():
            user_config_path = make_user_config_dir()
        else:
            user_config_path = get_user_config_path()

        script_hooks_enabled = True
        if user_config_path is None:
            logging.warn('Failed to find or create scripts directory, proceeding without scripting support')
            script_hooks_enabled = False
        else:
            self.script_loader = ScriptHookLoader(user_config_path)

        # initiating the graphs
        self.graphs = OrderedDict()
        self.summaries = OrderedDict()

        # TODO: Update to find sensors automatically


        freq_source = FreqSource(is_admin)
        self.graphs[freq_source.get_source_name()] = StuiBarGraph(freq_source, 'freq light', 'freq dark', 'freq light smooth', 'freq dark smooth')
        self.summaries[freq_source.get_source_name()] = SummaryTextList(freq_source)

        util_source = UtilSource()
        self.graphs[util_source.get_source_name()] = StuiBarGraph(util_source, 'util light', 'util dark', 'util light smooth', 'util dark smooth')
        self.summaries[util_source.get_source_name()] = SummaryTextList(util_source)

        temp_source = TemperatureSource(self.custom_temp)

        if script_hooks_enabled:
            temp_source.add_edge_hook(self.script_loader.load_script(temp_source.__class__.__name__, 30000)) # Invoke threshold script every 30s while threshold is exceeded.

        alert_colors = ['high temp light', 'high temp dark', 'high temp light smooth', 'high temp dark smooth']
        self.graphs[temp_source.get_source_name()] = StuiBarGraph(temp_source, 'temp light', 'temp dark', 'temp light smooth', 'temp dark smooth', alert_colors=alert_colors)
        self.summaries[temp_source.get_source_name()] = SummaryTextList(temp_source, 'high temp txt')

        rapl_power_source = RaplPowerSource()
        self.graphs[rapl_power_source.get_source_name()] = StuiBarGraph(rapl_power_source, 'power dark', 'power light', 'power dark smooth', 'power light smooth')
        self.summaries[rapl_power_source.get_source_name()] = SummaryTextList(rapl_power_source)

        fan_source = FanSource(self.custom_fan)
        self.summaries[fan_source.get_source_name()] = SummaryTextList(fan_source)

        # only interested in available graph
        self.available_graphs = OrderedDict((key, val) for key, val in self.graphs.items() if val.get_is_available())
        self.available_summaries = OrderedDict((key, val) for key, val in self.summaries.items() if val.get_is_available())

        self.visible_graphs = self.available_graphs.copy()
        self.show_graphs()

        cpu_stats = self.cpu_stats()
        graph_controls = self.graph_controls()
        graph_stats = self.graph_stats()

        text_col = ViListBox(urwid.SimpleListWalker(cpu_stats + graph_controls + [urwid.Divider()] + graph_stats))

        vline = urwid.AttrWrap(urwid.SolidFill(u'\u2502'), 'line')
        w = urwid.Columns([
                           ('fixed',  20, text_col),
                           ('fixed',  1, vline),
                           ('weight', 2, self.graph_place_holder),
                           ],
                          dividechars=1, focus_column=0)

        w = urwid.Padding(w, ('fixed left', 1), ('fixed right', 0))
        w = urwid.AttrWrap(w, 'body')
        w = urwid.LineBox(w)
        w = urwid.AttrWrap(w, 'line')
        self.main_window_w = w
        return self.main_window_w
コード例 #2
0
ファイル: s_tui.py プロジェクト: giltsuker/s-tui
    def __init__(self, args):

        # Load and configure user config dir when controller starts
        if not user_config_dir_exists():
            user_config_dir = make_user_config_dir()
        else:
            user_config_dir = get_user_config_dir()

        self.script_hooks_enabled = True
        if user_config_dir is None:
            logging.warning("Failed to find or create scripts directory,\
                             proceeding without scripting support")
            self.script_hooks_enabled = False
        else:
            self.script_loader = ScriptHookLoader(user_config_dir)

        # Use user config file if one was saved before
        self.conf = None
        if user_config_file_exists():
            self.conf = configparser.ConfigParser()
            self.conf.read(get_user_config_file())
        else:
            logging.debug("Config file not found")

        # Set refresh rate accorrding to user config
        self.refresh_rate = '2.0'
        try:
            self.refresh_rate = str(self.conf.getfloat(
                'GraphControll', 'refresh'))
            logging.debug("User refresh rate: " + str(self.refresh_rate))
        except (AttributeError, ValueError, configparser.NoOptionError,
                configparser.NoSectionError):
            logging.debug("No refresh rate configed")

        # Set initial smooth graph state according to user config
        self.smooth_graph_mode = False
        try:
            if self.conf.getboolean('GraphControll', 'UTF8'):
                self.smooth_graph_mode = True
            else:
                logging.debug("UTF8 selected as " +
                              self.conf.get('GraphControll', 'UTF8'))
        except (AttributeError, ValueError, configparser.NoOptionError,
                configparser.NoSectionError):
            logging.debug("No user config for utf8")

        self.temp_thresh = args.t_thresh

        # Try to load high temperature threshold if configured
        if args.t_thresh is None:
            try:
                self.temp_thresh = self.conf.get('TempControll', 'threshold')
                logging.debug("Temperature threshold set to " +
                              str(self.temp_thresh))
            except (AttributeError, ValueError, configparser.NoOptionError,
                    configparser.NoSectionError):
                logging.debug("No user config for temp threshold")

        # Needed for use in view
        self.args = args

        self.animate_alarm = None
        self.terminal = args.terminal
        self.json = args.json
        self.mode = GraphMode()

        self.handle_mouse = not args.no_mouse

        self.stress_start_time = 0
        self.stress_time = 0

        self.view = GraphView(self)
        # use the first mode (no stress) as the default
        mode = self.get_modes()[0]
        self.mode.set_mode(mode)
        # update the view
        self.view.on_mode_change(mode)
        self.view.update_displayed_information()

        # Update csv file to save
        self.csv_file = None
        self.save_csv = args.csv
        if args.csv_file is not None:
            self.csv_file = args.csv_file
            logging.info("Printing output to csv " + self.csv_file)
        elif args.csv_file is None and args.csv:
            self.csv_file = DEFAULT_CSV_FILE
コード例 #3
0
ファイル: s_tui.py プロジェクト: dvejmz/s-tui
class GraphView(urwid.WidgetPlaceholder):
    """
    A class responsible for providing the application's interface and
    graph display.
    """
    def __init__(self, controller, args):

        self.controller = controller
        self.custom_temp = args.custom_temp
        self.custom_fan = args.custom_fan
        self.args = args
        self.hline = urwid.AttrWrap(urwid.SolidFill(u'_'), 'line')
        self.mode_buttons = []
        self.refresh_rate_ctrl = urwid.Edit(('bold text', u'Refresh[s]:'), self.controller.refresh_rate)


        self.visible_graphs = {}
        self.graph_place_holder = urwid.WidgetPlaceholder(urwid.Pile([]))

        self.main_window_w = []

        self.stress_menu = StressMenu(self.on_menu_close)
        self.help_menu = HelpMenu(self.on_menu_close)
        self.about_menu = AboutMenu(self.on_menu_close)
        self.temp_sensors_menu = TempSensorsMenu(self.on_sensors_menu_close)
        self.global_data = GlobalData(is_admin)

        self.stress_menu.sqrt_workers = str(self.global_data.num_cpus)
        self.left_margin = 0
        self.top_margin = 0
        self.v_relative = 50
        self.h_relative = 50

        urwid.WidgetPlaceholder.__init__(self, self.main_window())
        urwid.connect_signal(self.refresh_rate_ctrl, 'change', self.update_refresh_rate)


    def update_refresh_rate(self, edit, new_refresh_rate):
        try:
            if float(new_refresh_rate) <= 0.001:
                pass
            else:
                self.controller.refresh_rate = new_refresh_rate
        except:
            self.controller.refresh_rate = '1.0'

    def update_displayed_information(self):
        """ Update all the graphs that are being displayed """

        for key,val in self.summaries.items():
            val.source.update()

        for g in self.visible_graphs.values():
            g.update_displayed_graph_data()

        for s in self.available_summaries.values():
            s.update()


    def on_reset_button(self, w):
        """Reset graph data and display empty graph"""
        for g in self.visible_graphs.values():
            g.reset()
        for g in self.graphs.values():
            try:
                g.source.reset()
            except NotImplementedError:
                pass
        self.update_displayed_information()

    def on_menu_close(self):
        """Return to main screen"""
        self.original_widget = self.main_window_w

    def on_sensors_menu_close(self):
        """Return to main screen and update sensor"""
        if self.temp_sensors_menu.current_active_mode:
            logging.info("State is not None")
            self.args.custom_temp = self.temp_sensors_menu.current_active_mode
            self.__init__(self.controller, self.args)
            logging.info("Temp sensor updated to " + self.args.custom_temp)
        else:
            logging.info("Temp sensor is None")

        self.original_widget = self.main_window_w


    def on_stress_menu_open(self, w):
        """Open stress options"""
        self.original_widget = urwid.Overlay(self.stress_menu.main_window,
                                             self.original_widget,
                                             ('relative', self.left_margin),
                                             self.stress_menu.get_size()[1],
                                             ('relative', self.top_margin),
                                             self.stress_menu.get_size()[0])

    def on_help_menu_open(self, w):
        """Open Help menu"""
        self.original_widget = urwid.Overlay(self.help_menu.main_window,
                                             self.original_widget,
                                             ('relative', self.left_margin),
                                             self.help_menu.get_size()[1],
                                             ('relative', self.top_margin),
                                             self.help_menu.get_size()[0])

    def on_about_menu_open(self, w):
        """Open About menu"""
        self.original_widget = urwid.Overlay(self.about_menu.main_window,
                                             self.original_widget,
                                             ('relative', self.left_margin),
                                             self.about_menu.get_size()[1],
                                             ('relative', self.top_margin),
                                             self.about_menu.get_size()[0])

    def on_temp_sensors_menu_open(self, w):
        """Open About menu"""
        self.original_widget = urwid.Overlay(self.temp_sensors_menu.main_window,
                                             self.original_widget,
                                             ('relative', self.left_margin),
                                             self.temp_sensors_menu.get_size()[1],
                                             ('relative', self.top_margin),
                                             self.temp_sensors_menu.get_size()[0])

    def on_mode_button(self, button, state):
        """Notify the controller of a new mode setting."""
        if state:
            # The new mode is the label of the button
            self.controller.set_mode(button.get_label())
            self.controller.start_stress()


    def on_mode_change(self, m):
        """Handle external mode change by updating radio buttons."""
        for rb in self.mode_buttons:
            if rb.get_label() == m:
                rb.set_state(True, do_callback=False)
                break

    def on_unicode_checkbox(self, w, state):
        """Enable smooth edges if utf-8 is supported"""
        logging.debug("unicode State is " + str(state))
        if state:
            self.hline = urwid.AttrWrap(urwid.SolidFill(u'\N{LOWER ONE QUARTER BLOCK}'), 'line')
        else:
            self.hline = urwid.AttrWrap(urwid.SolidFill(u'_'), 'line')

        for g_name,g in self.graphs.items():
            g.set_smooth_colors(state)

        self.show_graphs()


    def exit_program(self, w=None):
        """ Kill all stress operations upon exit"""
        try:
            kill_child_processes(self.controller.mode.get_stress_process())
        except:
            logging.debug('Could not kill process')
        raise urwid.ExitMainLoop()

    def graph_controls(self):
        """ Dislplay sidebar controls. i.e. buttons, and controls"""
        modes = self.controller.get_modes()
        # setup mode radio buttons
        group = []
        for m in modes:
            rb = radio_button(group, m, self.on_mode_button)
            self.mode_buttons.append(rb)

        # Create list of buttons
        control_options = [button("Reset", self.on_reset_button)]
        if stress_installed:
            control_options.append(button('Stress Options', self.on_stress_menu_open))
        control_options.append(button('Temp Sensors', self.on_temp_sensors_menu_open))
        control_options.append(button('Help', self.on_help_menu_open))
        control_options.append(button('About', self.on_about_menu_open))

        # Create the menu
        animate_controls = urwid.GridFlow(control_options, 18, 2, 0, 'center')


        if urwid.get_encoding_mode() == "utf8":
            unicode_checkbox = urwid.CheckBox(
                "Smooth Graph", state=False,
                on_state_change=self.on_unicode_checkbox)
        else:
            unicode_checkbox = urwid.Text(
                "UTF-8 encoding not detected")


        install_stress_message = urwid.Text("")
        if not stress_installed:
            install_stress_message = urwid.Text(('button normal', u"(N/A) install stress"))


        graph_checkboxes = [urwid.CheckBox(x.get_graph_name(), state=True,
                            on_state_change=lambda w, state, x=x:  self.change_checkbox_state(x, state))
                            for x in self.available_graphs.values()]
        unavalable_graphs = [urwid.Text(( "[N/A] " + x.get_graph_name()) ) for x in self.graphs.values() if x.source.get_is_available() == False]
        graph_checkboxes += unavalable_graphs

        buttons = [urwid.Text(('bold text', u"Modes"), align="center"),
                   ] +  self.mode_buttons + [
            install_stress_message,
            urwid.Divider(),
            urwid.Text(('bold text', u"Control Options"), align="center"),
            animate_controls,
            urwid.Divider(),
            self.refresh_rate_ctrl,
            urwid.Divider(),
            urwid.LineBox(urwid.Pile(graph_checkboxes)),
            urwid.LineBox(unicode_checkbox),
            urwid.Divider(),
            button("Quit", self.exit_program),
            ]

        return buttons

    def change_checkbox_state(self, x, state):

        if state:
            self.visible_graphs[x.get_graph_name()] = x
        else:
            del self.visible_graphs[x.get_graph_name()]
        self.show_graphs()


    def show_graphs(self):
        """Show a pile of the graph selected for dislpay"""
        elements = itertools.chain.from_iterable(([graph, ('fixed', 1, self.hline)]
                                            for graph in self.visible_graphs.values()))
        self.graph_place_holder.original_widget = urwid.Pile(elements)

    def cpu_stats(self):
           """Read and display processor name """
           cpu_name = urwid.Text("CPU Name N/A", align="center")
           try:
               cpu_name = urwid.Text(get_processor_name().strip(), align="center")
           except:
               logging.info("CPU name not available")
           cpu_stats = [cpu_name, urwid.Divider()]
           return cpu_stats

    def graph_stats(self):

        fixed_stats = []
        for key, val in self.available_summaries.items():
            fixed_stats += val.get_text_item_list()

        return fixed_stats

    def main_window(self):

        user_config_path = None
        if not user_config_dir_exists():
            user_config_path = make_user_config_dir()
        else:
            user_config_path = get_user_config_path()

        script_hooks_enabled = True
        if user_config_path is None:
            logging.warn('Failed to find or create scripts directory, proceeding without scripting support')
            script_hooks_enabled = False
        else:
            self.script_loader = ScriptHookLoader(user_config_path)

        # initiating the graphs
        self.graphs = OrderedDict()
        self.summaries = OrderedDict()

        # TODO: Update to find sensors automatically


        freq_source = FreqSource(is_admin)
        self.graphs[freq_source.get_source_name()] = StuiBarGraph(freq_source, 'freq light', 'freq dark', 'freq light smooth', 'freq dark smooth')
        self.summaries[freq_source.get_source_name()] = SummaryTextList(freq_source)

        util_source = UtilSource()
        self.graphs[util_source.get_source_name()] = StuiBarGraph(util_source, 'util light', 'util dark', 'util light smooth', 'util dark smooth')
        self.summaries[util_source.get_source_name()] = SummaryTextList(util_source)

        temp_source = TemperatureSource(self.custom_temp)

        if script_hooks_enabled:
            temp_source.add_edge_hook(self.script_loader.load_script(temp_source.__class__.__name__, 30000)) # Invoke threshold script every 30s while threshold is exceeded.

        alert_colors = ['high temp light', 'high temp dark', 'high temp light smooth', 'high temp dark smooth']
        self.graphs[temp_source.get_source_name()] = StuiBarGraph(temp_source, 'temp light', 'temp dark', 'temp light smooth', 'temp dark smooth', alert_colors=alert_colors)
        self.summaries[temp_source.get_source_name()] = SummaryTextList(temp_source, 'high temp txt')

        rapl_power_source = RaplPowerSource()
        self.graphs[rapl_power_source.get_source_name()] = StuiBarGraph(rapl_power_source, 'power dark', 'power light', 'power dark smooth', 'power light smooth')
        self.summaries[rapl_power_source.get_source_name()] = SummaryTextList(rapl_power_source)

        fan_source = FanSource(self.custom_fan)
        self.summaries[fan_source.get_source_name()] = SummaryTextList(fan_source)

        # only interested in available graph
        self.available_graphs = OrderedDict((key, val) for key, val in self.graphs.items() if val.get_is_available())
        self.available_summaries = OrderedDict((key, val) for key, val in self.summaries.items() if val.get_is_available())

        self.visible_graphs = self.available_graphs.copy()
        self.show_graphs()

        cpu_stats = self.cpu_stats()
        graph_controls = self.graph_controls()
        graph_stats = self.graph_stats()

        text_col = ViListBox(urwid.SimpleListWalker(cpu_stats + graph_controls + [urwid.Divider()] + graph_stats))

        vline = urwid.AttrWrap(urwid.SolidFill(u'\u2502'), 'line')
        w = urwid.Columns([
                           ('fixed',  20, text_col),
                           ('fixed',  1, vline),
                           ('weight', 2, self.graph_place_holder),
                           ],
                          dividechars=1, focus_column=0)

        w = urwid.Padding(w, ('fixed left', 1), ('fixed right', 0))
        w = urwid.AttrWrap(w, 'body')
        w = urwid.LineBox(w)
        w = urwid.AttrWrap(w, 'line')
        self.main_window_w = w
        return self.main_window_w