dotfiles/i3wrapper.py

138 lines
3.6 KiB
Python
Executable File

#!/usr/bin/env python
import json
import os
import subprocess
import sys
_BITS = []
def _bit(idx):
def wrapper(func):
_BITS.append([idx, func.__name__.replace('_', ''), func])
return func
return wrapper
@_bit(6)
def _mem():
with open('/proc/meminfo') as meminfo_fp:
attrs = {}
for line in meminfo_fp.readlines():
parts = line.split(':', 2)
attrs[parts[0].strip()] = parts[1].strip()
avail = int(attrs['MemAvailable'].split()[0])
total = int(attrs['MemTotal'].split()[0])
used = int(((total - avail) / total) * 100)
color = None
if used > 75:
color = '#ff0000'
if used < 25:
color = '#00ff00'
return 'M:{}%'.format(used), color
@_bit(0)
def _backlight(dev_dir='/sys/class/backlight/intel_backlight'):
with open('{}/brightness'.format(dev_dir)) as br_fp:
with open('{}/max_brightness'.format(dev_dir)) as mb_fp:
value = int(br_fp.read().strip())
max_value = int(mb_fp.read().strip())
pct = int(float(float(value) / float(max_value)) * 100)
color = None
if pct >= 75:
color = '#ffaa00'
if pct <= 25:
color = '#5599ff'
return '☼:{}%'.format(pct), color
THINKFAN_CONF = '/etc/thinkfan.conf'
ACPI_IBM_FAN = '/proc/acpi/ibm/fan'
@_bit(7)
def _hwtemp(conf=THINKFAN_CONF, fan=ACPI_IBM_FAN):
if not os.path.exists(conf):
return None, None
temps = []
with open('/etc/thinkfan.conf') as tfc_fp:
for line in tfc_fp.readlines():
if not line.startswith('hwmon '):
continue
try:
with open(line.split(' ')[1].strip()) as temp_fp:
temps.append(float(temp_fp.read()))
except (OSError, IOError) as exc:
sys.stderr.write(str(exc) + '\n')
avg_temp = float(sum(temps)) / len(temps) / 1000.0
color = None
fan_level = 'unset'
try:
with open(fan) as fan_fp:
for line in fan_fp.readlines():
if not line.startswith('level:\t\t'):
continue
fan_level = int(line.replace('level:\t\t', ''))
except (OSError, IOError) as exc:
sys.stderr.write(str(exc) + '\n')
if avg_temp > 75:
color = '#ff0000'
if avg_temp >= 50:
color = '#ffaa00'
if avg_temp <= 25:
color = '#5599ff'
return 'T:{:.1f}°C L:{}'.format(avg_temp, fan_level), color
def _print_line(message):
sys.stdout.write(message + '\n')
sys.stdout.flush()
def _read_line():
try:
line = sys.stdin.readline().strip()
if not line:
sys.exit(3)
return line
except KeyboardInterrupt:
sys.exit()
def main(bits=_BITS):
_print_line(_read_line())
_print_line(_read_line())
while True:
line, prefix = _read_line(), ''
if line.startswith(','):
line, prefix = line[1:], ','
loaded = json.loads(line)
for idx, name, func in bits:
try:
value, color = func()
if value is None:
continue
record = dict(full_text=str(value), name=name)
if color is not None:
record.update(dict(color=color))
loaded.insert(idx, record)
except Exception as exc:
sys.stderr.write(str(exc) + '\n')
sys.stderr.flush()
_print_line(prefix+json.dumps(loaded))
if __name__ == '__main__':
main()