From 996ddfc8c908763dbc94fa5d9074f3d4d8c20fa1 Mon Sep 17 00:00:00 2001 From: lasers Date: Mon, 6 Feb 2017 10:52:20 -0600 Subject: [PATCH 1/3] keyboard_layout: streamline --- py3status/modules/keyboard_layout.py | 65 +++++++++------------------- 1 file changed, 21 insertions(+), 44 deletions(-) diff --git a/py3status/modules/keyboard_layout.py b/py3status/modules/keyboard_layout.py index 17ff596f82..6b885aff80 100644 --- a/py3status/modules/keyboard_layout.py +++ b/py3status/modules/keyboard_layout.py @@ -3,18 +3,15 @@ Display keyboard layout. Configuration parameters: - cache_timeout: check for keyboard layout change every seconds (default 10) - colors: a comma separated string of color values for each layout, - eg: "us=#FCE94F, fr=#729FCF". (deprecated use color options) - (default None) - format: see placeholders below (default '{layout}') + cache_timeout: refresh interval for this module (default 10) + colors: deprecated. see color options below (default None) + format: display format for this module (default '{layout}') Format placeholders: - {layout} currently active keyboard layout + {layout} keyboard layout Color options: - color_: color for the layout - eg color_fr = '#729FCF' + color_: colorize the layout. eg color_fr = '#729FCF' Requires: xkblayout-state: @@ -26,6 +23,8 @@ """ import re +LAYOUTS_RE = re.compile(r".*layout:\s*((\w+,?)+).*", flags=re.DOTALL) +LEDMASK_RE = re.compile(r".*LED\smask:\s*\d{4}([01])\d{3}.*", flags=re.DOTALL) class Py3status: @@ -36,17 +35,15 @@ class Py3status: colors = None format = '{layout}' - def __init__(self): - """ - find the best implementation to get the keyboard's layout - """ + def post_config_hook(self): try: self._xkblayout() self._command = self._xkblayout except: - self._command = self._xset + self._command = self._setxkbmap + self.colors_dict = {} - # old default values for backwards compatability + # old compatability: set default values self.defaults = { 'fr': '#268BD2', 'ru': '#F75252', @@ -55,58 +52,38 @@ def __init__(self): } def keyboard_layout(self): + lang = self._command().strip() or '??' response = { 'cached_until': self.py3.time_in(self.cache_timeout), - 'full_text': '' + 'full_text': self.py3.safe_format(self.format, {'layout': lang}) } + if self.colors and not self.colors_dict: self.colors_dict = dict((k.strip(), v.strip()) for k, v in ( layout.split('=') for layout in self.colors.split(','))) - lang = self._command().strip() or '??' - lang_color = getattr(self.py3, 'COLOR_%s' % lang.upper()) if not lang_color: lang_color = self.colors_dict.get(lang) - if not lang_color: - # If not found try to use old default value + if not lang_color: # old compatability: try default value lang_color = self.defaults.get(lang) - if lang_color: response['color'] = lang_color - response['full_text'] = self.py3.safe_format(self.format, {'layout': lang}) return response - def _get_layouts(self): - """ - Returns a list of predefined keyboard layouts - """ - layouts_re = re.compile(r".*layout:\s*((\w+,?)+).*", flags=re.DOTALL) - out = self.py3.command_output(["setxkbmap", "-query"]) - - layouts = re.match(layouts_re, out).group(1).split(",") - return layouts - def _xkblayout(self): - """ - check using xkblayout-state - """ return self.py3.command_output(["xkblayout-state", "print", "%s"]) - def _xset(self): - """ - Check using setxkbmap >= 1.3.0 and xset - This method works only for the first two predefined layouts. - """ - ledmask_re = re.compile(r".*LED\smask:\s*\d{4}([01])\d{3}.*", - flags=re.DOTALL) - layouts = self._get_layouts() + def _setxkbmap(self): + # this method works only for the first two predefined layouts. + out = self.py3.command_output(["setxkbmap", "-query"]) + layouts = re.match(LAYOUTS_RE, out).group(1).split(",") if len(layouts) == 1: return layouts[0] - xset_output = self.py3.command_output(["xset", "-q"]) - led_mask = re.match(ledmask_re, xset_output).groups(0)[0] + xset_output = self.py3.command_output(["xset", "-q"]) + led_mask = re.match(LEDMASK_RE, xset_output).groups(0)[0] return layouts[int(led_mask)] From 2b30d97c112a013edb2f28ce99287d11c0f1aabe Mon Sep 17 00:00:00 2001 From: lasers Date: Sat, 18 Feb 2017 00:41:30 -0600 Subject: [PATCH 2/3] external_script: fix exception --- py3status/modules/external_script.py | 58 ++++++++++++++++------------ 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/py3status/modules/external_script.py b/py3status/modules/external_script.py index db15c0dcc9..e6a25b37be 100644 --- a/py3status/modules/external_script.py +++ b/py3status/modules/external_script.py @@ -30,6 +30,9 @@ @author frimdo ztracenastopa@centrum.cz """ +STRING_UNAVAILABLE = "external_script: N/A" +STRING_ERROR = "external_script: error" + class Py3status: """ @@ -41,34 +44,39 @@ class Py3status: strip_output = False def external_script(self): - if self.script_path: - return_value = self.py3.command_output(self.script_path, shell=True) - # this is a convenience cleanup code to avoid breaking i3bar which - # does not support multi lines output - if len(return_value.split('\n')) > 2: - return_value = return_value.split('\n')[0] - self.py3.notify_user( - 'Script {} output contains new lines.'.format( - self.script_path) + - ' Only the first one is being displayed to avoid breaking your i3bar', - rate_limit=None) - elif return_value[-1] == '\n': - return_value = return_value.rstrip('\n') - - if self.strip_output: - return_value = return_value.strip() - - response = { - 'cached_until': self.py3.time_in(self.cache_timeout), - 'full_text': self.py3.safe_format(self.format, - {'output': return_value}) + if not self.script_path: + return { + 'cached_until': self.py3.CACHE_FOREVER, + 'color': self.py3.COLOR_BAD, + 'full_text': STRING_UNAVAILABLE } - else: - response = { + try: + full_text = self.py3.command_output(self.script_path, shell=True) + except: + return { 'cached_until': self.py3.time_in(self.cache_timeout), - 'full_text': '' + 'color': self.py3.COLOR_BAD, + 'full_text': STRING_ERROR } - return response + # this is a convenience cleanup code to avoid breaking i3bar which + # does not support multi lines output + if len(full_text.split('\n')) > 2: + full_text = full_text.split('\n')[0] + self.py3.notify_user( + 'Script {} output contains new lines.'.format( + self.script_path) + + ' Only the first one is being displayed to avoid breaking your i3bar', + rate_limit=None) + elif full_text[-1] == '\n': + full_text = full_text.rstrip('\n') + + if self.strip_output: + full_text = full_text.strip() + + return { + 'cached_until': self.py3.time_in(self.cache_timeout), + 'full_text': self.py3.safe_format(self.format, {'output': full_text}) + } if __name__ == "__main__": From 03f53f8ff89c452aae26d40b1d2ee991ab284d08 Mon Sep 17 00:00:00 2001 From: lasers Date: Sat, 18 Feb 2017 05:23:55 -0600 Subject: [PATCH 3/3] external_script: new state --- py3status/modules/external_script.py | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/py3status/modules/external_script.py b/py3status/modules/external_script.py index e6a25b37be..a66621ef76 100644 --- a/py3status/modules/external_script.py +++ b/py3status/modules/external_script.py @@ -51,31 +51,21 @@ def external_script(self): 'full_text': STRING_UNAVAILABLE } try: - full_text = self.py3.command_output(self.script_path, shell=True) + output = self.py3.command_output(self.script_path, shell=True) + output = output.splitlines()[0] except: return { 'cached_until': self.py3.time_in(self.cache_timeout), 'color': self.py3.COLOR_BAD, 'full_text': STRING_ERROR } - # this is a convenience cleanup code to avoid breaking i3bar which - # does not support multi lines output - if len(full_text.split('\n')) > 2: - full_text = full_text.split('\n')[0] - self.py3.notify_user( - 'Script {} output contains new lines.'.format( - self.script_path) + - ' Only the first one is being displayed to avoid breaking your i3bar', - rate_limit=None) - elif full_text[-1] == '\n': - full_text = full_text.rstrip('\n') if self.strip_output: - full_text = full_text.strip() + output = output.strip() return { 'cached_until': self.py3.time_in(self.cache_timeout), - 'full_text': self.py3.safe_format(self.format, {'output': full_text}) + 'full_text': self.py3.safe_format(self.format, {'output': output}) }