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: for backend in self.backends:
name = backend.__class__.__name__ name = backend.__class__.__name__
updates, notif_body = backend.updates updates, notif_body = backend.updates
updates_count += updates try:
updates_count += updates
except TypeError:
pass
self.data[name] = updates self.data[name] = updates
self.notif_body[name] = notif_body or "" 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 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): 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 The notification body consists of the package name and version for each
name and version for each update. 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 @property
def updates(self): def updates(self):
command = ["dnf", "check-update"] if HAS_DNF_BINDINGS:
dnf = run_through_shell(command) try:
if dnf.err: with dnf.Base() as base:
return "?", dnf.err base.read_all_repos()
base.fill_sack()
upgrades = base.sack.query().upgrades().run()
raw = dnf.out notif_body = ''.join([
update_count = 0 '%s: %s-%s\n' % (pkg.name, pkg.version, pkg.release)
if dnf.rc == 100: for pkg in upgrades
lines = raw.splitlines()[2:] ])
lines = [l for l in lines if len(split("\s+", l.rstrip())) == 3] return len(upgrades), notif_body
update_count = len(lines) except Exception as exc:
notif_body = sub(r"(\S+)\s+(\S+)\s+\S+\s*\n", r"\1: \2\n", raw) self.logger.error('DNF update check failed', exc_info=True)
return update_count, notif_body return '?', exc.__str__()
else:
return '?', 'Failed to import DNF Python bindings'
Backend = Dnf Backend = Dnf