Merge branch 'master' of git://github.com/tobi-wan-kenobi/bumblebee-status

This commit is contained in:
Lucas Souto 2018-09-07 22:22:07 -03:00
commit 17131c5bdc
8 changed files with 122 additions and 22 deletions

View file

@ -5,7 +5,7 @@
[![Test Coverage](https://codeclimate.com/github/tobi-wan-kenobi/bumblebee-status/badges/coverage.svg)](https://codeclimate.com/github/tobi-wan-kenobi/bumblebee-status/coverage) [![Test Coverage](https://codeclimate.com/github/tobi-wan-kenobi/bumblebee-status/badges/coverage.svg)](https://codeclimate.com/github/tobi-wan-kenobi/bumblebee-status/coverage)
[![Issue Count](https://codeclimate.com/github/tobi-wan-kenobi/bumblebee-status/badges/issue_count.svg)](https://codeclimate.com/github/tobi-wan-kenobi/bumblebee-status) [![Issue Count](https://codeclimate.com/github/tobi-wan-kenobi/bumblebee-status/badges/issue_count.svg)](https://codeclimate.com/github/tobi-wan-kenobi/bumblebee-status)
**Many, many thanks to all contributors! As of now, 27 of the modules are from various contributors (!), and only 16 from myself.** **Many, many thanks to all contributors! As of now, 28 of the modules are from various contributors (!), and only 16 from myself.**
![Solarized Powerline](https://github.com/tobi-wan-kenobi/bumblebee-status/blob/master/screenshots/themes/powerline-solarized.png) ![Solarized Powerline](https://github.com/tobi-wan-kenobi/bumblebee-status/blob/master/screenshots/themes/powerline-solarized.png)

View file

@ -35,6 +35,8 @@ class Module(bumblebee.engine.Module):
self._states["include"].append(state) self._states["include"].append(state)
self._format = self.parameter("format","{intf} {state} {ip} {ssid}"); self._format = self.parameter("format","{intf} {state} {ip} {ssid}");
self._update_widgets(widgets) self._update_widgets(widgets)
self.iwgetid = bumblebee.util.which("iwgetid")
def update(self, widgets): def update(self, widgets):
self._update_widgets(widgets) self._update_widgets(widgets)
@ -106,7 +108,7 @@ class Module(bumblebee.engine.Module):
def get_ssid(self, intf): def get_ssid(self, intf):
if self._iswlan(intf): if self._iswlan(intf):
try: try:
return subprocess.check_output(["iwgetid","-r",intf]).strip().decode('utf-8') return subprocess.check_output([self.iwgetid,"-r",intf]).strip().decode('utf-8')
except: except:
return "" return ""
return "" return ""

View file

@ -0,0 +1,51 @@
# pylint: disable=C0111,R0903
"""Displays the result of a notmuch count query
default : unread emails which path do not contained "Trash" (notmuch count "tag:unread AND NOT path:/.*Trash.*/")
Parameters:
* notmuch_count.query: notmuch count query to show result
Errors:
if the notmuch query failed, the shown value is -1
Dependencies:
notmuch (https://notmuchmail.org/)
"""
import bumblebee.input
import bumblebee.output
import bumblebee.engine
import os
class Module(bumblebee.engine.Module):
def __init__(self, engine, config):
super(Module, self).__init__(engine, config,
bumblebee.output.Widget(full_text=self.output)
)
self._notmuch_count_query = self.parameter("query", "tag:unread AND NOT path:/.*Trash.*/")
self._notmuch_count = self.count_notmuch()
def output(self, widget):
self._notmuch_count = self.count_notmuch()
return str(self._notmuch_count)
def state(self, widgets):
if self._notmuch_count == 0:
return "empty"
return "items"
def count_notmuch(self):
try:
notmuch_count_cmd = "notmuch count " + self._notmuch_count_query
notmuch_count = int(bumblebee.util.execute(notmuch_count_cmd))
return notmuch_count
except Exception:
return -1
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -6,6 +6,7 @@ Aliases: pasink (use this to control output instead of input), pasource
Parameters: Parameters:
* pulseaudio.autostart: If set to "true" (default is "false"), automatically starts the pulseaudio daemon if it is not running * pulseaudio.autostart: If set to "true" (default is "false"), automatically starts the pulseaudio daemon if it is not running
* pulseaudio.percent_change: How much to change volume by when scrolling on the module (default is 2%)
Requires the following executable: Requires the following executable:
* pulseaudio * pulseaudio
@ -33,6 +34,13 @@ class Module(bumblebee.engine.Module):
bumblebee.util.execute("pulseaudio --start") bumblebee.util.execute("pulseaudio --start")
except Exception: except Exception:
pass pass
try:
percent_change = int(self.parameter("percent_change","2%").strip("%"))
except:
percent_change = 2
if percent_change < 0 or percent_change > 100:
percent_change = 2
self._left = 0 self._left = 0
self._right = 0 self._right = 0
@ -51,8 +59,8 @@ class Module(bumblebee.engine.Module):
events = [ events = [
{"type": "mute", "action": "toggle", "button": bumblebee.input.LEFT_MOUSE}, {"type": "mute", "action": "toggle", "button": bumblebee.input.LEFT_MOUSE},
{"type": "volume", "action": "+2%", "button": bumblebee.input.WHEEL_UP}, {"type": "volume", "action": "+{percent}%".format(percent=percent_change), "button": bumblebee.input.WHEEL_UP},
{"type": "volume", "action": "-2%", "button": bumblebee.input.WHEEL_DOWN}, {"type": "volume", "action": "-{percent}%".format(percent=percent_change), "button": bumblebee.input.WHEEL_DOWN},
] ]
for event in events: for event in events:

View file

@ -60,4 +60,23 @@ def durationfmt(duration, shorten=False, suffix=False):
return "{}{}".format(res, suf if suffix else "") return "{}{}".format(res, suf if suffix else "")
def which(program):
import os
def is_exe(fpath):
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
fpath, fname = os.path.split(program)
if fpath:
if is_exe(program):
return program
else:
localPATH = os.environ["PATH"].split(os.pathsep)
localPATH += ["/sbin", "/usr/sbin/", "/usr/local/sbin"]
for path in localPATH:
exe_file = os.path.join(path, program)
if is_exe(exe_file):
return exe_file
return None
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -3,7 +3,7 @@
echo "testing with $(python2 -V 2>&1)" echo "testing with $(python2 -V 2>&1)"
python2 $(which nosetests) -v --with-coverage --cover-erase tests/ python2 $(which nosetests) -v --with-coverage --cover-erase tests/
if [ $? == 0 ]; then if test $? -eq 0 ; then
echo echo
echo "testing with $(python3 -V 2>&1)" echo "testing with $(python3 -V 2>&1)"

View file

@ -1,11 +1,12 @@
# pylint: disable=C0103,C0111 # pylint: disable=C0103,C0111
import mock
import unittest import unittest
import re
import tests.mocks as mocks import tests.mocks as mocks
from bumblebee.util import * import bumblebee.util as bu
class TestUtil(unittest.TestCase): class TestUtil(unittest.TestCase):
def setUp(self): def setUp(self):
@ -17,28 +18,28 @@ class TestUtil(unittest.TestCase):
self.popen.cleanup() self.popen.cleanup()
def test_bytefmt(self): def test_bytefmt(self):
self.assertEquals(bytefmt(10), "10.00B") self.assertEquals(bu.bytefmt(10), "10.00B")
self.assertEquals(bytefmt(15*1024), "15.00KiB") self.assertEquals(bu.bytefmt(15 * 1024), "15.00KiB")
self.assertEquals(bytefmt(20*1024*1024), "20.00MiB") self.assertEquals(bu.bytefmt(20 * 1024 * 1024), "20.00MiB")
self.assertEquals(bytefmt(22*1024*1024*1024), "22.00GiB") self.assertEquals(bu.bytefmt(22 * 1024 * 1024 * 1024), "22.00GiB")
self.assertEquals(bytefmt(35*1024*1024*1024*1024), "35840.00GiB") self.assertEquals(bu.bytefmt(35 * 1024 * 1024 * 1024 * 1024), "35840.00GiB")
def test_durationfmt(self): def test_durationfmt(self):
self.assertEquals(durationfmt(00), "00:00") self.assertEquals(bu.durationfmt(00), "00:00")
self.assertEquals(durationfmt(25), "00:25") self.assertEquals(bu.durationfmt(25), "00:25")
self.assertEquals(durationfmt(60), "01:00") self.assertEquals(bu.durationfmt(60), "01:00")
self.assertEquals(durationfmt(119), "01:59") self.assertEquals(bu.durationfmt(119), "01:59")
self.assertEquals(durationfmt(3600), "01:00:00") self.assertEquals(bu.durationfmt(3600), "01:00:00")
self.assertEquals(durationfmt(7265), "02:01:05") self.assertEquals(bu.durationfmt(7265), "02:01:05")
def test_execute(self): def test_execute(self):
execute(self.some_command_with_args) bu.execute(self.some_command_with_args)
self.assertTrue(self.popen.mock.popen.called) self.assertTrue(self.popen.mock.popen.called)
self.popen.mock.popen.assert_call(self.some_command_with_args) self.popen.mock.popen.assert_call(self.some_command_with_args)
self.assertTrue(self.popen.mock.communicate.called) self.assertTrue(self.popen.mock.communicate.called)
def test_execute_nowait(self): def test_execute_nowait(self):
execute(self.some_command_with_args, False) bu.execute(self.some_command_with_args, False)
self.assertTrue(self.popen.mock.popen.called) self.assertTrue(self.popen.mock.popen.called)
self.popen.mock.popen.assert_call(self.some_command_with_args) self.popen.mock.popen.assert_call(self.some_command_with_args)
self.assertFalse(self.popen.mock.communicate.called) self.assertFalse(self.popen.mock.communicate.called)
@ -51,6 +52,22 @@ class TestUtil(unittest.TestCase):
self.popen.mock.returncode = 1 self.popen.mock.returncode = 1
with self.assertRaises(RuntimeError): with self.assertRaises(RuntimeError):
execute(self.some_command_with_args) bu.execute(self.some_command_with_args)
def test_which(self):
# test for a binary that has to be somewhere
print(bu.which("ls"))
self.assertTrue(re.search('/(ls)$', bu.which("ls")))
# test for a binary that is not necessarily there
program = "iwgetid"
self.assertTrue(
bu.which(program) is None or
re.search('/(' + program + ')$', bu.which(program))
)
# test if which also works with garbage input
self.assertTrue(bu.which("qwertygarbage") is None)
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -15,6 +15,9 @@
"load": { "prefix": "" }, "load": { "prefix": "" },
"layout": { "prefix": "" }, "layout": { "prefix": "" },
"layout-xkb": { "prefix": "" }, "layout-xkb": { "prefix": "" },
"notmuch_count": { "empty": {"prefix": "\uf0e0" },
"items": {"prefix": "\uf0e0" }
},
"todo": { "empty": {"prefix": "" }, "todo": { "empty": {"prefix": "" },
"items": {"prefix": "" }, "items": {"prefix": "" },
"uptime": {"prefix": "" } "uptime": {"prefix": "" }