Rewrite DNF updates module to use DNF's Python API

This is a lot easier than trying to parse the DNF CLI output.
This commit is contained in:
Erik Johnson 2016-11-30 11:11:47 -06:00
parent 78392fc499
commit 0eb825cdd8
2 changed files with 29 additions and 19 deletions

View File

@ -126,7 +126,10 @@ class Updates(Module):
for backend in self.backends:
name = backend.__class__.__name__
updates, notif_body = backend.updates
updates_count += updates
try:
updates_count += updates
except TypeError:
pass
self.data[name] = updates
self.notif_body[name] = notif_body or ""

View File

@ -1,33 +1,40 @@
from i3pystatus.core.command import run_through_shell
from i3pystatus.updates import Backend
from re import split, sub
try:
import dnf
HAS_DNF_BINDINGS = True
except ImportError:
HAS_DNF_BINDINGS = False
class Dnf(Backend):
"""
Gets updates for RPM-based distributions with `dnf check-update`.
Gets updates for RPM-based distributions using the `DNF API`_
The notification body consists of the status line followed by the package
name and version for each update.
The notification body consists of the package name and version for each
available update.
https://dnf.readthedocs.org/en/latest/command_ref.html#check-update-command
.. _`DNF API`: http://dnf.readthedocs.io/en/latest/api.html
"""
@property
def updates(self):
command = ["dnf", "check-update"]
dnf = run_through_shell(command)
if dnf.err:
return "?", dnf.err
if HAS_DNF_BINDINGS:
try:
with dnf.Base() as base:
base.read_all_repos()
base.fill_sack()
upgrades = base.sack.query().upgrades().run()
raw = dnf.out
update_count = 0
if dnf.rc == 100:
lines = raw.splitlines()[2:]
lines = [l for l in lines if len(split("\s+", l.rstrip())) == 3]
update_count = len(lines)
notif_body = sub(r"(\S+)\s+(\S+)\s+\S+\s*\n", r"\1: \2\n", raw)
return update_count, notif_body
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