Skip to content

Commit

Permalink
Logging and Bug Fixes (#2)
Browse files Browse the repository at this point in the history
* Fix incorrect low battery report

* Add app version to system tray

* Added a simple cli
- added --clean tag for using default settings
- added --version flag

* Add project dependencies to pyproject (just in case)

* Update AUR files

* Fix battery report error and added logs

* Bump to 1.2.0
  • Loading branch information
fer-hnndz authored Oct 3, 2024
1 parent 4242508 commit 6d77340
Show file tree
Hide file tree
Showing 12 changed files with 116 additions and 46 deletions.
7 changes: 4 additions & 3 deletions .SRCINFO
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pkgbase = battery-advisor
pkgdesc = A simple tool to monitor and notify about battery status. Built with Python.
pkgver = 1.0.0
pkgver = 1.2.0
pkgrel = 1
url = https://github.com/fer-hnndz/battery-advisor
arch = any
Expand All @@ -14,8 +14,9 @@ pkgbase = battery-advisor
depends = python-gobject
depends = libnotify
depends = python-pystray
depends = python-systemd
backup = etc/battery-advisor/defaultSettings.toml
source = https://files.pythonhosted.org/packages/source/b/battery_advisor/battery_advisor-1.0.0.tar.gz
sha256sums = d4a6f15ded5961d37566e232fccdc4b52d25ea545d67697f55da6778aa5a8205
source = https://files.pythonhosted.org/packages/source/b/battery_advisor/battery_advisor-1.2.0.tar.gz
sha256sums = e2128de236038d4beae221cd92e8c82a50a033d97bd7bdd6afab725e02bc8fc3

pkgname = battery-advisor
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ __pycache__
dist
src/
*.gz
pkg
pkg
*.log
6 changes: 3 additions & 3 deletions PKGBUILD
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
# Maintainer: Jorge Hernández <[email protected]>
pkgname="battery-advisor"
pkgver=1.0.0
pkgver=1.2.0
pkgrel=1
pkgdesc="A simple tool to monitor and notify about battery status. Built with Python."
arch=('any')
url="https://github.com/fer-hnndz/battery-advisor"
license=('MIT')
depends=("python" "python-psutil" "python-toml" "python-gobject" "libnotify" "python-pystray")
depends=("python" "python-psutil" "python-toml" "python-gobject" "libnotify" "python-pystray" "python-systemd")
backup=("etc/battery-advisor/defaultSettings.toml")
makedepends=(python-build python-installer python-wheel)
_name=${pkgname#python-}
source=("https://files.pythonhosted.org/packages/source/${_name::1}/${_name//-/_}/${_name//-/_}-$pkgver.tar.gz")
sha256sums=(d4a6f15ded5961d37566e232fccdc4b52d25ea545d67697f55da6778aa5a8205)
sha256sums=(e2128de236038d4beae221cd92e8c82a50a033d97bd7bdd6afab725e02bc8fc3)
validpgpkeys=()

prepare() {
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,4 @@ $ yay -S battery-advisor
- python-pystray
- python-toml
- python-psutil
- python-systemd
2 changes: 1 addition & 1 deletion battery_advisor/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
from .entry import main
from .entry import cli
from .settings_loader import load_settings
62 changes: 40 additions & 22 deletions battery_advisor/battery_advisor.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,31 +9,47 @@
from .types import BatteryReport
from typing import Optional
from datetime import datetime
import logging
from systemd.journal import JournalHandler

settings = Settings.load()
VERSION = "1.1.0"
logger = logging.getLogger(__name__)
logger.addHandler(JournalHandler())


class BatteryAdvisor:
"""Base Program that manages SysTray Icon and the battery checker service."""

def __init__(self):
def __init__(self, clean: bool = False):
"""
Initializes the Battery Advisor program.
Parameters
----------
clean : bool, optional
If True, the program will use default settings.
"""

logging.debug("==== Initializing Battery Advisor... ====")
self.running = True
self.settings = Settings.load(clean)

def get_battery_reports(self) -> Optional[BatteryReport]:
"""Returns thet status that needs to be reported to the user"""

batt_percent, plugged = get_battery_status()
logger.info(f"Battery Status: {batt_percent}% | Plugged: {plugged}")

if plugged:
return None

if batt_percent <= settings.battery_action_treshold:
if batt_percent <= self.settings.battery_action_treshold:
return BatteryReport.ACTION

if batt_percent <= settings.critical_battery_treshold:
if batt_percent <= self.settings.critical_battery_treshold:
return BatteryReport.CRITICAL

if batt_percent <= 100:
if batt_percent <= self.settings.low_battery_treshold:
return BatteryReport.LOW

return None
Expand All @@ -44,7 +60,7 @@ def _battery_checker(self):
This one runs in a separate thread because the SysTray icon must run on the main thread.
"""

print("Starting battery checker...")
logging.info("Starting battery checker...")

# Always get initial status to avoid false notifications
_, was_plugged = get_battery_status()
Expand All @@ -55,34 +71,33 @@ def _battery_checker(self):
time.sleep(3)
continue

print("Checking battery status...")
_, plugged = get_battery_status()

# Battery Plugged in notifications
if plugged != was_plugged:
was_plugged = plugged
if plugged and settings.notify_plugged:
if plugged and self.settings.notify_plugged:
notify("Battery Plugged In", "Battery is now charging")
elif not plugged and settings.notify_unplugged:
elif not plugged and self.settings.notify_unplugged:
notify("Battery Unplugged", "Battery is now discharging.")

report = self.get_battery_reports()
print("Battery Report:", report)
logging.info("Battery Report:", report)

if report is None:
time.sleep(settings.check_interval)
time.sleep(self.settings.check_interval)
continue

if report == BatteryReport.ACTION:
battery_action = settings.battery_action
battery_action = self.settings.battery_action
alert(message=f"Your battery will {battery_action.capitalize()} soon.")
time.sleep(3)
execute_action(battery_action, settings.actions)
execute_action(battery_action, self.settings.actions)

if report == BatteryReport.CRITICAL:
alert_with_options(
message="Your battery is critically low. Please plug in your charger.",
options=settings.critical_battery_options,
options=self.settings.critical_battery_options,
title="Battery Critically Low",
)

Expand All @@ -98,25 +113,27 @@ def _battery_checker(self):
):
r = alert_with_options(
"Battery is low. Please plug in your charger.",
settings.low_battery_options,
self.settings.low_battery_options,
title="Battery Low",
)

selected_action = settings.low_battery_options[r]
selected_action = self.settings.low_battery_options[r]

if selected_action == "remind":
remind_timestamp = datetime.fromtimestamp(
remind_timestamp.timestamp() + settings.remind_time
remind_timestamp.timestamp() + self.settings.remind_time
)

else:
execute_action(selected_action, settings.actions)
execute_action(selected_action, self.settings.actions)

time.sleep(settings.check_interval)
time.sleep(self.settings.check_interval)

def _on_enabled_click(self, icon, item):
self.running = not self.running
print("Battery Advisor is now", "enabled" if self.running else "disabled")
logging.warning(
"Battery Advisor is now", "enabled" if self.running else "disabled"
)

def start(self):
batt_thread = threading.Thread(target=self._battery_checker, daemon=True)
Expand All @@ -127,8 +144,9 @@ def start(self):
text="Enabled",
checked=lambda item: self.running,
action=self._on_enabled_click,
)
),
MenuItem(text=f"Version: {VERSION}", checked=None, action=None),
)
get_icon(menu).run()
print("Exiting...")
logging.info("Exiting...")
return 0
28 changes: 25 additions & 3 deletions battery_advisor/entry.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
from .battery_advisor import BatteryAdvisor
from .battery_advisor import BatteryAdvisor, VERSION
import argparse
import logging
import os
from .utils import _get_project_root


def main():
BatteryAdvisor().start()
def cli():
log_path = os.path.join(_get_project_root(), "advisor.log")

logging.basicConfig(
level=logging.DEBUG,
format="[%(asctime)s ] (%(module)s.%(funcName)s | %(levelname)s) %(message)s",
datefmt="%d/%m/%Y @ %H:%M:%S %Z",
filename=log_path,
)

parser = argparse.ArgumentParser(
prog="Battery Advisor",
description="A simple tool to monitor and notify about battery status. Built with Python.",
epilog="Made with ❤️ by Jorge Hernández.",
)
parser.add_argument("--version", action="version", version=f"%(prog)s {VERSION}")
parser.add_argument("--clean", action="store_true", help="Use default settings.")

args = parser.parse_args()
BatteryAdvisor(clean=args.clean).start()
33 changes: 26 additions & 7 deletions battery_advisor/settings_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,27 @@
from .utils import _get_project_root

user_settings_path = os.path.expanduser("~/.config/battery-advisor/settings.toml")
default_settings_path = _get_project_root() + "/defaultSettings.toml"


def load_settings() -> SettingsFile:
def load_settings(load_default: bool = False) -> SettingsFile:
"""Loads the settings from the settings.toml file and returns a dictionary with the settings
Parameters
----------
load_default : bool, optional
If True, the default settings will be loaded instead of the user settings.
"""

if load_default:
print("Loading default settings...")
with open(default_settings_path) as f:
return toml.load(f)

path = (
user_settings_path
if os.path.exists(user_settings_path)
else _get_project_root() + "/defaultSettings.toml"
else default_settings_path
)

if not os.path.exists(user_settings_path):
Expand All @@ -31,8 +45,7 @@ def __init__(self, settings: SettingsFile):
self.remind_time: int = int(settings["advisor"]["remind_time"])

# Tresholds
# self.low_battery_treshold = settings["tresholds"]["low_battery_treshold"]
self.low_battery_treshold = 100
self.low_battery_treshold = settings["tresholds"]["low_battery_treshold"]
self.critical_battery_treshold = settings["tresholds"][
"critical_battery_treshold"
]
Expand All @@ -50,7 +63,13 @@ def __init__(self, settings: SettingsFile):
self.notify_unplugged = settings["advisor"]["notify_unplugged"]

@classmethod
def load(cls: Type["Settings"]) -> "Settings":
"""Loads the settings from the settings.toml file and returns a Settings object"""
def load(cls: Type["Settings"], clean: bool = False) -> "Settings":
"""Loads the settings from the settings.toml file and returns a Settings object
Parameters
----------
clean : bool, optional
If True, the default settings will be loaded instead of the user settings.
"""

return cls(load_settings())
return cls(load_settings(load_default=clean))
1 change: 1 addition & 0 deletions battery_advisor/version.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VERSION = "1.2.0"
4 changes: 2 additions & 2 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from battery_advisor import main
from battery_advisor import cli

if __name__ == "__main__":
main()
cli()
2 changes: 1 addition & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 10 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
[tool.poetry]
name = "battery-advisor"
version = "1.0.0"
version = "1.2.0"
description = "A simple tool to monitor and notify about battery status. Built with Python."
authors = ["fer-hnndz <[email protected]>"]
license = "MIT"
readme = "README.md"
homepage = "https://github.com/fer-hnndz/battery-advisor"
keywords = ["battery", "monitor", "notify"]
include = ["defaultSettings.toml", "icon.png", "LICENSE"]

classifiers = [
"Development Status :: 5 - Production/Stable",
"Operating System :: POSIX :: Linux",
"Topic :: Desktop Environment",
]

[tool.poetry.dependencies]
python = "^3.11"
pystray = "^0.19.5"
toml = "^0.10.2"
psutil = "^6.0.0"

[tool.poetry.group.dev.dependencies]
black = "^24.8.0"
Expand All @@ -22,4 +29,4 @@ requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

[tool.poetry.scripts]
battery-advisor = "battery_advisor:entry.main"
battery-advisor = "battery_advisor:entry.cli"

0 comments on commit 6d77340

Please sign in to comment.