[modules] move some modules into contrib, as appropriate

This commit is contained in:
tobi-wan-kenobi 2020-05-08 20:59:38 +02:00
parent 21049b9b03
commit dd4294ecfa
5 changed files with 0 additions and 0 deletions

View file

@ -1,334 +0,0 @@
# UPowerManger Class Copyright (C) 2017 Oscar Svensson (wogscpar) under MIT licence from upower-python
"""Displays battery status, remaining percentage and charging information.
Parameters:
* battery-upower.warning : Warning threshold in % of remaining charge (defaults to 20)
* battery-upower.critical : Critical threshold in % of remaining charge (defaults to 10)
* battery-upower.showremaining : If set to true (default) shows the remaining time until the batteries are completely discharged
contributed by `martindoublem <https://github.com/martindoublem>`_ - many thanks!
"""
import dbus
import logging
import core.module
import core.widget
import core.input
import util.format
class UPowerManager:
def __init__(self):
self.UPOWER_NAME = "org.freedesktop.UPower"
self.UPOWER_PATH = "/org/freedesktop/UPower"
self.DBUS_PROPERTIES = "org.freedesktop.DBus.Properties"
self.bus = dbus.SystemBus()
def detect_devices(self):
upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH)
upower_interface = dbus.Interface(upower_proxy, self.UPOWER_NAME)
devices = upower_interface.EnumerateDevices()
return devices
def get_display_device(self):
upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH)
upower_interface = dbus.Interface(upower_proxy, self.UPOWER_NAME)
dispdev = upower_interface.GetDisplayDevice()
return dispdev
def get_critical_action(self):
upower_proxy = self.bus.get_object(self.UPOWER_NAME, self.UPOWER_PATH)
upower_interface = dbus.Interface(upower_proxy, self.UPOWER_NAME)
critical_action = upower_interface.GetCriticalAction()
return critical_action
def get_device_percentage(self, battery):
battery_proxy = self.bus.get_object(self.UPOWER_NAME, battery)
battery_proxy_interface = dbus.Interface(battery_proxy, self.DBUS_PROPERTIES)
return battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Percentage")
def get_full_device_information(self, battery):
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"
)
online = battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "Online")
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"
)
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"
)
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"
)
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"
)
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"
)
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,
}
return information_table
def is_lid_present(self):
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"))
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"))
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"))
return on_battery
def has_wakeup_capabilities(self):
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")
)
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")
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")
data = upower_interface.GetTotal()
return data
def is_loading(self, battery):
battery_proxy = self.bus.get_object(self.UPOWER_NAME, battery)
battery_proxy_interface = dbus.Interface(battery_proxy, self.DBUS_PROPERTIES)
state = int(battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "State"))
if state == 1:
return True
else:
return False
def get_state(self, battery):
battery_proxy = self.bus.get_object(self.UPOWER_NAME, battery)
battery_proxy_interface = dbus.Interface(battery_proxy, self.DBUS_PROPERTIES)
state = int(battery_proxy_interface.Get(self.UPOWER_NAME + ".Device", "State"))
if state == 0:
return "Unknown"
elif state == 1:
return "Loading"
elif state == 2:
return "Discharging"
elif state == 3:
return "Empty"
elif state == 4:
return "Fully charged"
elif state == 5:
return "Pending charge"
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))
try:
self.power = UPowerManager()
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"
)
self._showremaining = util.format.asbool(self.parameter("showremaining", True))
def capacity(self, widget):
widget.set("capacity", -1)
widget.set("ac", False)
output = "n/a"
try:
capacity = int(self.power.get_device_percentage(self.device))
capacity = capacity if capacity < 100 else 100
widget.set("capacity", capacity)
output = "{}%".format(capacity)
widget.set("theme.minwidth", "100%")
except Exception as e:
logging.exception("unable to get battery capacity: {}".format(str(e)))
if self._showremaining:
try:
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: 1 => charging, 2 => discharging, other => don't care
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))
)
return output
def state(self, widget):
state = []
capacity = widget.get("capacity", -1)
if capacity < 0:
return ["critical", "unknown"]
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")
else:
charge = "Unknown"
try:
charge = self.power.get_state(self.device)
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))
)
)
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")
else:
state.append("charging")
return state
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,213 +0,0 @@
# pylint: disable=C0111,R0903
"""Displays battery status, remaining percentage and charging information.
Parameters:
* battery.device : Comma-separated list of battery devices to read information from (defaults to auto for auto-detection)
* battery.warning : Warning threshold in % of remaining charge (defaults to 20)
* battery.critical : Critical threshold in % of remaining charge (defaults to 10)
* battery.showdevice : If set to 'true', add the device name to the widget (defaults to False)
* battery.decorate : If set to 'false', hides additional icons (charging, etc.) (defaults to True)
* battery.showpowerconsumption: If set to 'true', show current power consumption (defaults to False)
* battery.compact-devices : If set to 'true', compacts multiple batteries into a single entry (default to False)
(partially) contributed by `martindoublem <https://github.com/martindoublem>`_ - many thanks!
"""
import os
import glob
import logging
log = logging.getLogger(__name__)
try:
import power
except ImportError:
log.warning('unable to import module "power": Time estimates will not be available')
import core.module
import core.widget
import core.input
import util.format
class BatteryManager(object):
def remaining(self):
try:
estimate = power.PowerManagement().get_time_remaining_estimate()
# do not show remaining if on AC
if estimate == power.common.TIME_REMAINING_UNLIMITED:
return None
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)
if not os.path.exists(path):
return default
try:
with open("{}/{}".format(path, component)) as f:
return f.read().strip()
except IOError:
return "n/a"
return default
def capacity(self, battery):
capacity = self.read(battery, "capacity", 100)
if capacity != "n/a":
capacity = int(capacity)
return capacity if capacity < 100 else 100
def capacity_all(self, batteries):
now = 0
full = 0
for battery in batteries:
try:
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:
now += int(f.read())
except IOError:
return "n/a"
return int(float(now) / float(full) * 100.0)
def isac(self, 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
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)
def charge(self, battery):
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"
class Module(core.module.Module):
def __init__(self, config, theme):
widgets = []
super().__init__(config, theme, widgets)
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*")
]
if len(self._batteries) == 0:
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
)
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
)
widgets.append(widget)
for w in self.widgets():
if util.format.asbool(self.parameter("decorate", True)) == False:
widget.set("theme.exclude", "suffix")
def capacity(self, widget):
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%")
# Read power conumption
if util.format.asbool(self.parameter("showpowerconsumption", False)):
output = "{}% ({})".format(
capacity, self.__manager.consumption(widget.name)
)
else:
output = "{}%".format(capacity)
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)
)
if util.format.asbool(self.parameter("showdevice", False)):
output = "{} ({})".format(output, widget.name)
return output
def state(self, widget):
state = []
capacity = widget.get("capacity")
if capacity < 0:
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 widget.get("ac"):
state.append("AC")
else:
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))
)
)
else:
if capacity > 95:
state.append("charged")
else:
state.append("charging")
return state
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,70 +0,0 @@
# pylint: disable=C0111,R0903
"""Displays the brightness of a display
Parameters:
* brightness.step: The amount of increase/decrease on scroll in % (defaults to 2)
contributed by `TheEdgeOfRage <https://github.com/TheEdgeOfRage>`_ - many thanks!
"""
import glob
import shutil
import core.module
import core.widget
import core.input
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.__readcmd = None
step = self.parameter("step", 2)
if shutil.which("light"):
self.__readcmd = self.__light
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)
)
else:
self.__readcmd = self.__xbacklight
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)
core.input.register(self, button=core.input.WHEEL_DOWN, cmd=down_cmd)
def brightness(self, widget):
return self.__brightness
def __light(self):
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
def __xbacklight(self):
return util.cli.execute("xbacklight -get").strip()
def update(self):
try:
self.__brightness = "{:3.0f}%".format(float(self.__readcmd()))
except:
self.__brightness = "n/a"
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,160 +0,0 @@
# pylint: disable=C0111,R0903
"""Displays information about the current song in cmus.
Requires the following executable:
* cmus-remote
Parameters:
* cmus.format: Format string for the song information. Tag values can be put in curly brackets (i.e. {artist})
Additional tags:
* {file} - full song file name
* {file1} - song file name without path prefix
if {file} = '/foo/bar.baz', then {file1} = 'bar.baz'
* {file2} - song file name without path prefix and extension suffix
if {file} = '/foo/bar.baz', then {file2} = 'bar'
* cmus.layout: Space-separated list of widgets to add. Possible widgets are the buttons/toggles cmus.prev, cmus.next, cmus.shuffle and cmus.repeat, and the main display with play/pause function cmus.main.
* cmus.server: The address of the cmus server, either a UNIX socket or host[:port]. Connects to the local instance by default.
* cmus.passwd: The password to use for the TCP/IP connection.
contributed by `TheEdgeOfRage <https://github.com/TheEdgeOfRage>`_ - many thanks!
"""
from collections import defaultdict
import os
import string
import core.module
import core.widget
import core.input
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._status = None
self._shuffle = False
self._repeat = False
self._tags = defaultdict(lambda: "")
# Create widgets
widget_list = []
widget_map = {}
for widget_name in self._layout.split():
widget = core.widget.Widget(name=widget_name, module=self)
widget_list.append(widget)
self._cmd = "cmus-remote"
if self._server is not None:
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
)
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),
}
else:
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
for widget, callback_options in widget_map.items():
core.input.register(widget, **callback_options)
def hidden(self):
return self._status is None
@core.decorators.scrollable
def description(self, widget):
return string.Formatter().vformat(self._fmt, (), self._tags)
def update(self):
self._load_song()
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",
}
return returns.get(widget.name, self._status)
def _eval_line(self, line):
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})
return
name, key, value = (line.split(" ", 2) + [None, None])[:3]
if name == "status":
self._status = key
if name == "tag":
self._tags.update({key: value})
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"
def _load_song(self):
info = ""
try:
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._eval_line(line)
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,24 +0,0 @@
# pylint: disable=C0111,R0903
"""Shows Linux kernel version information
contributed by `pierre87 <https://github.com/pierre87>`_ - many thanks!
"""
import platform
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 platform.release()
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4