Merge pull request #499 from terminalmage/issue498

Rewrite DNF updates module to use DNF's Python API
This commit is contained in:
enkore 2016-12-02 11:35:27 +01:00 committed by GitHub
commit a1eba370bd
2 changed files with 37 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,48 @@
from i3pystatus.core.command import run_through_shell
from i3pystatus.updates import Backend
from re import split, sub
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 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