diff --git a/docs/i3pystatus.rst b/docs/i3pystatus.rst index 80637a5..dacbbb7 100644 --- a/docs/i3pystatus.rst +++ b/docs/i3pystatus.rst @@ -7,10 +7,10 @@ Module reference :System: `clock`_ - `disk`_ - `load`_ - `mem`_ - `cpu_usage`_ :Audio: `alsa`_ - `pulseaudio`_ :Hardware: `battery`_ - `backlight`_ - `temp`_ -:Network: `network`_ +:Network: `network`_ :Music: `now_playing`_ - `mpd`_ :Websites & stuff: `weather`_ - `bitcoin`_ - `reddit`_ - `parcel`_ -:Other: `mail`_ - `pyload`_ - `text`_ +:Other: `mail`_ - `pyload`_ - `text`_ - `updates`_ :Advanced: `file`_ - `regex`_ - `runwatch`_ - `shell`_ .. autogen:: i3pystatus Module @@ -25,3 +25,12 @@ Mail Backends .. autogen:: i3pystatus.mail SettingsBase .. nothin' + +.. _updatebackends: + +Update Backends +--------------- + +.. autogen:: i3pystatus.updates SettingsBase + + .. nothin' diff --git a/i3pystatus/updates/__init__.py b/i3pystatus/updates/__init__.py new file mode 100644 index 0000000..e135cae --- /dev/null +++ b/i3pystatus/updates/__init__.py @@ -0,0 +1,86 @@ +from i3pystatus import SettingsBase, IntervalModule, formatp +from i3pystatus.core.util import internet, require + + +class Backend(SettingsBase): + settings = () + updates = 0 + + +class Updates(IntervalModule): + """ + Generic update checker. + To use select appropriate backend(s) for your system. + For list of all available backends see :ref:`updatebackends`. + + Left clicking on the module will refresh the count of upgradeable packages. + This may be used to dismiss the notification after updating your system. + + .. rubric:: Available formatters + + * `{count}` — Sum of all available updates from all backends. + + .. rubric:: Usage example + + :: + + from i3pystatus import Status + from i3pystatus.updates import pacman, cower + + status = Status(standalone=True) + + status.register("updates", + format = "Updates: {count}", + format_no_updates = "No updates", + backends = [pacman.Pacman(), cower.Cower()]) + + status.run() + + """ + + interval = 3600 + + settings = ( + ("backends", "Required list of backends used to check for updates."), + ("format", "String shown when updates are available. " + "May contain formatters."), + ("format_no_updates", "String that is shown if no updates are available." + " If not set the module will be hidden if no updates are available."), + "color", + "color_no_updates", + ("interval", "Default interval is set to one hour."), + ) + required = ("backends",) + + backends = None + format = "Updates: {count}" + format_no_updates = None + color = "#00DD00" + color_no_updates = "#FFFFFF" + + on_leftclick = "run" + + def init(self): + if not isinstance(self.backends, list): + self.backends = [self.backends] + + @require(internet) + def run(self): + updates_count = 0 + for backend in self.backends: + updates_count += backend.updates + + if updates_count == 0: + self.output = {} if not self.format_no_updates else { + "full_text": self.format_no_updates, + "color": self.color_no_updates, + } + return + + fdict = { + "count": updates_count, + } + self.output = { + "full_text": formatp(self.format, **fdict).strip(), + "color": self.color, + } diff --git a/i3pystatus/updates/aptget.py b/i3pystatus/updates/aptget.py new file mode 100644 index 0000000..f73c733 --- /dev/null +++ b/i3pystatus/updates/aptget.py @@ -0,0 +1,32 @@ +import os + +from i3pystatus.core.command import run_through_shell +from i3pystatus.updates import Backend + + +class AptGet(Backend): + """ + Gets update count for Debian based distributions. + + This mimics the Arch Linux `checkupdates` script + but with apt-get and written in python. + """ + + @property + def updates(self): + cache_dir = "/tmp/update-cache-" + os.getenv("USER") + if not os.path.exists(cache_dir): + os.mkdir(cache_dir) + + command = "apt-get update -o Dir::State::Lists=" + cache_dir + run_through_shell(command.split()) + command = "apt-get upgrade -s -o Dir::State::Lists=" + cache_dir + apt = run_through_shell(command.split()) + + update_count = 0 + for line in apt.out.split("\n"): + if line.startswith("Inst"): + update_count += 1 + return update_count + +Backend = AptGet diff --git a/i3pystatus/updates/cower.py b/i3pystatus/updates/cower.py new file mode 100644 index 0000000..144f156 --- /dev/null +++ b/i3pystatus/updates/cower.py @@ -0,0 +1,18 @@ +from i3pystatus.core.command import run_through_shell +from i3pystatus.updates import Backend + + +class Cower(Backend): + """ + Checks for updates in Arch User Repositories using the `cower` AUR helper. + + Depends on cower AUR agent - https://github.com/falconindy/cower + """ + + @property + def updates(self): + command = ["cower", "-u"] + cower = run_through_shell(command) + return cower.out.count('\n') + +Backend = Cower diff --git a/i3pystatus/updates/pacman.py b/i3pystatus/updates/pacman.py new file mode 100644 index 0000000..8f40945 --- /dev/null +++ b/i3pystatus/updates/pacman.py @@ -0,0 +1,17 @@ +from i3pystatus.core.command import run_through_shell +from i3pystatus.updates import Backend + + +class Pacman(Backend): + """ + Checks for updates in Arch Linux repositories using the + `checkupdates` script which is part of the `pacman` package. + """ + + @property + def updates(self): + command = ["checkupdates"] + checkupdates = run_through_shell(command) + return checkupdates.out.count('\n') + +Backend = Pacman diff --git a/setup.py b/setup.py index b8ef64d..8cf3168 100755 --- a/setup.py +++ b/setup.py @@ -20,6 +20,7 @@ setup(name="i3pystatus", "i3pystatus.core", "i3pystatus.mail", "i3pystatus.pulseaudio", + "i3pystatus.updates", ], entry_points={ "console_scripts": [