[formatting] reformat using "black -t py34"

getting rid of thinking about consistent formatting...
This commit is contained in:
tobi-wan-kenobi 2020-05-03 11:15:52 +02:00
parent fa98bcbdd1
commit 30c1f712a6
119 changed files with 3961 additions and 3495 deletions

View file

@ -1,6 +1,6 @@
# pylint: disable=C0111,R0903
'''Displays volume and mute status and controls for PulseAudio devices. Use wheel up and down to change volume, left click mutes, right click opens pavucontrol.
"""Displays volume and mute status and controls for PulseAudio devices. Use wheel up and down to change volume, left click mutes, right click opens pavucontrol.
Aliases: pasink (use this to control output instead of input), pasource
@ -16,7 +16,7 @@ Requires the following executable:
* pulseaudio
* pactl
* pavucontrol
'''
"""
import re
import logging
@ -29,15 +29,18 @@ import util.cli
import util.graph
import util.format
class Module(core.module.Module):
def __init__(self, config, theme, channel):
super().__init__(config, theme, core.widget.Widget(self.volume))
if util.format.asbool(self.parameter('autostart', False)):
util.cli.execute('pulseaudio --start', ignore_errors=True)
if util.format.asbool(self.parameter("autostart", False)):
util.cli.execute("pulseaudio --start", ignore_errors=True)
self._change = util.format.asint(self.parameter('percent_change', '2%').strip('%'), 0, 100)
self._limit = util.format.asint(self.parameter('limit', '0%').strip('%'), 0)
self._change = util.format.asint(
self.parameter("percent_change", "2%").strip("%"), 0, 100
)
self._limit = util.format.asint(self.parameter("limit", "0%").strip("%"), 0)
self._left = 0
self._right = 0
@ -45,131 +48,153 @@ class Module(core.module.Module):
self._mute = False
self._failed = False
self._channel = channel
self._showbars = util.format.asbool(self.parameter('showbars', 0))
self._showbars = util.format.asbool(self.parameter("showbars", 0))
self._patterns = [
{'expr': 'Name:', 'callback': (lambda line: False)},
{'expr': 'Mute:', 'callback': (lambda line: self.mute(False if ' no' in line.lower() else True))},
{'expr': 'Volume:', 'callback': self.getvolume},
{"expr": "Name:", "callback": (lambda line: False)},
{
"expr": "Mute:",
"callback": (
lambda line: self.mute(False if " no" in line.lower() else True)
),
},
{"expr": "Volume:", "callback": self.getvolume},
]
core.input.register(self, button=core.input.RIGHT_MOUSE, cmd='pavucontrol')
core.input.register(self, button=core.input.RIGHT_MOUSE, cmd="pavucontrol")
events = [
{'type': 'mute', 'action': self.toggle, 'button': core.input.LEFT_MOUSE},
{'type': 'volume', 'action': self.increase_volume, 'button': core.input.WHEEL_UP},
{'type': 'volume', 'action': self.decrease_volume, 'button': core.input.WHEEL_DOWN},
{"type": "mute", "action": self.toggle, "button": core.input.LEFT_MOUSE},
{
"type": "volume",
"action": self.increase_volume,
"button": core.input.WHEEL_UP,
},
{
"type": "volume",
"action": self.decrease_volume,
"button": core.input.WHEEL_DOWN,
},
]
for event in events:
core.input.register(self, button=event['button'], cmd=event['action'])
core.input.register(self, button=event["button"], cmd=event["action"])
def set_volume(self, amount):
util.cli.execute('pactl set-{}-{} @DEFAULT_{}@ {}'.format(
self._channel, 'volume', self._channel.upper(), amount))
util.cli.execute(
"pactl set-{}-{} @DEFAULT_{}@ {}".format(
self._channel, "volume", self._channel.upper(), amount
)
)
def increase_volume(self, event):
if self._limit > 0: # we need to check the limit
if self._limit > 0: # we need to check the limit
left = int(self._left)
right = int(self._right)
if left + self._change >= self._limit or right + self._change >= self._limit:
if (
left + self._change >= self._limit
or right + self._change >= self._limit
):
if left == right:
# easy case, just set to limit
self.set_volume('{}%'.format(self._limit))
self.set_volume("{}%".format(self._limit))
return
else:
# don't adjust anymore, since i don't know how to update only one channel
return
self.set_volume('+{}%'.format(self._change))
self.set_volume("+{}%".format(self._change))
def decrease_volume(self, event):
self.set_volume('-{}%'.format(self._change))
self.set_volume("-{}%".format(self._change))
def toggle(self, event):
util.cli.execute('pactl set-{}-mute @DEFAULT_{}@ toggle'.format(
self._channel, self._channel.upper()))
util.cli.execute(
"pactl set-{}-mute @DEFAULT_{}@ toggle".format(
self._channel, self._channel.upper()
)
)
def mute(self, value):
self._mute = value
def getvolume(self, line):
if 'mono' in line:
m = re.search(r'mono:.*\s*\/\s*(\d+)%', line)
if "mono" in line:
m = re.search(r"mono:.*\s*\/\s*(\d+)%", line)
if m:
self._mono = m.group(1)
else:
m = re.search(r'left:.*\s*\/\s*(\d+)%.*right:.*\s*\/\s*(\d+)%', line)
m = re.search(r"left:.*\s*\/\s*(\d+)%.*right:.*\s*\/\s*(\d+)%", line)
if m:
self._left = m.group(1)
self._right = m.group(2)
def _default_device(self):
output = util.cli.execute('pactl info')
pattern = 'Default {}: '.format('Sink' if self._channel == 'sink' else 'Source')
for line in output.split('\n'):
output = util.cli.execute("pactl info")
pattern = "Default {}: ".format("Sink" if self._channel == "sink" else "Source")
for line in output.split("\n"):
if line.startswith(pattern):
return line.replace(pattern, '')
logging.error('no pulseaudio device found')
return 'n/a'
return line.replace(pattern, "")
logging.error("no pulseaudio device found")
return "n/a"
def volume(self, widget):
if self._failed == True:
return 'n/a'
return "n/a"
if int(self._mono) > 0:
vol = '{}%'.format(self._mono)
vol = "{}%".format(self._mono)
if self._showbars:
vol = '{} {}'.format(
vol, util.graph.hbar(float(self._mono)))
vol = "{} {}".format(vol, util.graph.hbar(float(self._mono)))
return vol
elif self._left == self._right:
vol = '{}%'.format(self._left)
vol = "{}%".format(self._left)
if self._showbars:
vol = '{} {}'.format(
vol, util.graph.hbar(float(self._left)))
vol = "{} {}".format(vol, util.graph.hbar(float(self._left)))
return vol
else:
vol = '{}%/{}%'.format(self._left, self._right)
vol = "{}%/{}%".format(self._left, self._right)
if self._showbars:
vol = '{} {}{}'.format(
vol = "{} {}{}".format(
vol,
util.graph.hbar(float(self._left)),
util.graph.hbar(float(self._right)))
util.graph.hbar(float(self._right)),
)
return vol
def update(self):
try:
self._failed = False
channel = 'sinks' if self._channel == 'sink' else 'sources'
channel = "sinks" if self._channel == "sink" else "sources"
device = self._default_device()
result = util.cli.execute('pactl list {}'.format(channel))
result = util.cli.execute("pactl list {}".format(channel))
found = False
for line in result.split('\n'):
if 'Name: {}'.format(device) in line:
for line in result.split("\n"):
if "Name: {}".format(device) in line:
found = True
continue
if found is False:
continue
for pattern in self._patterns:
if not pattern['expr'] in line:
if not pattern["expr"] in line:
continue
if pattern['callback'](line) is False and found == True:
if pattern["callback"](line) is False and found == True:
return
except Exception as e:
self._failed = True
logging.exception(e)
if util.format.asbool(self.parameter('autostart', False)):
util.cli.execute('pulseaudio --start', ignore_errors=True)
if util.format.asbool(self.parameter("autostart", False)):
util.cli.execute("pulseaudio --start", ignore_errors=True)
else:
raise e
def state(self, widget):
if self._mute:
return ['warning', 'muted']
return ["warning", "muted"]
if int(self._left) > int(100):
return ['critical', 'unmuted']
return ['unmuted']
return ["critical", "unmuted"]
return ["unmuted"]
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -17,7 +17,8 @@ import core.input
import util.format
class UPowerManager():
class UPowerManager:
def __init__(self):
self.UPOWER_NAME = "org.freedesktop.UPower"
self.UPOWER_PATH = "/org/freedesktop/UPower"
@ -56,64 +57,100 @@ class UPowerManager():
battery_proxy = self.bus.get_object(self.UPOWER_NAME, battery)
battery_proxy_interface = dbus.Interface(battery_proxy, self.DBUS_PROPERTIES)
hasHistory = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "HasHistory")
hasStatistics = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "HasStatistics")
isPresent = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "IsPresent")
isRechargable = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "IsRechargeable")
hasHistory = battery_proxy_interface.Get(
self.UPOWER_NAME + ".Device", "HasHistory"
)
hasStatistics = battery_proxy_interface.Get(
self.UPOWER_NAME + ".Device", "HasStatistics"
)
isPresent = battery_proxy_interface.Get(
self.UPOWER_NAME + ".Device", "IsPresent"
)
isRechargable = battery_proxy_interface.Get(
self.UPOWER_NAME + ".Device", "IsRechargeable"
)
online = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Online")
powersupply = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "PowerSupply")
powersupply = battery_proxy_interface.Get(
self.UPOWER_NAME + ".Device", "PowerSupply"
)
capacity = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Capacity")
energy = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Energy")
energyempty = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "EnergyEmpty")
energyfull = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "EnergyFull")
energyfulldesign = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "EnergyFullDesign")
energyrate = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "EnergyRate")
luminosity = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Luminosity")
percentage = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Percentage")
temperature = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Temperature")
energyempty = battery_proxy_interface.Get(
self.UPOWER_NAME + ".Device", "EnergyEmpty"
)
energyfull = battery_proxy_interface.Get(
self.UPOWER_NAME + ".Device", "EnergyFull"
)
energyfulldesign = battery_proxy_interface.Get(
self.UPOWER_NAME + ".Device", "EnergyFullDesign"
)
energyrate = battery_proxy_interface.Get(
self.UPOWER_NAME + ".Device", "EnergyRate"
)
luminosity = battery_proxy_interface.Get(
self.UPOWER_NAME + ".Device", "Luminosity"
)
percentage = battery_proxy_interface.Get(
self.UPOWER_NAME + ".Device", "Percentage"
)
temperature = battery_proxy_interface.Get(
self.UPOWER_NAME + ".Device", "Temperature"
)
voltage = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Voltage")
timetoempty = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "TimeToEmpty")
timetofull = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "TimeToFull")
timetoempty = battery_proxy_interface.Get(
self.UPOWER_NAME + ".Device", "TimeToEmpty"
)
timetofull = battery_proxy_interface.Get(
self.UPOWER_NAME + ".Device", "TimeToFull"
)
iconname = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "IconName")
model = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Model")
nativepath = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "NativePath")
nativepath = battery_proxy_interface.Get(
self.UPOWER_NAME + ".Device", "NativePath"
)
serial = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Serial")
vendor = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Vendor")
state = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "State")
technology = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Technology")
technology = battery_proxy_interface.Get(
self.UPOWER_NAME + ".Device", "Technology"
)
battype = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Type")
warninglevel = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "WarningLevel")
updatetime = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "UpdateTime")
warninglevel = battery_proxy_interface.Get(
self.UPOWER_NAME + ".Device", "WarningLevel"
)
updatetime = battery_proxy_interface.Get(
self.UPOWER_NAME + ".Device", "UpdateTime"
)
information_table = {
'HasHistory': hasHistory,
'HasStatistics': hasStatistics,
'IsPresent': isPresent,
'IsRechargeable': isRechargable,
'Online': online,
'PowerSupply': powersupply,
'Capacity': capacity,
'Energy': energy,
'EnergyEmpty': energyempty,
'EnergyFull': energyfull,
'EnergyFullDesign': energyfulldesign,
'EnergyRate': energyrate,
'Luminosity': luminosity,
'Percentage': percentage,
'Temperature': temperature,
'Voltage': voltage,
'TimeToEmpty': timetoempty,
'TimeToFull': timetofull,
'IconName': iconname,
'Model': model,
'NativePath': nativepath,
'Serial': serial,
'Vendor': vendor,
'State': state,
'Technology': technology,
'Type': battype,
'WarningLevel': warninglevel,
'UpdateTime': updatetime
"HasHistory": hasHistory,
"HasStatistics": hasStatistics,
"IsPresent": isPresent,
"IsRechargeable": isRechargable,
"Online": online,
"PowerSupply": powersupply,
"Capacity": capacity,
"Energy": energy,
"EnergyEmpty": energyempty,
"EnergyFull": energyfull,
"EnergyFullDesign": energyfulldesign,
"EnergyRate": energyrate,
"Luminosity": luminosity,
"Percentage": percentage,
"Temperature": temperature,
"Voltage": voltage,
"TimeToEmpty": timetoempty,
"TimeToFull": timetofull,
"IconName": iconname,
"Model": model,
"NativePath": nativepath,
"Serial": serial,
"Vendor": vendor,
"State": state,
"Technology": technology,
"Type": battype,
"WarningLevel": warninglevel,
"UpdateTime": updatetime,
}
return information_table
@ -122,40 +159,48 @@ class UPowerManager():
upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH)
upower_interface = dbus.Interface(upower_proxy, self.DBUS_PROPERTIES)
is_lid_present = bool(upower_interface.Get(self.UPOWER_NAME, 'LidIsPresent'))
is_lid_present = bool(upower_interface.Get(self.UPOWER_NAME, "LidIsPresent"))
return is_lid_present
def is_lid_closed(self):
upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH)
upower_interface = dbus.Interface(upower_proxy, self.DBUS_PROPERTIES)
is_lid_closed = bool(upower_interface.Get(self.UPOWER_NAME, 'LidIsClosed'))
is_lid_closed = bool(upower_interface.Get(self.UPOWER_NAME, "LidIsClosed"))
return is_lid_closed
def on_battery(self):
upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH)
upower_interface = dbus.Interface(upower_proxy, self.DBUS_PROPERTIES)
on_battery = bool(upower_interface.Get(self.UPOWER_NAME, 'OnBattery'))
on_battery = bool(upower_interface.Get(self.UPOWER_NAME, "OnBattery"))
return on_battery
def has_wakeup_capabilities(self):
upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH + "/Wakeups")
upower_proxy = self.bus.get_object(
self.UPOWER_NAME, self.UPOWER_PATH + "/Wakeups"
)
upower_interface = dbus.Interface(upower_proxy, self.DBUS_PROPERTIES)
has_wakeup_capabilities = bool(upower_interface.Get(self.UPOWER_NAME + '.Wakeups', 'HasCapability'))
has_wakeup_capabilities = bool(
upower_interface.Get(self.UPOWER_NAME + ".Wakeups", "HasCapability")
)
return has_wakeup_capabilities
def get_wakeups_data(self):
upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH + "/Wakeups")
upower_interface = dbus.Interface(upower_proxy, self.UPOWER_NAME + '.Wakeups')
upower_proxy = self.bus.get_object(
self.UPOWER_NAME, self.UPOWER_PATH + "/Wakeups"
)
upower_interface = dbus.Interface(upower_proxy, self.UPOWER_NAME + ".Wakeups")
data = upower_interface.GetData()
return data
def get_wakeups_total(self):
upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH + "/Wakeups")
upower_interface = dbus.Interface(upower_proxy, self.UPOWER_NAME + '.Wakeups')
upower_proxy = self.bus.get_object(
self.UPOWER_NAME, self.UPOWER_PATH + "/Wakeups"
)
upower_interface = dbus.Interface(upower_proxy, self.UPOWER_NAME + ".Wakeups")
data = upower_interface.GetTotal()
return data
@ -166,7 +211,7 @@ class UPowerManager():
state = int(battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "State"))
if (state == 1):
if state == 1:
return True
else:
return False
@ -177,21 +222,22 @@ class UPowerManager():
state = int(battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "State"))
if (state == 0):
if state == 0:
return "Unknown"
elif (state == 1):
elif state == 1:
return "Loading"
elif (state == 2):
elif state == 2:
return "Discharging"
elif (state == 3):
elif state == 3:
return "Empty"
elif (state == 4):
elif state == 4:
return "Fully charged"
elif (state == 5):
elif state == 5:
return "Pending charge"
elif (state == 6):
elif state == 6:
return "Pending discharge"
class Module(core.module.Module):
def __init__(self, config, theme):
super().__init__(config, theme, core.widget.Widget(self.capacity))
@ -201,11 +247,11 @@ class Module(core.module.Module):
self.device = self.power.get_display_device()
except Exception as e:
logging.exception("unable to get battery display device: {}".format(str(e)))
core.input.register(self, button=core.input.LEFT_MOUSE,
cmd="gnome-power-statistics")
core.input.register(
self, button=core.input.LEFT_MOUSE, cmd="gnome-power-statistics"
)
self._showremaining = util.format.asbool(
self.parameter("showremaining", True))
self._showremaining = util.format.asbool(self.parameter("showremaining", True))
def capacity(self, widget):
widget.set("capacity", -1)
@ -222,19 +268,25 @@ class Module(core.module.Module):
if self._showremaining:
try:
p = self.power # an alias to make each line of code shorter
p = self.power # an alias to make each line of code shorter
proxy = p.bus.get_object(p.UPOWER_NAME, self.device)
interface = dbus.Interface(proxy, p.DBUS_PROPERTIES)
state = int(interface.Get(p.UPOWER_NAME+".Device", "State"))
state = int(interface.Get(p.UPOWER_NAME + ".Device", "State"))
# state: 1 => charging, 2 => discharging, other => don't care
remain = int(interface.Get(
p.UPOWER_NAME+".Device", ["TimeToFull", "TimeToEmpty"][state-1]))
remain = int(
interface.Get(
p.UPOWER_NAME + ".Device",
["TimeToFull", "TimeToEmpty"][state - 1],
)
)
remain = util.format.duration(remain, compact=True, unit=True)
output = "{} {}".format(output, remain)
except IndexError:
pass
except Exception as e:
logging.exception("unable to get battery remaining time: {}".format(str(e)))
logging.exception(
"unable to get battery remaining time: {}".format(str(e))
)
return output
@ -258,9 +310,17 @@ class Module(core.module.Module):
except Exception as e:
logging.exception("unable to get charge value: {}".format(str(e)))
if charge == "Discharging":
state.append("discharging-{}".format(min([10, 25, 50, 80, 100], key=lambda i: abs(i - capacity))))
state.append(
"discharging-{}".format(
min([10, 25, 50, 80, 100], key=lambda i: abs(i - capacity))
)
)
elif charge == "Unknown":
state.append("unknown-{}".format(min([10, 25, 50, 80, 100], key=lambda i: abs(i - capacity))))
state.append(
"unknown-{}".format(
min([10, 25, 50, 80, 100], key=lambda i: abs(i - capacity))
)
)
else:
if capacity > 95:
state.append("charged")
@ -268,4 +328,5 @@ class Module(core.module.Module):
state.append("charging")
return state
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -15,6 +15,7 @@ Parameters:
import os
import glob
import logging
log = logging.getLogger(__name__)
try:
@ -28,6 +29,7 @@ import core.input
import util.format
class BatteryManager(object):
def remaining(self):
try:
@ -35,26 +37,25 @@ class BatteryManager(object):
# do not show remaining if on AC
if estimate == power.common.TIME_REMAINING_UNLIMITED:
return None
return estimate*60 # return value in seconds
return estimate * 60 # return value in seconds
except Exception as e:
return -1
return -1
def read(self, battery, component, default=None):
path = '/sys/class/power_supply/{}'.format(battery)
path = "/sys/class/power_supply/{}".format(battery)
if not os.path.exists(path):
return default
try:
with open('{}/{}'.format(path, component)) as f:
with open("{}/{}".format(path, component)) as f:
return f.read().strip()
except IOError:
return 'n/a'
return "n/a"
return default
def capacity(self, battery):
capacity = self.read(battery, 'capacity', 100)
if capacity != 'n/a':
capacity = self.read(battery, "capacity", 100)
if capacity != "n/a":
capacity = int(capacity)
return capacity if capacity < 100 else 100
@ -64,37 +65,41 @@ class BatteryManager(object):
full = 0
for battery in batteries:
try:
with open('/sys/class/power_supply/{}/energy_full'.format(battery)) as f:
with open(
"/sys/class/power_supply/{}/energy_full".format(battery)
) as f:
full += int(f.read())
with open('/sys/class/power_supply/{}/energy_now'.format(battery)) as f:
with open("/sys/class/power_supply/{}/energy_now".format(battery)) as f:
now += int(f.read())
except IOError:
return 'n/a'
return int(float(now)/float(full)*100.0)
return "n/a"
return int(float(now) / float(full) * 100.0)
def isac(self, battery):
path = '/sys/class/power_supply/{}'.format(battery)
path = "/sys/class/power_supply/{}".format(battery)
return not os.path.exists(path)
def isac_any(self, batteries):
for battery in batteries:
if self.isac(battery): return True
if self.isac(battery):
return True
return False
def consumption(self, battery):
consumption = self.read(battery, 'power_now', 'n/a')
if consumption == 'n/a':
return 'n/a'
return '{}W'.format(int(consumption)/1000000)
consumption = self.read(battery, "power_now", "n/a")
if consumption == "n/a":
return "n/a"
return "{}W".format(int(consumption) / 1000000)
def charge(self, battery):
return self.read(battery, 'status', 'n/a')
return self.read(battery, "status", "n/a")
def charge_any(self, batteries):
for battery in batteries:
if self.charge(battery) == 'Discharging':
return 'Discharging'
return 'Charged'
if self.charge(battery) == "Discharging":
return "Discharging"
return "Charged"
class Module(core.module.Module):
def __init__(self, config, theme):
@ -103,81 +108,104 @@ class Module(core.module.Module):
self.__manager = BatteryManager()
self._batteries = util.format.aslist(self.parameter('device', 'auto'))
if self._batteries[0] == 'auto':
self._batteries = [ os.path.basename(battery) for battery in glob.glob('/sys/class/power_supply/BAT*') ]
self._batteries = util.format.aslist(self.parameter("device", "auto"))
if self._batteries[0] == "auto":
self._batteries = [
os.path.basename(battery)
for battery in glob.glob("/sys/class/power_supply/BAT*")
]
if len(self._batteries) == 0:
raise Exceptions('no batteries configured/found')
core.input.register(self, button=core.input.LEFT_MOUSE,
cmd='gnome-power-statistics')
raise Exceptions("no batteries configured/found")
core.input.register(
self, button=core.input.LEFT_MOUSE, cmd="gnome-power-statistics"
)
if util.format.asbool(self.parameter('compact-devices', False)):
widget = core.widget.Widget(full_text=self.capacity, name='all-batteries', module=self)
if util.format.asbool(self.parameter("compact-devices", False)):
widget = core.widget.Widget(
full_text=self.capacity, name="all-batteries", module=self
)
widgets.append(widget)
else:
for battery in self._batteries:
log.debug('adding new widget for {}'.format(battery))
widget = core.widget.Widget(full_text=self.capacity, name=battery, module=self)
log.debug("adding new widget for {}".format(battery))
widget = core.widget.Widget(
full_text=self.capacity, name=battery, module=self
)
widgets.append(widget)
for w in self.widgets():
if util.format.asbool(self.parameter('decorate', True)) == False:
widget.set('theme.exclude', 'suffix')
if util.format.asbool(self.parameter("decorate", True)) == False:
widget.set("theme.exclude", "suffix")
def capacity(self, widget):
if widget.name == 'all-batteries':
if widget.name == "all-batteries":
capacity = self.__manager.capacity_all(self._batteries)
else:
capacity = self.__manager.capacity(widget.name)
widget.set('capacity', capacity)
widget.set('ac', self.__manager.isac_any(self._batteries))
widget.set('theme.minwidth', '100%')
widget.set("capacity", capacity)
widget.set("ac", self.__manager.isac_any(self._batteries))
widget.set("theme.minwidth", "100%")
# Read power conumption
if util.format.asbool(self.parameter('showpowerconsumption', False)):
output = '{}% ({})'.format(capacity, self.__manager.consumption(widget.name))
if util.format.asbool(self.parameter("showpowerconsumption", False)):
output = "{}% ({})".format(
capacity, self.__manager.consumption(widget.name)
)
else:
output = '{}%'.format(capacity)
output = "{}%".format(capacity)
if util.format.asbool(self.parameter('showremaining', True))\
and self.__manager.charge(widget.name) == 'Discharging':
if (
util.format.asbool(self.parameter("showremaining", True))
and self.__manager.charge(widget.name) == "Discharging"
):
remaining = self.__manager.remaining()
if remaining >= 0:
output = '{} {}'.format(output, util.format.duration(remaining, compact=True, unit=True))
output = "{} {}".format(
output, util.format.duration(remaining, compact=True, unit=True)
)
if util.format.asbool(self.parameter('showdevice', False)):
output = '{} ({})'.format(output, widget.name)
if util.format.asbool(self.parameter("showdevice", False)):
output = "{} ({})".format(output, widget.name)
return output
def state(self, widget):
state = []
capacity = widget.get('capacity')
capacity = widget.get("capacity")
if capacity < 0:
log.debug('battery state: {}'.format(state))
return ['critical', 'unknown']
log.debug("battery state: {}".format(state))
return ["critical", "unknown"]
if capacity < int(self.parameter('critical', 10)):
state.append('critical')
elif capacity < int(self.parameter('warning', 20)):
state.append('warning')
if capacity < int(self.parameter("critical", 10)):
state.append("critical")
elif capacity < int(self.parameter("warning", 20)):
state.append("warning")
if widget.get('ac'):
state.append('AC')
if widget.get("ac"):
state.append("AC")
else:
if widget.name == 'all-batteries':
if widget.name == "all-batteries":
charge = self.__manager.charge_any(self._batteries)
else:
charge = self.__manager.charge(widget.name)
if charge == 'Discharging':
state.append('discharging-{}'.format(min([10, 25, 50, 80, 100], key=lambda i: abs(i-capacity))))
elif charge == 'Unknown':
state.append('unknown-{}'.format(min([10, 25, 50, 80, 100], key=lambda i: abs(i-capacity))))
if charge == "Discharging":
state.append(
"discharging-{}".format(
min([10, 25, 50, 80, 100], key=lambda i: abs(i - capacity))
)
)
elif charge == "Unknown":
state.append(
"unknown-{}".format(
min([10, 25, 50, 80, 100], key=lambda i: abs(i - capacity))
)
)
else:
if capacity > 95:
state.append('charged')
state.append("charged")
else:
state.append('charging')
state.append("charging")
return state
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -17,27 +17,29 @@ import core.decorators
import util.cli
class Module(core.module.Module):
@core.decorators.every(seconds=30)
def __init__(self, config, theme):
super().__init__(config, theme, core.widget.Widget(self.brightness))
self.__brightness = 'n/a'
self.__brightness = "n/a"
self.__readcmd = None
step = self.parameter('step', 2)
step = self.parameter("step", 2)
if shutil.which('light'):
if shutil.which("light"):
self.__readcmd = self.__light
self.register_cmd('light -A {}%'.format(step),
'light -U {}%'.format(step))
elif shutil.which('brightnessctl'):
self.register_cmd("light -A {}%".format(step), "light -U {}%".format(step))
elif shutil.which("brightnessctl"):
self.__readcmd = self.__brightnessctl
self.register_cmd('brightnessctl s {}%+'.format(step),
'brightnessctl s {}%-'.format(step))
self.register_cmd(
"brightnessctl s {}%+".format(step), "brightnessctl s {}%-".format(step)
)
else:
self.__readcmd = self.__xbacklight
self.register_cmd('xbacklight +{}%'.format(step),
'xbacklight -{}%'.format(step))
self.register_cmd(
"xbacklight +{}%".format(step), "xbacklight -{}%".format(step)
)
def register_cmd(self, up_cmd, down_cmd):
core.input.register(self, button=core.input.WHEEL_UP, cmd=up_cmd)
@ -47,20 +49,21 @@ class Module(core.module.Module):
return self.__brightness
def __light(self):
return util.cli.execute('light').strip()
return util.cli.execute("light").strip()
def __brightnessctl(self):
m = util.cli.execute('brightnessctl m').strip()
g = util.cli.execute('brightnessctl g').strip()
return float(g)/float(m)*100.0
m = util.cli.execute("brightnessctl m").strip()
g = util.cli.execute("brightnessctl g").strip()
return float(g) / float(m) * 100.0
def __xbacklight(self):
return util.cli.execute('xbacklight -get').strip()
return util.cli.execute("xbacklight -get").strip()
def update(self):
try:
self.__brightness = '{:3.0f}%'.format(float(self.__readcmd()))
self.__brightness = "{:3.0f}%".format(float(self.__readcmd()))
except:
self.__brightness = 'n/a'
self.__brightness = "n/a"
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -32,18 +32,21 @@ import core.decorators
import util.cli
import util.format
class Module(core.module.Module):
def __init__(self, config, theme):
super().__init__(config, theme, [])
self._layout = self.parameter('layout', 'cmus.prev cmus.main cmus.next cmus.shuffle cmus.repeat')
self._fmt = self.parameter('format', '{artist} - {title} {position}/{duration}')
self._server = self.parameter('server', None)
self._passwd = self.parameter('passwd', None)
self._layout = self.parameter(
"layout", "cmus.prev cmus.main cmus.next cmus.shuffle cmus.repeat"
)
self._fmt = self.parameter("format", "{artist} - {title} {position}/{duration}")
self._server = self.parameter("server", None)
self._passwd = self.parameter("passwd", None)
self._status = None
self._shuffle = False
self._repeat = False
self._tags = defaultdict(lambda: '')
self._tags = defaultdict(lambda: "")
# Create widgets
widget_list = []
@ -51,25 +54,48 @@ class Module(core.module.Module):
for widget_name in self._layout.split():
widget = core.widget.Widget(name=widget_name, module=self)
widget_list.append(widget)
self._cmd = 'cmus-remote'
self._cmd = "cmus-remote"
if self._server is not None:
self._cmd = '{cmd} --server {server}'.format(cmd=self._cmd, server=self._server)
self._cmd = "{cmd} --server {server}".format(
cmd=self._cmd, server=self._server
)
if self._passwd is not None:
self._cmd = '{cmd} --passwd {passwd}'.format(cmd=self._cmd, passwd=self._passwd)
self._cmd = "{cmd} --passwd {passwd}".format(
cmd=self._cmd, passwd=self._passwd
)
if widget_name == 'cmus.prev':
widget_map[widget] = {'button': core.input.LEFT_MOUSE, 'cmd': '{cmd} -r'.format(cmd=self._cmd)}
elif widget_name == 'cmus.main':
widget_map[widget] = {'button': core.input.LEFT_MOUSE, 'cmd': '{cmd} -u'.format(cmd=self._cmd)}
if widget_name == "cmus.prev":
widget_map[widget] = {
"button": core.input.LEFT_MOUSE,
"cmd": "{cmd} -r".format(cmd=self._cmd),
}
elif widget_name == "cmus.main":
widget_map[widget] = {
"button": core.input.LEFT_MOUSE,
"cmd": "{cmd} -u".format(cmd=self._cmd),
}
widget.full_text(self.description)
elif widget_name == 'cmus.next':
widget_map[widget] = {'button': core.input.LEFT_MOUSE, 'cmd': '{cmd} -n'.format(cmd=self._cmd)}
elif widget_name == 'cmus.shuffle':
widget_map[widget] = {'button': core.input.LEFT_MOUSE, 'cmd': '{cmd} -S'.format(cmd=self._cmd)}
elif widget_name == 'cmus.repeat':
widget_map[widget] = {'button': core.input.LEFT_MOUSE, 'cmd': '{cmd} -R'.format(cmd=self._cmd)}
elif widget_name == "cmus.next":
widget_map[widget] = {
"button": core.input.LEFT_MOUSE,
"cmd": "{cmd} -n".format(cmd=self._cmd),
}
elif widget_name == "cmus.shuffle":
widget_map[widget] = {
"button": core.input.LEFT_MOUSE,
"cmd": "{cmd} -S".format(cmd=self._cmd),
}
elif widget_name == "cmus.repeat":
widget_map[widget] = {
"button": core.input.LEFT_MOUSE,
"cmd": "{cmd} -R".format(cmd=self._cmd),
}
else:
raise KeyError('The cmus module does not support a {widget_name!r} widget'.format(widget_name=widget_name))
raise KeyError(
"The cmus module does not support a {widget_name!r} widget".format(
widget_name=widget_name
)
)
self.widgets(widget_list)
# Register input callbacks
@ -88,44 +114,45 @@ class Module(core.module.Module):
def state(self, widget):
returns = {
'cmus.shuffle': 'shuffle-on' if self._shuffle else 'shuffle-off',
'cmus.repeat': 'repeat-on' if self._repeat else 'repeat-off',
'cmus.prev': 'prev',
'cmus.next': 'next',
"cmus.shuffle": "shuffle-on" if self._shuffle else "shuffle-off",
"cmus.repeat": "repeat-on" if self._repeat else "repeat-off",
"cmus.prev": "prev",
"cmus.next": "next",
}
return returns.get(widget.name, self._status)
def _eval_line(self, line):
if line.startswith('file '):
if line.startswith("file "):
full_file = line[5:]
file1 = os.path.basename(full_file)
file2 = os.path.splitext(file1)[0]
self._tags.update({'file': full_file})
self._tags.update({'file1': file1})
self._tags.update({'file2': file2})
self._tags.update({"file": full_file})
self._tags.update({"file1": file1})
self._tags.update({"file2": file2})
return
name, key, value = (line.split(' ', 2) + [None, None])[:3]
name, key, value = (line.split(" ", 2) + [None, None])[:3]
if name == 'status':
if name == "status":
self._status = key
if name == 'tag':
if name == "tag":
self._tags.update({key: value})
if name in ['duration', 'position']:
if name in ["duration", "position"]:
self._tags.update({name: util.format.duration(int(key))})
if name == 'set' and key == 'repeat':
self._repeat = value == 'true'
if name == 'set' and key == 'shuffle':
self._shuffle = value == 'true'
if name == "set" and key == "repeat":
self._repeat = value == "true"
if name == "set" and key == "shuffle":
self._shuffle = value == "true"
def _load_song(self):
info = ''
info = ""
try:
info = util.cli.execute('{cmd} -Q'.format(cmd=self._cmd))
info = util.cli.execute("{cmd} -Q".format(cmd=self._cmd))
except RuntimeError:
self._status = None
self._tags = defaultdict(lambda: '')
for line in info.split('\n'):
self._tags = defaultdict(lambda: "")
for line in info.split("\n"):
self._eval_line(line)
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,12 +1,12 @@
# pylint: disable=C0111,R0903
'''Displays CPU utilization across all CPUs.
"""Displays CPU utilization across all CPUs.
Parameters:
* cpu.warning : Warning threshold in % of CPU usage (defaults to 70%)
* cpu.critical: Critical threshold in % of CPU usage (defaults to 80%)
* cpu.format : Format string (defaults to '{:.01f}%')
'''
"""
import psutil
@ -14,17 +14,19 @@ import core.module
import core.widget
import core.input
class Module(core.module.Module):
def __init__(self, config, theme):
super().__init__(config, theme, core.widget.Widget(self.utilization))
self.widget().set('theme.minwidth', self._format.format(100.0-10e-20))
self.widget().set("theme.minwidth", self._format.format(100.0 - 10e-20))
self._utilization = psutil.cpu_percent(percpu=False)
core.input.register(self, button=core.input.LEFT_MOUSE,
cmd='gnome-system-monitor')
core.input.register(
self, button=core.input.LEFT_MOUSE, cmd="gnome-system-monitor"
)
@property
def _format(self):
return self.parameter('format', '{:.01f}%')
return self.parameter("format", "{:.01f}%")
def utilization(self, _):
return self._format.format(self._utilization)
@ -35,4 +37,5 @@ class Module(core.module.Module):
def state(self, _):
return self.threshold_state(self._utilization, 70, 80)
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -10,12 +10,14 @@ Parameters:
import core.decorators
from .datetime import Module
class Module(Module):
@core.decorators.every(hours=1)
def __init__(self, config, theme):
super().__init__(config, theme)
def default_format(self):
return '%x'
return "%x"
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,11 +1,11 @@
# pylint: disable=C0111,R0903
'''Displays the current date and time.
"""Displays the current date and time.
Parameters:
* datetime.format: strftime()-compatible formatting string
* datetime.locale: locale to use rather than the system default
'''
"""
from __future__ import absolute_import
import datetime
@ -15,29 +15,31 @@ import core.module
import core.widget
import core.input
class Module(core.module.Module):
def __init__(self, config, theme):
super().__init__(config, theme, core.widget.Widget(self.full_text))
core.input.register(self, button=core.input.LEFT_MOUSE, cmd='calendar')
self._fmt = self.parameter('format', self.default_format())
core.input.register(self, button=core.input.LEFT_MOUSE, cmd="calendar")
self._fmt = self.parameter("format", self.default_format())
l = locale.getdefaultlocale()
if not l or l == (None, None):
l = ('en_US', 'UTF-8')
lcl = self.parameter('locale', '.'.join(l))
l = ("en_US", "UTF-8")
lcl = self.parameter("locale", ".".join(l))
try:
locale.setlocale(locale.LC_TIME, lcl.split('.'))
locale.setlocale(locale.LC_TIME, lcl.split("."))
except Exception as e:
locale.setlocale(locale.LC_TIME, ('en_US', 'UTF-8'))
locale.setlocale(locale.LC_TIME, ("en_US", "UTF-8"))
def default_format(self):
return '%x %X'
return "%x %X"
def full_text(self, widget):
enc = locale.getpreferredencoding()
retval = datetime.datetime.now().strftime(self._fmt)
if hasattr(retval, 'decode'):
if hasattr(retval, "decode"):
return retval.decode(enc)
return retval
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -8,15 +8,17 @@ import core.module
import core.widget
import core.decorators
class Module(core.module.Module):
@core.decorators.every(minutes=60)
def __init__(self, config, theme):
super().__init__(config, theme, core.widget.Widget(self.full_text))
def full_text(self, widgets):
return 'debug'
return "debug"
def state(self, widget):
return 'warning'
return "warning"
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,6 +1,6 @@
# pylint: disable=C0111,R0903
'''Shows free diskspace, total diskspace and the percentage of free disk space.
"""Shows free diskspace, total diskspace and the percentage of free disk space.
Parameters:
* disk.warning: Warning threshold in % of disk space (defaults to 80%)
@ -8,7 +8,7 @@ Parameters:
* disk.path: Path to calculate disk usage from (defaults to /)
* disk.open: Which application / file manager to launch (default xdg-open)
* disk.format: Format string, tags {path}, {used}, {left}, {size} and {percent} (defaults to '{path} {used}/{size} ({percent:05.02f}%)')
'''
"""
import os
@ -18,20 +18,24 @@ import core.input
import util.format
class Module(core.module.Module):
def __init__(self, config, theme):
super().__init__(config, theme, core.widget.Widget(self.diskspace))
self._path = self.parameter('path', '/')
self._format = self.parameter('format', '{used}/{size} ({percent:05.02f}%)')
self._path = self.parameter("path", "/")
self._format = self.parameter("format", "{used}/{size} ({percent:05.02f}%)")
self._used = 0
self._left = 0
self._size = 0
self._percent = 0
core.input.register(self, button=core.input.LEFT_MOUSE,
cmd='{} {}'.format(self.parameter('open', 'xdg-open'), self._path))
core.input.register(
self,
button=core.input.LEFT_MOUSE,
cmd="{} {}".format(self.parameter("open", "xdg-open"), self._path),
)
def diskspace(self, widget):
used_str = util.format.byte(self._used)
@ -39,20 +43,23 @@ class Module(core.module.Module):
left_str = util.format.byte(self._left)
percent_str = self._percent
return self._format.format(path=self._path,
used=used_str,
left=left_str,
size=size_str,
percent=percent_str)
return self._format.format(
path=self._path,
used=used_str,
left=left_str,
size=size_str,
percent=percent_str,
)
def update(self):
st = os.statvfs(self._path)
self._size = st.f_blocks * st.f_frsize
self._used = (st.f_blocks - st.f_bfree) * st.f_frsize
self._left = self._size - self._used;
self._percent = 100.0 * self._used/self._size
self._left = self._size - self._used
self._percent = 100.0 * self._used / self._size
def state(self, widget):
return self.threshold_state(self._percent, 80, 90)
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -8,23 +8,26 @@ import core.module
import core.widget
import core.event
class Module(core.module.Module):
def __init__(self, config, theme):
super().__init__(config, theme, core.widget.Widget(self.full_text))
self.__error = ''
self.__state = 'critical'
self.__error = ""
self.__state = "critical"
core.event.register('error', self.__set_error)
core.event.register("error", self.__set_error)
def full_text(self, widgets):
return self.__error
def __set_error(self, error='n/a', state='critical'):
def __set_error(self, error="n/a", state="critical"):
self.__error = error
self.__state = state
def state(self, widget):
if self.__error: return [self.__state]
if self.__error:
return [self.__state]
return []
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -16,6 +16,7 @@ import core.widget
import util.cli
class Module(core.module.Module):
def __init__(self, config, theme):
super().__init__(config, theme, [])
@ -33,40 +34,49 @@ class Module(core.module.Module):
directory = self.__get_git_root(directory)
repo = pygit2.Repository(directory)
new_widgets.append(core.widget.Widget(name='git.main', full_text=repo.head.shorthand))
new_widgets.append(
core.widget.Widget(name="git.main", full_text=repo.head.shorthand)
)
for filepath, flags in repo.status().items():
if flags == pygit2.GIT_STATUS_WT_NEW or \
flags == pygit2.GIT_STATUS_INDEX_NEW:
state['new'] = True
if flags == pygit2.GIT_STATUS_WT_DELETED or \
flags == pygit2.GIT_STATUS_INDEX_DELETED:
state['deleted'] = True
if flags == pygit2.GIT_STATUS_WT_MODIFIED or \
flags == pygit2.GIT_STATUS_INDEX_MODIFIED:
state['modified'] = True
if (
flags == pygit2.GIT_STATUS_WT_NEW
or flags == pygit2.GIT_STATUS_INDEX_NEW
):
state["new"] = True
if (
flags == pygit2.GIT_STATUS_WT_DELETED
or flags == pygit2.GIT_STATUS_INDEX_DELETED
):
state["deleted"] = True
if (
flags == pygit2.GIT_STATUS_WT_MODIFIED
or flags == pygit2.GIT_STATUS_INDEX_MODIFIED
):
state["modified"] = True
self.__error = False
if 'new' in state:
new_widgets.append(core.widget.Widget(name='git.new'))
if 'modified' in state:
new_widgets.append(core.widget.Widget(name='git.modified'))
if 'deleted' in state:
new_widgets.append(core.widget.Widget(name='git.deleted'))
if "new" in state:
new_widgets.append(core.widget.Widget(name="git.new"))
if "modified" in state:
new_widgets.append(core.widget.Widget(name="git.modified"))
if "deleted" in state:
new_widgets.append(core.widget.Widget(name="git.deleted"))
self.widgets().clear()
self.widget(new_widgets)
except Exception as e:
self.__error = True
def state(self, widget):
return widget.name.split('.')[1]
return widget.name.split(".")[1]
def __get_git_root(self, directory):
while len(directory) > 1:
if os.path.exists(os.path.join(directory, ".git")):
return directory
directory = "/".join(directory.split("/")[0:-1])
return "/"
return "/"
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -8,6 +8,7 @@ import core.module
import core.widget
import core.decorators
class Module(core.module.Module):
@core.decorators.every(minutes=60)
def __init__(self, config, theme):
@ -16,4 +17,5 @@ class Module(core.module.Module):
def full_text(self, widgets):
return platform.release()
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -15,6 +15,7 @@ Parameters:
from xkbgroup import *
import logging
log = logging.getLogger(__name__)
import core.module
@ -23,15 +24,14 @@ import core.input
import util.format
class Module(core.module.Module):
def __init__(self, config, theme):
super().__init__(config, theme, core.widget.Widget(self.current_layout))
core.input.register(self, button=core.input.LEFT_MOUSE,
cmd=self.__next_keymap)
core.input.register(self, button=core.input.RIGHT_MOUSE,
cmd=self.__prev_keymap)
self.__show_variant = util.format.asbool(self.parameter('show_variant', True))
core.input.register(self, button=core.input.LEFT_MOUSE, cmd=self.__next_keymap)
core.input.register(self, button=core.input.RIGHT_MOUSE, cmd=self.__prev_keymap)
self.__show_variant = util.format.asbool(self.parameter("show_variant", True))
def __next_keymap(self, event):
self.__set_keymap(1)
@ -41,7 +41,8 @@ class Module(core.module.Module):
def __set_keymap(self, rotation):
xkb = XKeyboard()
if xkb.groups_count < 2: return # nothing to do
if xkb.groups_count < 2:
return # nothing to do
layouts = xkb.groups_symbols
idx = layouts.index(xkb.group_symbol)
xkb.group_symbol = str(layouts[(idx + rotation) % len(layouts)])
@ -49,13 +50,22 @@ class Module(core.module.Module):
def current_layout(self, widget):
try:
xkb = XKeyboard()
log.debug('group num: {}'.format(xkb.group_num))
name = xkb.group_name if util.format.asbool(self.parameter('showname'), False) else xkb.group_symbol
log.debug("group num: {}".format(xkb.group_num))
name = (
xkb.group_name
if util.format.asbool(self.parameter("showname"), False)
else xkb.group_symbol
)
if self.__show_variant:
return '{} ({})'.format(name, xkb.group_variant) if xkb.group_variant else name
return (
"{} ({})".format(name, xkb.group_variant)
if xkb.group_variant
else name
)
return name
except Exception as e:
print('got exception: {}'.format(e))
return 'n/a'
print("got exception: {}".format(e))
return "n/a"
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,11 +1,11 @@
# pylint: disable=C0111,R0903
'''Displays system load.
"""Displays system load.
Parameters:
* load.warning : Warning threshold for the one-minute load average (defaults to 70% of the number of CPUs)
* load.critical: Critical threshold for the one-minute load average (defaults to 80% of the number of CPUs)
'''
"""
import os
import multiprocessing
@ -13,6 +13,7 @@ import multiprocessing
import core.module
import core.input
class Module(core.module.Module):
def __init__(self, config, theme):
super().__init__(config, theme, core.widget.Widget(self.load))
@ -21,11 +22,12 @@ class Module(core.module.Module):
self._cpus = multiprocessing.cpu_count()
except NotImplementedError as e:
self._cpus = 1
core.input.register(self, button=core.input.LEFT_MOUSE,
cmd='gnome-system-monitor')
core.input.register(
self, button=core.input.LEFT_MOUSE, cmd="gnome-system-monitor"
)
def load(self, widget):
return '{:.02f}/{:.02f}/{:.02f}'.format(
return "{:.02f}/{:.02f}/{:.02f}".format(
self._load[0], self._load[1], self._load[2]
)
@ -33,6 +35,7 @@ class Module(core.module.Module):
self._load = os.getloadavg()
def state(self, widget):
return self.threshold_state(self._load[0], self._cpus*0.7, self._cpus*0.8)
return self.threshold_state(self._load[0], self._cpus * 0.7, self._cpus * 0.8)
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,13 +1,13 @@
# pylint: disable=C0111,R0903
'''Displays available RAM, total amount of RAM and percentage available.
"""Displays available RAM, total amount of RAM and percentage available.
Parameters:
* memory.warning : Warning threshold in % of memory used (defaults to 80%)
* memory.critical: Critical threshold in % of memory used (defaults to 90%)
* memory.format: Format string (defaults to '{used}/{total} ({percent:05.02f}%)')
* memory.usedonly: Only show the amount of RAM in use (defaults to False). Same as memory.format='{used}'
'''
"""
import re
@ -17,49 +17,61 @@ import core.input
import util.format
class Module(core.module.Module):
def __init__(self, config, theme):
super().__init__(config, theme, core.widget.Widget(self.memory_usage))
core.input.register(self, button=core.input.LEFT_MOUSE,
cmd='gnome-system-monitor')
core.input.register(
self, button=core.input.LEFT_MOUSE, cmd="gnome-system-monitor"
)
@property
def _format(self):
if util.format.asbool(self.parameter('usedonly', False)):
return '{used}'
if util.format.asbool(self.parameter("usedonly", False)):
return "{used}"
else:
return self.parameter('format', '{used}/{total} ({percent:05.02f}%)')
return self.parameter("format", "{used}/{total} ({percent:05.02f}%)")
def memory_usage(self, widget):
return self._format.format(**self._mem)
def update(self):
data = {}
with open('/proc/meminfo', 'r') as f:
with open("/proc/meminfo", "r") as f:
for line in f:
tmp = re.split(r'[:\s]+', line)
tmp = re.split(r"[:\s]+", line)
value = int(tmp[1])
if tmp[2] == 'kB': value = value*1024
if tmp[2] == 'mB': value = value*1024*1024
if tmp[2] == 'gB': value = value*1024*1024*1024
if tmp[2] == "kB":
value = value * 1024
if tmp[2] == "mB":
value = value * 1024 * 1024
if tmp[2] == "gB":
value = value * 1024 * 1024 * 1024
data[tmp[0]] = value
if 'MemAvailable' in data:
used = data['MemTotal'] - data['MemAvailable']
if "MemAvailable" in data:
used = data["MemTotal"] - data["MemAvailable"]
else:
used = data['MemTotal'] - data['MemFree'] - data['Buffers'] - data['Cached'] - data['Slab']
used = (
data["MemTotal"]
- data["MemFree"]
- data["Buffers"]
- data["Cached"]
- data["Slab"]
)
self._mem = {
'total': util.format.byte(data['MemTotal']),
'available': util.format.byte(data['MemAvailable']),
'free': util.format.byte(data['MemFree']),
'used': util.format.byte(used),
'percent': float(used)/float(data['MemTotal'])*100.0
"total": util.format.byte(data["MemTotal"]),
"available": util.format.byte(data["MemAvailable"]),
"free": util.format.byte(data["MemFree"]),
"used": util.format.byte(used),
"percent": float(used) / float(data["MemTotal"]) * 100.0,
}
def state(self, widget):
if self._mem['percent'] > float(self.parameter('critical', 90)):
return 'critical'
if self._mem['percent'] > float(self.parameter('warning', 80)):
return 'warning'
if self._mem["percent"] > float(self.parameter("critical", 90)):
return "critical"
if self._mem["percent"] > float(self.parameter("warning", 80)):
return "warning"
return None
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,4 +1,4 @@
#pylint: disable=C0111,R0903
# pylint: disable=C0111,R0903
"""Displays the name, IP address(es) and status of each available network interface.
@ -22,22 +22,30 @@ import core.decorators
import util.cli
import util.format
class Module(core.module.Module):
@core.decorators.every(seconds=10)
def __init__(self, config, theme):
widgets = []
super().__init__(config, theme, widgets)
self._exclude = tuple(filter(len, self.parameter('exclude', 'lo,virbr,docker,vboxnet,veth,br').split(',')))
self._include = self.parameter('include', '').split(',')
self._exclude = tuple(
filter(
len,
self.parameter("exclude", "lo,virbr,docker,vboxnet,veth,br").split(","),
)
)
self._include = self.parameter("include", "").split(",")
self._states = { 'include': [], 'exclude': [] }
for state in tuple(filter(len, util.format.aslist(self.parameter('states', '')))):
if state[0] == '^':
self._states['exclude'].append(state[1:])
self._states = {"include": [], "exclude": []}
for state in tuple(
filter(len, util.format.aslist(self.parameter("states", "")))
):
if state[0] == "^":
self._states["exclude"].append(state[1:])
else:
self._states['include'].append(state)
self._format = self.parameter('format','{intf} {state} {ip} {ssid}');
self.iwgetid = shutil.which('iwgetid')
self._states["include"].append(state)
self._format = self.parameter("format", "{intf} {state} {ip} {ssid}")
self.iwgetid = shutil.which("iwgetid")
self._update_widgets(widgets)
def update(self):
@ -46,71 +54,91 @@ class Module(core.module.Module):
def state(self, widget):
states = []
if widget.get('state') == 'down':
states.append('critical')
elif widget.get('state') != 'up':
states.append('warning')
if widget.get("state") == "down":
states.append("critical")
elif widget.get("state") != "up":
states.append("warning")
intf = widget.get('intf')
iftype = 'wireless' if self._iswlan(intf) else 'wired'
iftype = 'tunnel' if self._istunnel(intf) else iftype
intf = widget.get("intf")
iftype = "wireless" if self._iswlan(intf) else "wired"
iftype = "tunnel" if self._istunnel(intf) else iftype
states.append('{}-{}'.format(iftype, widget.get('state')))
states.append("{}-{}".format(iftype, widget.get("state")))
return states
def _iswlan(self, intf):
# wifi, wlan, wlp, seems to work for me
if intf.startswith('w'): return True
if intf.startswith("w"):
return True
return False
def _istunnel(self, intf):
return intf.startswith('tun') or intf.startswith('wg')
return intf.startswith("tun") or intf.startswith("wg")
def get_addresses(self, intf):
retval = []
try:
for ip in netifaces.ifaddresses(intf).get(netifaces.AF_INET, []):
if ip.get('addr', '') != '':
retval.append(ip.get('addr'))
if ip.get("addr", "") != "":
retval.append(ip.get("addr"))
except Exception:
return []
return retval
def _update_widgets(self, widgets):
interfaces = [i for i in netifaces.interfaces() if not i.startswith(self._exclude)]
interfaces = [
i for i in netifaces.interfaces() if not i.startswith(self._exclude)
]
interfaces.extend([i for i in netifaces.interfaces() if i in self._include])
for widget in widgets:
widget.set('visited', False)
widget.set("visited", False)
for intf in interfaces:
addr = []
state = 'down'
state = "down"
for ip in self.get_addresses(intf):
addr.append(ip)
state = 'up'
state = "up"
if len(self._states['exclude']) > 0 and state in self._states['exclude']: continue
if len(self._states['include']) > 0 and state not in self._states['include']: continue
if len(self._states["exclude"]) > 0 and state in self._states["exclude"]:
continue
if (
len(self._states["include"]) > 0
and state not in self._states["include"]
):
continue
widget = self.widget(intf)
if not widget:
widget = core.widget.Widget(name=intf, module=self)
widgets.append(widget)
# join/split is used to get rid of multiple whitespaces (in case SSID is not available, for instance
widget.full_text(' '.join(self._format.format(ip=', '.join(addr),intf=intf,state=state,ssid=self.get_ssid(intf)).split()))
widget.set('intf', intf)
widget.set('state', state)
widget.set('visited', True)
widget.full_text(
" ".join(
self._format.format(
ip=", ".join(addr),
intf=intf,
state=state,
ssid=self.get_ssid(intf),
).split()
)
)
widget.set("intf", intf)
widget.set("state", state)
widget.set("visited", True)
for widget in widgets:
if widget.get('visited') is False:
if widget.get("visited") is False:
widgets.remove(widget)
def get_ssid(self, intf):
if self._iswlan(intf) and self.iwgetid:
return util.cli.execute('{} -r {}'.format(self.iwgetid, intf), ignore_errors=True)
return ''
return util.cli.execute(
"{} -r {}".format(self.iwgetid, intf), ignore_errors=True
)
return ""
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,7 +1,9 @@
from .__pulseaudio import Module
class Module(Module):
def __init__(self, config, theme):
super().__init__(config, theme, 'sink')
super().__init__(config, theme, "sink")
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,7 +1,9 @@
from .__pulseaudio import Module
class Module(Module):
def __init__(self, config, theme):
super().__init__(config, theme, 'source')
super().__init__(config, theme, "source")
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -24,30 +24,39 @@ import core.decorators
import util.cli
def get_rtt(module, widget):
try:
widget.set('rtt-unreachable', False)
res = util.cli.execute('ping -n -q -c {} -W {} {}'.format(
widget.get('rtt-probes'), widget.get('rtt-timeout'), widget.get('address')
))
widget.set("rtt-unreachable", False)
res = util.cli.execute(
"ping -n -q -c {} -W {} {}".format(
widget.get("rtt-probes"),
widget.get("rtt-timeout"),
widget.get("address"),
)
)
for line in res.split('\n'):
if line.startswith('{} packets transmitted'.format(widget.get('rtt-probes'))):
m = re.search(r'(\d+)% packet loss', line)
for line in res.split("\n"):
if line.startswith(
"{} packets transmitted".format(widget.get("rtt-probes"))
):
m = re.search(r"(\d+)% packet loss", line)
widget.set('packet-loss', m.group(1))
widget.set("packet-loss", m.group(1))
if not line.startswith('rtt'): continue
m = re.search(r'([0-9\.]+)/([0-9\.]+)/([0-9\.]+)/([0-9\.]+)\s+(\S+)', line)
if not line.startswith("rtt"):
continue
m = re.search(r"([0-9\.]+)/([0-9\.]+)/([0-9\.]+)/([0-9\.]+)\s+(\S+)", line)
widget.set('rtt-min', float(m.group(1)))
widget.set('rtt-avg', float(m.group(2)))
widget.set('rtt-max', float(m.group(3)))
widget.set('rtt-unit', m.group(5))
widget.set("rtt-min", float(m.group(1)))
widget.set("rtt-avg", float(m.group(2)))
widget.set("rtt-max", float(m.group(3)))
widget.set("rtt-unit", m.group(5))
except Exception as e:
widget.set('rtt-unreachable', True)
widget.set("rtt-unreachable", True)
core.event.trigger("update", [module.id], redraw_only=True)
core.event.trigger('update', [ module.id ], redraw_only=True)
class Module(core.module.Module):
@core.decorators.every(seconds=60)
@ -56,29 +65,31 @@ class Module(core.module.Module):
widget = self.widget()
widget.set('address', self.parameter('address', '8.8.8.8'))
widget.set('rtt-probes', self.parameter('probes', 5))
widget.set('rtt-timeout', self.parameter('timeout', 5.0))
widget.set('rtt-avg', 0.0)
widget.set('rtt-unit', '')
widget.set('packet-loss', 0)
widget.set("address", self.parameter("address", "8.8.8.8"))
widget.set("rtt-probes", self.parameter("probes", 5))
widget.set("rtt-timeout", self.parameter("timeout", 5.0))
widget.set("rtt-avg", 0.0)
widget.set("rtt-unit", "")
widget.set("packet-loss", 0)
def rtt(self, widget):
if widget.get('rtt-unreachable'):
return '{}: unreachable'.format(widget.get('address'))
return '{}: {:.1f}{} ({}%)'.format(
widget.get('address'),
widget.get('rtt-avg'),
widget.get('rtt-unit'),
widget.get('packet-loss')
if widget.get("rtt-unreachable"):
return "{}: unreachable".format(widget.get("address"))
return "{}: {:.1f}{} ({}%)".format(
widget.get("address"),
widget.get("rtt-avg"),
widget.get("rtt-unit"),
widget.get("packet-loss"),
)
def state(self, widget):
if widget.get('rtt-unreachable'): return ['critical']
return self.threshold_state(widget.get('rtt-avg'), 1000.0, 2000.0)
if widget.get("rtt-unreachable"):
return ["critical"]
return self.threshold_state(widget.get("rtt-avg"), 1000.0, 2000.0)
def update(self):
thread = threading.Thread(target=get_rtt, args=(self, self.widget(),))
thread.start()
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -24,45 +24,49 @@ import core.decorators
import util.cli
import util.location
def get_redshift_value(module):
widget = module.widget()
location = module.parameter('location', 'auto')
lat = module.parameter('lat', None)
lon = module.parameter('lon', None)
location = module.parameter("location", "auto")
lat = module.parameter("lat", None)
lon = module.parameter("lon", None)
# Even if location method is set to manual, if we have no lat or lon,
# fall back to the geoclue2 method.
if location == 'manual' and (lat is None or lon is None):
location = 'geoclue2'
if location == "manual" and (lat is None or lon is None):
location = "geoclue2"
command = ['redshift', '-p']
if location == 'manual':
command.extend(['-l', '{}:{}'.format(lat, lon)])
if location == 'geoclue2':
command.extend(['-l', 'geoclue2'])
command = ["redshift", "-p"]
if location == "manual":
command.extend(["-l", "{}:{}".format(lat, lon)])
if location == "geoclue2":
command.extend(["-l", "geoclue2"])
try:
res = util.cli.execute(' '.join(command))
res = util.cli.execute(" ".join(command))
except Exception:
res = ''
widget.set('temp', 'n/a')
widget.set('transition', '')
widget.set('state', 'day')
for line in res.split('\n'):
res = ""
widget.set("temp", "n/a")
widget.set("transition", "")
widget.set("state", "day")
for line in res.split("\n"):
line = line.lower()
if 'temperature' in line:
widget.set('temp', line.split(' ')[2])
if 'period' in line:
state = line.split(' ')[1]
if 'day' in state:
widget.set('state', 'day')
elif 'night' in state:
widget.set('state', 'night')
if "temperature" in line:
widget.set("temp", line.split(" ")[2])
if "period" in line:
state = line.split(" ")[1]
if "day" in state:
widget.set("state", "day")
elif "night" in state:
widget.set("state", "night")
else:
widget.set('state', 'transition')
match = re.search(r'(\d+)\.\d+% ([a-z]+)', line)
widget.set('transition', '({}% {})'.format(match.group(1), match.group(2)))
core.event.trigger('update', [ widget.module.id ], redraw_only=True)
widget.set("state", "transition")
match = re.search(r"(\d+)\.\d+% ([a-z]+)", line)
widget.set(
"transition", "({}% {})".format(match.group(1), match.group(2))
)
core.event.trigger("update", [widget.module.id], redraw_only=True)
class Module(core.module.Module):
@core.decorators.every(seconds=10)
@ -71,24 +75,24 @@ class Module(core.module.Module):
self.__thread = None
if self.parameter('location', '') == 'ipinfo':
if self.parameter("location", "") == "ipinfo":
# override lon/lat with ipinfo
try:
location = util.location.coordinates()
self.set('lat', location[0])
self.set('lon', location[1])
self.set('location', 'manual')
self.set("lat", location[0])
self.set("lon", location[1])
self.set("location", "manual")
except Exception:
# Fall back to geoclue2.
self.set('location', 'geoclue2')
self.set("location", "geoclue2")
self._text = ''
self._text = ""
def text(self, widget):
val = widget.get('temp', 'n/a')
transition = widget.get('transition', '')
val = widget.get("temp", "n/a")
transition = widget.get("transition", "")
if transition:
val = '{} {}'.format(val, transition)
val = "{} {}".format(val, transition)
return val
def update(self):
@ -98,6 +102,7 @@ class Module(core.module.Module):
self.__thread.start()
def state(self, widget):
return widget.get('state', None)
return widget.get("state", None)
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -26,11 +26,12 @@ import core.widget
import util.cli
import util.format
class Module(core.module.Module):
def __init__(self, config, theme):
super().__init__(config, theme, [])
self.__chip = self.parameter('chip', '')
self.__chip = self.parameter("chip", "")
self.__data = {}
self.__update()
@ -42,31 +43,45 @@ class Module(core.module.Module):
self.__update_widget(widget)
def state(self, widget):
widget_type = widget.get('type', '')
widget_type = widget.get("type", "")
try:
data = self.__data[widget.get('adapter')][widget.get('package')][widget.get('field')]
if 'crit' in data and float(data['input']) > float(data['crit']):
return ['critical', widget_type]
if 'max' in data and float(data['input']) > float(data['max']):
return ['warning', widget_type]
data = self.__data[widget.get("adapter")][widget.get("package")][
widget.get("field")
]
if "crit" in data and float(data["input"]) > float(data["crit"]):
return ["critical", widget_type]
if "max" in data and float(data["input"]) > float(data["max"]):
return ["warning", widget_type]
except:
pass
return [widget_type]
def __create_widgets(self):
show_temp = util.format.asbool(self.parameter('showtemp', True))
show_fan = util.format.asbool(self.parameter('showfan', True))
show_other = util.format.asbool(self.parameter('showother', False))
include_chip = tuple(filter(len, util.format.aslist(self.parameter('chip_include', ''))))
exclude_chip = tuple(filter(len, util.format.aslist(self.parameter('chip_exclude', ''))))
include_field = tuple(filter(len, util.format.aslist(self.parameter('field_include', ''))))
exclude_field = tuple(filter(len, util.format.aslist(self.parameter('field_exclude', ''))))
include_chip_field = tuple(filter(len, util.format.aslist(self.parameter('chip_field_include', ''))))
exclude_chip_field = tuple(filter(len, util.format.aslist(self.parameter('chip_field_exclude', ''))))
show_temp = util.format.asbool(self.parameter("showtemp", True))
show_fan = util.format.asbool(self.parameter("showfan", True))
show_other = util.format.asbool(self.parameter("showother", False))
include_chip = tuple(
filter(len, util.format.aslist(self.parameter("chip_include", "")))
)
exclude_chip = tuple(
filter(len, util.format.aslist(self.parameter("chip_exclude", "")))
)
include_field = tuple(
filter(len, util.format.aslist(self.parameter("field_include", "")))
)
exclude_field = tuple(
filter(len, util.format.aslist(self.parameter("field_exclude", "")))
)
include_chip_field = tuple(
filter(len, util.format.aslist(self.parameter("chip_field_include", "")))
)
exclude_chip_field = tuple(
filter(len, util.format.aslist(self.parameter("chip_field_exclude", "")))
)
if util.format.asbool(self.parameter('showcpu', True)):
if util.format.asbool(self.parameter("showcpu", True)):
widget = self.add_widget(full_text=self.__cpu)
widget.set('type', 'cpu')
widget.set("type", "cpu")
for adapter in self.__data:
if include_chip or exclude_chip:
@ -79,23 +94,27 @@ class Module(core.module.Module):
if include_chip_field:
try:
if all([i.split('.')[0] not in adapter for i in include_chip_field]):
if all(
[i.split(".")[0] not in adapter for i in include_chip_field]
):
continue
except:
pass
for package in self.__data[adapter]:
if util.format.asbool(self.parameter('showname', False)):
if util.format.asbool(self.parameter("showname", False)):
widget = self.add_widget(full_text=package)
widget.set('data', self.__data[adapter][package])
widget.set('package', package)
widget.set('field', '')
widget.set('adapter', adapter)
widget.set("data", self.__data[adapter][package])
widget.set("package", package)
widget.set("field", "")
widget.set("adapter", adapter)
for field in self.__data[adapter][package]:
if include_field or exclude_field:
if include_field:
if all([included not in field for included in include_field]):
if all(
[included not in field for included in include_field]
):
continue
else:
if any([excluded in field for excluded in exclude_field]):
@ -104,62 +123,79 @@ class Module(core.module.Module):
try:
if include_chip_field or exclude_chip_field:
if include_chip_field:
if all([i.split('.')[1] not in field for i in include_chip_field if i.split('.')[0] in adapter]):
if all(
[
i.split(".")[1] not in field
for i in include_chip_field
if i.split(".")[0] in adapter
]
):
continue
else:
if any([i.split('.')[1] in field for i in exclude_chip_field if i.split('.')[0] in adapter]):
if any(
[
i.split(".")[1] in field
for i in exclude_chip_field
if i.split(".")[0] in adapter
]
):
continue
except:
pass
widget = None
if 'temp' in field and show_temp:
if "temp" in field and show_temp:
# seems to be a temperature
widget = self.add_widget()
widget.set('type', 'temp')
if 'fan' in field and show_fan:
widget.set("type", "temp")
if "fan" in field and show_fan:
# seems to be a fan
widget = self.add_widget()
widget.set('type', 'fan')
widget.set("type", "fan")
elif show_other:
# everything else
widget = self.add_widget()
widget.set('type', 'other')
widget.set("type", "other")
if widget:
widget.set('package', package)
widget.set('field', field)
widget.set('adapter', adapter)
widget.set("package", package)
widget.set("field", field)
widget.set("adapter", adapter)
def __update_widget(self, widget):
if widget.get('field', '') == '':
return # nothing to do
data = self.__data[widget.get('adapter')][widget.get('package')][widget.get('field')]
if 'temp' in widget.get('field'):
widget.full_text(u'{:0.01f}°C'.format(data['input']))
elif 'fan' in widget.get('field'):
widget.full_text(u'{:0.0f}RPM'.format(data['input']))
if widget.get("field", "") == "":
return # nothing to do
data = self.__data[widget.get("adapter")][widget.get("package")][
widget.get("field")
]
if "temp" in widget.get("field"):
widget.full_text("{:0.01f}°C".format(data["input"]))
elif "fan" in widget.get("field"):
widget.full_text("{:0.0f}RPM".format(data["input"]))
else:
widget.full_text(u'{:0.0f}'.format(data['input']))
widget.full_text("{:0.0f}".format(data["input"]))
def __update(self):
output = util.cli.execute('sensors -u {}'.format(self.__chip), ignore_errors=True)
output = util.cli.execute(
"sensors -u {}".format(self.__chip), ignore_errors=True
)
self.__data = self.__parse(output)
def __parse(self, data):
output = {}
package = ''
package = ""
adapter = None
chip = None
for line in data.split('\n'):
if 'Adapter' in line:
for line in data.split("\n"):
if "Adapter" in line:
# new adapter
line = line.replace('Adapter: ', '')
output[chip + ' ' + line] = {}
adapter = chip + ' ' + line
chip = line #default - line before adapter is always the chip
if not adapter: continue
key, value = (line.split(':') + ['', ''])[:2]
if not line.startswith(' '):
line = line.replace("Adapter: ", "")
output[chip + " " + line] = {}
adapter = chip + " " + line
chip = line # default - line before adapter is always the chip
if not adapter:
continue
key, value = (line.split(":") + ["", ""])[:2]
if not line.startswith(" "):
# assume this starts a new package
if package in output[adapter] and output[adapter][package] == {}:
del output[adapter][package]
@ -168,9 +204,9 @@ class Module(core.module.Module):
else:
# feature for this chip
try:
name, variant = (key.strip().split('_', 1) + ['',''])[:2]
name, variant = (key.strip().split("_", 1) + ["", ""])[:2]
if not name in output[adapter][package]:
output[adapter][package][name] = { }
output[adapter][package][name] = {}
if variant:
output[adapter][package][name][variant] = {}
output[adapter][package][name][variant] = float(value)
@ -181,23 +217,26 @@ class Module(core.module.Module):
def __cpu(self, _):
mhz = None
try:
output = open('/sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq').read()
mhz = int(float(output)/1000.0)
output = open(
"/sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq"
).read()
mhz = int(float(output) / 1000.0)
except:
output = open('/proc/cpuinfo').read()
m = re.search(r'cpu MHz\s+:\s+(\d+)', output)
output = open("/proc/cpuinfo").read()
m = re.search(r"cpu MHz\s+:\s+(\d+)", output)
if m:
mhz = int(m.group(1))
else:
m = re.search(r'BogoMIPS\s+:\s+(\d+)', output)
m = re.search(r"BogoMIPS\s+:\s+(\d+)", output)
if m:
return '{} BogoMIPS'.format(int(m.group(1)))
return "{} BogoMIPS".format(int(m.group(1)))
if not mhz:
return 'n/a'
return "n/a"
if mhz < 1000:
return '{} MHz'.format(mhz)
return "{} MHz".format(mhz)
else:
return '{:0.01f} GHz'.format(float(mhz)/1000.0)
return "{:0.01f} GHz".format(float(mhz) / 1000.0)
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -10,6 +10,7 @@ import core.module
import core.widget
import core.decorators
class Module(core.module.Module):
@core.decorators.every(minutes=60)
def __init__(self, config, theme):
@ -19,4 +20,5 @@ class Module(core.module.Module):
def text(self, _):
return self.__text
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -6,8 +6,10 @@
import core.widget
import core.module
class Module(core.module.Module):
def __init__(self, config, theme):
super().__init__(config=config, theme=theme, widgets=core.widget.Widget('test'))
super().__init__(config=config, theme=theme, widgets=core.widget.Widget("test"))
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -10,12 +10,14 @@ Parameters:
import core.decorators
from .datetime import Module
class Module(Module):
@core.decorators.every(seconds=59) # ensures one update per minute
@core.decorators.every(seconds=59) # ensures one update per minute
def __init__(self, config, theme):
super().__init__(config, theme)
def default_format(self):
return '%X'
return "%X"
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -12,7 +12,7 @@ Parameters:
"""
# TODO:
# TODO:
# - support multiple backends by abstracting the menu structure into a tree
# - build the menu and the actions based on that abstracted tree
#
@ -29,30 +29,39 @@ import core.event
import util.cli
import util.popup
def build_menu(parent, current_directory, callback):
with os.scandir(current_directory) as it:
for entry in it:
if entry.name.startswith('.'): continue
if entry.name.startswith("."):
continue
if entry.is_file():
name = entry.name[:entry.name.rfind('.')]
parent.add_menuitem(name, callback=lambda : callback(os.path.join(current_directory, name)))
name = entry.name[: entry.name.rfind(".")]
parent.add_menuitem(
name,
callback=lambda: callback(os.path.join(current_directory, name)),
)
else:
submenu = util.popup.menu(parent, leave=False)
build_menu(submenu, os.path.join(current_directory, entry.name), callback)
build_menu(
submenu, os.path.join(current_directory, entry.name), callback
)
parent.add_cascade(entry.name, submenu)
class Module(core.module.Module):
def __init__(self, config, theme):
super().__init__(config, theme, core.widget.Widget(self.text))
self.__duration = int(self.parameter('duration', 30))
self.__offx = int(self.parameter('offx', 0))
self.__offy = int(self.parameter('offy', 0))
self.__path = os.path.expanduser(self.parameter('location', '~/.password-store/'))
self.__duration = int(self.parameter("duration", 30))
self.__offx = int(self.parameter("offx", 0))
self.__offy = int(self.parameter("offy", 0))
self.__path = os.path.expanduser(
self.parameter("location", "~/.password-store/")
)
self.__reset()
core.input.register(self, button=core.input.LEFT_MOUSE,
cmd=self.popup)
core.input.register(self, button=core.input.LEFT_MOUSE, cmd=self.popup)
def popup(self, widget):
menu = util.popup.menu(leave=False)
@ -62,14 +71,17 @@ class Module(core.module.Module):
def __reset(self):
self.__timer = None
self.__text = str(self.parameter('text', '<click-for-password>'))
self.__text = str(self.parameter("text", "<click-for-password>"))
def __callback(self, secret_name):
secret_name = secret_name.replace(self.__path, '') # remove common path
secret_name = secret_name.replace(self.__path, "") # remove common path
if self.__timer:
self.__timer.cancel()
res = util.cli.execute('pass -c {}'.format(secret_name), wait=False,
env={ 'PASSWORD_STORE_CLIP_TIME': self.__duration })
res = util.cli.execute(
"pass -c {}".format(secret_name),
wait=False,
env={"PASSWORD_STORE_CLIP_TIME": self.__duration},
)
self.__timer = threading.Timer(self.__duration, self.__reset)
self.__timer.start()
self.__start = int(time.time())
@ -77,7 +89,10 @@ class Module(core.module.Module):
def text(self, widget):
if self.__timer:
return '{} ({}s)'.format(self.__text, self.__duration - (int(time.time()) - self.__start))
return "{} ({}s)".format(
self.__text, self.__duration - (int(time.time()) - self.__start)
)
return self.__text
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,6 +1,6 @@
# pylint: disable=C0111,R0903
'''Shows a widget for each connected screen and allows the user to enable/disable screens.
"""Shows a widget for each connected screen and allows the user to enable/disable screens.
Parameters:
* xrandr.overwrite_i3config: If set to 'true', this module assembles a new i3 config
@ -14,7 +14,7 @@ Requires the following python module:
Requires the following executable:
* xrandr
'''
"""
import os
import re
@ -33,17 +33,18 @@ try:
except:
pass
class Module(core.module.Module):
@core.decorators.every(seconds=5) # takes up to 5s to detect a new screen
@core.decorators.every(seconds=5) # takes up to 5s to detect a new screen
def __init__(self, config, theme):
widgets = []
super().__init__(config, theme, widgets)
self._autoupdate = util.format.asbool(self.parameter('autoupdate', True))
self._autoupdate = util.format.asbool(self.parameter("autoupdate", True))
self._needs_update = True
try:
i3.Subscription(self._output_update, 'output')
i3.Subscription(self._output_update, "output")
except:
pass
@ -58,31 +59,33 @@ class Module(core.module.Module):
self._needs_update = False
for line in util.cli.execute('xrandr -q').split('\n'):
if not ' connected' in line:
for line in util.cli.execute("xrandr -q").split("\n"):
if not " connected" in line:
continue
display = line.split(' ', 2)[0]
m = re.search(r'\d+x\d+\+(\d+)\+\d+', line)
display = line.split(" ", 2)[0]
m = re.search(r"\d+x\d+\+(\d+)\+\d+", line)
widget = self.widget(display)
if not widget:
widget = core.widget.Widget(full_text=display, name=display, module=self)
widget = core.widget.Widget(
full_text=display, name=display, module=self
)
core.input.register(widget, button=1, cmd=self._toggle)
core.input.register(widget, button=3, cmd=self._toggle)
new_widgets.append(widget)
widget.set('state', 'on' if m else 'off')
widget.set('pos', int(m.group(1)) if m else sys.maxsize)
widget.set("state", "on" if m else "off")
widget.set("pos", int(m.group(1)) if m else sys.maxsize)
self.widgets(new_widgets)
if self._autoupdate == False:
widget = core.widget.Widget(full_text='', module=self)
widget.set('state', 'refresh')
widget = core.widget.Widget(full_text="", module=self)
widget.set("state", "refresh")
core.input.register(widget, button=1, cmd=self._refresh)
self.widgets().append(widget)
def state(self, widget):
return widget.get('state', 'off')
return widget.get("state", "off")
def _refresh(self, event):
self._needs_update = True
@ -91,26 +94,50 @@ class Module(core.module.Module):
self._refresh(self, event)
path = os.path.dirname(os.path.abspath(__file__))
if util.format.asbool(self.parameter('overwrite_i3config', False)) == True:
toggle_cmd = '{}/../../bin/toggle-display.sh'.format(path)
if util.format.asbool(self.parameter("overwrite_i3config", False)) == True:
toggle_cmd = "{}/../../bin/toggle-display.sh".format(path)
else:
toggle_cmd = 'xrandr'
toggle_cmd = "xrandr"
widget = self.widget_by_id(event['instance'])
widget = self.widget_by_id(event["instance"])
if widget.get('state') == 'on':
util.cli.execute('{} --output {} --off'.format(toggle_cmd, widget.name))
if widget.get("state") == "on":
util.cli.execute("{} --output {} --off".format(toggle_cmd, widget.name))
else:
first_neighbor = next((widget for widget in self.widgets() if widget.get('state') == 'on'), None)
last_neighbor = next((widget for widget in reversed(self.widgets()) if widget.get('state') == 'on'), None)
first_neighbor = next(
(widget for widget in self.widgets() if widget.get("state") == "on"),
None,
)
last_neighbor = next(
(
widget
for widget in reversed(self.widgets())
if widget.get("state") == "on"
),
None,
)
neighbor = first_neighbor if event['button'] == core.input.LEFT_MOUSE else last_neighbor
neighbor = (
first_neighbor
if event["button"] == core.input.LEFT_MOUSE
else last_neighbor
)
if neighbor is None:
util.cli.execute('{} --output {} --auto'.format(toggle_cmd, widget.name))
util.cli.execute(
"{} --output {} --auto".format(toggle_cmd, widget.name)
)
else:
util.cli.execute('{} --output {} --auto --{}-of {}'.format(toggle_cmd, widget.name,
'left' if event.get('button') == core.input.LEFT_MOUSE else 'right',
neighbor.name))
util.cli.execute(
"{} --output {} --auto --{}-of {}".format(
toggle_cmd,
widget.name,
"left"
if event.get("button") == core.input.LEFT_MOUSE
else "right",
neighbor.name,
)
)
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4