diff --git a/conf.yaml b/conf.yaml index 7416c97..4ce9b8f 100644 --- a/conf.yaml +++ b/conf.yaml @@ -1,4 +1,12 @@ +# Typical plugin properties: +# - name: plugin name (always required, all other properties are optional) +# - title: title representation on the panel +# - hide_ok: false to force display value even if it is below problem threshold +# - problem: a threshold value to make a value urgent and / or display +# the value on the panel + output_format: i3 + plugins: - name: ping title: NET @@ -6,15 +14,22 @@ plugins: - de-ber-as20647.anchors.atlas.ripe.net - nl-ams-as1101.anchors.atlas.ripe.net - uk-boh-as196745.anchors.atlas.ripe.net + hide_ok: false + - name: disk partition: / problem: 80 hide_ok: false + - name: disk partition: /home problem: 90 + - name: pacman + - name: mem + - name: load + - name: date format: '%a %d %H:%M' diff --git a/plugins/__init__.py b/plugins/__init__.py index 1a46771..3f61ec8 100644 --- a/plugins/__init__.py +++ b/plugins/__init__.py @@ -17,11 +17,18 @@ class PluginThreadCommon: self.thread = threading.Thread(target=self.run) self.thread.daemon = True + def format_status(self, status, urgent=False): + if 'title' in self.conf: + full_text = self.conf['title'] + ': ' + status + else: + full_text = status + self.status.update({'full_text': full_text, 'urgent': urgent}) + def start(self): self.thread.start() def main(self): - self.status['full_text'] = 'placeholder' + pass def run(self): while True: diff --git a/plugins/batt.py b/plugins/batt.py index b89d00d..b932ce5 100644 --- a/plugins/batt.py +++ b/plugins/batt.py @@ -17,13 +17,14 @@ class PluginThread(plugins.PluginThreadCommon): with \ open(BATTERY_DIR + 'capacity', 'r') as batt_capacity, \ open(BATTERY_DIR + 'status', 'r') as batt_status: - status = batt_status.read().strip() - capacity = batt_capacity.read().strip() - if status != 'Discharging': + capacity = batt_capacity.readline().strip() + status_value = batt_status.readline().strip() + + if status_value != 'Discharging': symbol = self.conf['symbol_charging'] - self.status['urgent'] = False + urgent = False else: symbol = self.conf['symbol_discharging'] - self.status['urgent'] = float(capacity) <= self.conf['problem'] + urgent = float(capacity) <= self.conf['problem'] - self.status['full_text'] = 'BAT: ' + capacity + '% ' + symbol + self.format_status(capacity + '% ' + symbol, urgent=urgent) diff --git a/plugins/date.py b/plugins/date.py index 8afe76e..9e2a292 100644 --- a/plugins/date.py +++ b/plugins/date.py @@ -15,4 +15,4 @@ class PluginThread(plugins.PluginThreadCommon): def main(self): now = datetime.datetime.now(tz=self.timezone) - self.status['full_text'] = now.strftime(self.conf['format']) + self.format_status(now.strftime(self.conf['format'])) diff --git a/plugins/disk.py b/plugins/disk.py index e705f4e..6085795 100644 --- a/plugins/disk.py +++ b/plugins/disk.py @@ -8,6 +8,8 @@ DISK_DEFAULTS = {'partition': '/', 'problem': 80, 'freq': 15} class PluginThread(plugins.PluginThreadCommon): def __init__(self, config): super(PluginThread, self).__init__(config, DISK_DEFAULTS) + if 'title' not in self.conf: + self.conf['title'] = self.conf['partition'] def main(self): du_stat = psutil.disk_usage(self.conf['partition']) @@ -17,6 +19,5 @@ class PluginThread(plugins.PluginThreadCommon): else: self.hide = True self.status['urgent'] = False - du_free = str(round(du_stat.free / 2**30, 2)) - disk_usage = self.conf['partition'] + ': ' + du_free + 'G' - self.status['full_text'] = disk_usage + status = '{:.2f}G'.format(du_stat.free / 2**30) + self.format_status(status) diff --git a/plugins/filecat.py b/plugins/filecat.py index 9eae04d..5f404c9 100644 --- a/plugins/filecat.py +++ b/plugins/filecat.py @@ -13,10 +13,6 @@ class PluginThread(plugins.PluginThreadCommon): self.hide = False self.format_status(self.conf['title'], False) - def format_status(self, contents, urgent): - self.status['urgent'] = urgent - self.status['full_text'] = self.conf['title'] + ': ' + contents - def main(self): try: with open(self.conf['filename'], 'r') as datafile: diff --git a/plugins/fortune.py b/plugins/fortune.py index 562d653..0f35354 100644 --- a/plugins/fortune.py +++ b/plugins/fortune.py @@ -3,7 +3,7 @@ import requests import time -FGA_DEFAULTS = { +FORTUNE_DEFAULTS = { 'uri': 'http://fucking-great-advice.ru/api/random', 'freq': 120, 'retry': 3 } @@ -11,21 +11,21 @@ FGA_DEFAULTS = { class PluginThread(plugins.PluginThreadCommon): def __init__(self, config): - super(PluginThread, self).__init__(config, FGA_DEFAULTS) + super(PluginThread, self).__init__(config, FORTUNE_DEFAULTS) self.retry = False def main(self): try: req = requests.get(self.conf['uri'], timeout=2) - advice = req.json()['text'] if req.status_code == 200 else 'N/A' + fortune = req.json()['text'] if req.status_code == 200 else 'N/A' self.retry = False except requests.exceptions.Timeout: - advice = 'N/A (timeout)' + fortune = 'N/A (timeout)' self.retry = True except requests.exceptions.ConnectionError: - advice = 'N/A (offline)' + fortune = 'N/A (offline)' self.retry = True - self.status['full_text'] = advice + self.format_status(fortune) def run(self): while True: diff --git a/plugins/load.py b/plugins/load.py index 75dd4a0..d68441f 100644 --- a/plugins/load.py +++ b/plugins/load.py @@ -2,7 +2,7 @@ import os import plugins -LOAD_DEFAULTS = {'freq': 20, 'problem': 1} +LOAD_DEFAULTS = {'title': 'LA', 'freq': 20, 'problem': 1} class PluginThread(plugins.PluginThreadCommon): @@ -13,8 +13,9 @@ class PluginThread(plugins.PluginThreadCommon): loads = os.getloadavg() if loads[0] >= self.conf['problem']: self.hide = False - self.status['urgent'] = True + urgent = True else: self.hide = True - self.status['urgent'] = False - self.status['full_text'] = 'LA: {:.2f} {:.2f} {:.2f}'.format(*loads) + urgent = False + status = '{:.2f} {:.2f} {:.2f}'.format(*loads) + self.format_status(status, urgent=urgent) diff --git a/plugins/mem.py b/plugins/mem.py index 1abc7eb..2eeaad5 100644 --- a/plugins/mem.py +++ b/plugins/mem.py @@ -2,7 +2,7 @@ import psutil import plugins -MEM_DEFAULTS = {'problem': 85} +MEM_DEFAULTS = {'title': 'RAM', 'problem': 85} class PluginThread(plugins.PluginThreadCommon): @@ -13,9 +13,9 @@ class PluginThread(plugins.PluginThreadCommon): mem_stat = psutil.virtual_memory() if mem_stat.percent > self.conf['problem']: self.hide = False - self.status['urgent'] = True + urgent = True else: self.hide = True - self.status['urgent'] = False + urgent = False mem_available = round(mem_stat.available / 2**30, 2) - self.status['full_text'] = 'RAM: {:.2f}G'.format(mem_available) + self.format_status('{:.2f}G'.format(mem_available), urgent) diff --git a/plugins/pacman.py b/plugins/pacman.py index edf36e9..625314b 100644 --- a/plugins/pacman.py +++ b/plugins/pacman.py @@ -11,12 +11,6 @@ PACMAN_DEFAULTS = { class PluginThread(plugins.PluginThreadCommon): def __init__(self, config): super(PluginThread, self).__init__(config, PACMAN_DEFAULTS) - self.format_status(0) - - def format_status(self, count): - self.hide = count == 0 - self.status['urgent'] = count >= self.conf['problem'] - self.status['full_text'] = self.conf['title'] + ': ' + str(count) def main(self): pacman_qu = subprocess.Popen( @@ -25,5 +19,11 @@ class PluginThread(plugins.PluginThreadCommon): encoding='UTF-8' ) out = pacman_qu.communicate()[0].strip().splitlines() - packages = [pkg for pkg in out if not '[ignored]' in pkg] - self.format_status(len(packages)) + packages = len([pkg for pkg in out if not '[ignored]' in pkg]) + if packages: + self.hide = False + else: + self.hide = True + self.format_status( + str(packages), urgent=packages >= self.conf['problem'] + ) diff --git a/plugins/ping.py b/plugins/ping.py index 8e6a391..e919dea 100644 --- a/plugins/ping.py +++ b/plugins/ping.py @@ -1,33 +1,26 @@ import os +import subprocess import random import plugins PING_DEFAULTS = { - 'hosts': list(), 'title': 'PING', 'timeout': 150 + 'hosts': tuple(), 'title': 'PING', 'timeout': 150 } class PluginThread(plugins.PluginThreadCommon): def __init__(self, config): super(PluginThread, self).__init__(config, PING_DEFAULTS) - self.format_status('n/a') - - def format_status(self, state): - self.status['full_text'] = self.conf['title'] + ': ' + state - if state == 'up': - self.status['urgent'] = False - self.hide = True - else: - self.status['urgent'] = True + self.ping_cmd = ('fping', '-c1', '-qt' + str(self.conf['timeout'])) def main(self): - random.shuffle(self.conf['hosts']) - for host in self.conf['hosts']: - fping = 'fping -qc1t' + str(self.conf['timeout'])\ - + ' ' + host + ' &>/dev/null' - response = os.system(fping) - if response == 0: - self.format_status('on') - break - self.format_status('down') + host = random.choice(self.conf['hosts']) + fping = subprocess.run( + (*self.ping_cmd, host), + stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL + ) + if fping.returncode == 0: + self.format_status('up') + else: + self.format_status('down', urgent=True) diff --git a/vdstatus b/vdstatus index e5d8cf6..88b9a91 100755 --- a/vdstatus +++ b/vdstatus @@ -49,8 +49,9 @@ class PluginRunner: outputs = list() for plugin in self.plugins_loaded: if \ - not plugin.conf['hide_ok'] or \ - not plugin.hide: + 'full_text' in plugin.status and ( + not plugin.conf['hide_ok'] or not plugin.hide + ): outputs.append(plugin.status) print(self.format_output(outputs), flush=True)