i3pystatus/i3pystatus/updates/dnf.py

54 lines
1.6 KiB
Python

from i3pystatus.updates import Backend
import sys
# Remove first dir from sys.path to avoid shadowing dnf module from
# site-packages dir when this module executed directly on the CLI.
__module_dir = sys.path.pop(0)
try:
import dnf
HAS_DNF_BINDINGS = True
except ImportError:
HAS_DNF_BINDINGS = False
finally:
# Replace the directory we popped earlier
sys.path.insert(0, __module_dir)
class Dnf(Backend):
"""
Gets updates for RPM-based distributions using the `DNF API`_
The notification body consists of the package name and version for each
available update.
.. _`DNF API`: http://dnf.readthedocs.io/en/latest/api.html
"""
@property
def updates(self):
if HAS_DNF_BINDINGS:
try:
with dnf.Base() as base:
base.read_all_repos()
base.fill_sack()
upgrades = base.sack.query().upgrades().run()
notif_body = ''.join([
'%s: %s-%s\n' % (pkg.name, pkg.version, pkg.release)
for pkg in upgrades
])
return len(upgrades), notif_body
except Exception as exc:
self.logger.error('DNF update check failed', exc_info=True)
return '?', exc.__str__()
else:
return '?', 'Failed to import DNF Python bindings'
Backend = Dnf
if __name__ == "__main__":
"""
Call this module directly; Print the update count and notification body.
"""
print("Updates: {}\n\n{}".format(*Backend().updates))