Merge pull request #2 from tobi-wan-kenobi/master

update
This commit is contained in:
Martin Morlot 2019-10-20 11:08:47 +02:00 committed by GitHub
commit 10b3f317f4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 149 additions and 67 deletions

View file

@ -1,6 +1,10 @@
--- ---
name: Bug Report name: Bug Report
about: Something is broken / doesn't work as expected about: Something doesn't work (as expected)
title: ''
labels: ''
assignees: ''
--- ---
### Bug Report ### Bug Report
@ -8,17 +12,12 @@ about: Something is broken / doesn't work as expected
#### Summary #### Summary
Affected module: <module name> Affected module: <module name>
Description: #### Description:
<description> <description>
#### What is the current behaviour and what is the expected behaviour?
#### How to reproduce #### How to reproduce
<!-- Please provide steps on how to reproduce the issue (screenshots would be great) --> <!-- Please provide steps on how to reproduce the issue (screenshots would be great) -->
#### Expected behavior
<!-- What was the expected (correct) behavior? -->
<!-- <!--
If you are having problems with fonts, please read: If you are having problems with fonts, please read:
https://github.com/tobi-wan-kenobi/bumblebee-status/issues/228 https://github.com/tobi-wan-kenobi/bumblebee-status/issues/228
@ -29,4 +28,3 @@ https://github.com/tobi-wan-kenobi/bumblebee-status/issues/233
Please note FontAwesome 5 is currently not supported: Please note FontAwesome 5 is currently not supported:
https://github.com/tobi-wan-kenobi/bumblebee-status/issues/239 https://github.com/tobi-wan-kenobi/bumblebee-status/issues/239
--> -->

View file

@ -1,6 +1,10 @@
--- ---
name: Feature Request name: Feature Request
about: You have a neat idea that should be implemented? about: You have a neat idea that should be implemented?
title: ''
labels: ''
assignees: ''
--- ---
### Feature Request ### Feature Request

View file

@ -1,20 +0,0 @@
---
name: ❓ Support Question
about: Have a problem that you can't figure out?
---
<!-- Fill in the relevant information below to help triage your issue. -->
<!--
Note: All issues will instant closed if the issue template is not complete. Please understand that it is easier for us if you fill out the template to help you faster.
!All text inside \<\!-- \--\> will be hidden from us so please remove the arrows in the statements below.
-->
| Q | A
|------------ | -----
| Version | x
#### Support Question
<!-- Describe the issue you are facing here. -->

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, 48 of the modules are from various contributors (!), and only 19 from myself.** **Many, many thanks to all contributors! As of now, 49 of the modules are from various contributors (!), and only 19 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)
@ -189,7 +189,7 @@ Modules and commandline utilities are only required for modules, the core itself
* netifaces (for the modules 'nic', 'traffic') * netifaces (for the modules 'nic', 'traffic')
* requests (for the modules 'weather', 'github', 'getcrypto', 'stock', 'currency', 'sun') * requests (for the modules 'weather', 'github', 'getcrypto', 'stock', 'currency', 'sun')
* power (for the module 'battery') * power (for the module 'battery')
* dbus (for the module 'spotify') * dbus (for the module 'spotify', 'deezer')
* i3ipc (for the module 'title') * i3ipc (for the module 'title')
* pacman-contrib (for module 'arch-update') * pacman-contrib (for module 'arch-update')
* docker (for the module 'docker_ps') * docker (for the module 'docker_ps')

View file

@ -25,9 +25,12 @@ except ImportError:
class Module(bumblebee.engine.Module): class Module(bumblebee.engine.Module):
def __init__(self, engine, config): def __init__(self, engine, config):
self._batteries = [] self._batteries = []
for battery in os.listdir('/sys/class/power_supply/'): try:
if not any(i in battery for i in ['AC', 'hidpp']): for battery in os.listdir('/sys/class/power_supply/'):
self._batteries.append("/sys/class/power_supply/" + battery) if not any(i in battery for i in ['AC', 'hidpp']):
self._batteries.append("/sys/class/power_supply/" + battery)
except:
pass
super(Module, self).__init__(engine, config, bumblebee.output.Widget(full_text=self.capacity)) super(Module, self).__init__(engine, config, bumblebee.output.Widget(full_text=self.capacity))
@ -67,11 +70,7 @@ class Module(bumblebee.engine.Module):
errors += 1 errors += 1
if errors == len(self._batteries): if errors == len(self._batteries):
# if all batteries return errors, but we are still running return "n/a"
# assume we are on A/C
widget.set("ac", True)
widget.set("capacity", 100)
return "ac"
capacity = int( float(self.energy_now) / float(self.energy_full) * 100.0) capacity = int( float(self.energy_now) / float(self.energy_full) * 100.0)
capacity = capacity if capacity < 100 else 100 capacity = capacity if capacity < 100 else 100

View file

@ -0,0 +1,77 @@
# pylint: disable=C0111,R0903
"""Displays the current song being played
Requires the following library:
* python-dbus
Parameters:
* deezer.format: Format string (defaults to "{artist} - {title}")
Available values are: {album}, {title}, {artist}, {trackNumber}, {playbackStatus}
* deezer.previous: Change binding for previous song (default is left click)
* deezer.next: Change binding for next song (default is right click)
* deezer.pause: Change binding for toggling pause (default is middle click)
Available options for deezer.previous, deezer.next and deezer.pause are:
LEFT_CLICK, RIGHT_CLICK, MIDDLE_CLICK, SCROLL_UP, SCROLL_DOWN
"""
import bumblebee.input
import bumblebee.output
import bumblebee.engine
from bumblebee.output import scrollable
try:
import dbus
except ImportError:
pass
class Module(bumblebee.engine.Module):
def __init__(self, engine, config):
super(Module, self).__init__(engine, config,
bumblebee.output.Widget(full_text=self.deezer)
)
buttons = {"LEFT_CLICK":bumblebee.input.LEFT_MOUSE,
"RIGHT_CLICK":bumblebee.input.RIGHT_MOUSE,
"MIDDLE_CLICK":bumblebee.input.MIDDLE_MOUSE,
"SCROLL_UP":bumblebee.input.WHEEL_UP,
"SCROLL_DOWN":bumblebee.input.WHEEL_DOWN,
}
self._song = ""
self._format = self.parameter("format", "{artist} - {title}")
prev_button = self.parameter("previous", "LEFT_CLICK")
next_button = self.parameter("next", "RIGHT_CLICK")
pause_button = self.parameter("pause", "MIDDLE_CLICK")
cmd = "dbus-send --session --type=method_call --dest=org.mpris.MediaPlayer2.deezer \
/org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player."
engine.input.register_callback(self, button=buttons[prev_button],
cmd=cmd + "Previous")
engine.input.register_callback(self, button=buttons[next_button],
cmd=cmd + "Next")
engine.input.register_callback(self, button=buttons[pause_button],
cmd=cmd + "PlayPause")
## @scrollable
def deezer(self, widget):
return str(self._song)
def hidden(self):
return str(self._song) == ""
def update(self, widgets):
try:
bus = dbus.SessionBus()
deezer = bus.get_object("org.mpris.MediaPlayer2.deezer", "/org/mpris/MediaPlayer2")
deezer_iface = dbus.Interface(deezer, 'org.freedesktop.DBus.Properties')
props = deezer_iface.Get('org.mpris.MediaPlayer2.Player', 'Metadata')
playback_status = str(deezer_iface.Get('org.mpris.MediaPlayer2.Player', 'PlaybackStatus'))
self._song = self._format.format(album=str(props.get('xesam:album')),
title=str(props.get('xesam:title')),
artist=','.join(props.get('xesam:artist')),
trackNumber=str(props.get('xesam:trackNumber')),
playbackStatus=u"\u25B6" if playback_status=="Playing" else u"\u258D\u258D" if playback_status=="Paused" else "",)
except Exception:
self._song = ""
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -93,13 +93,21 @@ class Module(bumblebee.engine.Module):
return temperature return temperature
def get_mhz(self): def get_mhz(self):
mhz = None
try: try:
output = open("/sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq").read() output = open("/sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq").read()
mhz = int(float(output)/1000.0) mhz = int(float(output)/1000.0)
except: except:
output = open("/proc/cpuinfo").read() output = open("/proc/cpuinfo").read()
m = re.search(r"cpu MHz\s+:\s+(\d+)", output) m = re.search(r"cpu MHz\s+:\s+(\d+)", output)
mhz = int(m.group(1)) if m:
mhz = int(m.group(1))
else:
m = re.search(r"BogoMIPS\s+:\s+(\d+)", output)
if m:
return "{} BogoMIPS".format(int(m.group(1)))
if not mhz:
return "n/a"
if mhz < 1000: if mhz < 1000:
return "{} MHz".format(mhz) return "{} MHz".format(mhz)

View file

@ -132,18 +132,25 @@ class Module(bumblebee.engine.Module):
return output return output
def _cpu(self, _): def _cpu(self, _):
mhz = None
try: try:
output = open("/sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq").read() output = open("/sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq").read()
mhz = int(float(output)/1000.0) mhz = int(float(output)/1000.0)
except: except:
output = open("/proc/cpuinfo").read() output = open("/proc/cpuinfo").read()
m = re.search(r"cpu MHz\s+:\s+(\d+)", output) m = re.search(r"cpu MHz\s+:\s+(\d+)", output)
mhz = int(m.group(1)) if m:
mhz = int(m.group(1))
else:
m = re.search(r"BogoMIPS\s+:\s+(\d+)", output)
if m:
return "{} BogoMIPS".format(int(m.group(1)))
if not mhz:
return "n/a"
if mhz < 1000: if mhz < 1000:
return "{} MHz".format(mhz) return "{} MHz".format(mhz)
else: else:
return "{:0.01f} GHz".format(float(mhz)/1000.0) return "{:0.01f} GHz".format(float(mhz)/1000.0)
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -1,7 +1,7 @@
# -*- coding: UTF-8 -*- # -*- coding: UTF-8 -*-
# pylint: disable=C0111,R0903 # pylint: disable=C0111,R0903
"""Display a stock quote from yahoo finance. """Display a stock quote from worldtradingdata.com
Requires the following python packages: Requires the following python packages:
* requests * requests
@ -9,7 +9,6 @@ Requires the following python packages:
Parameters: Parameters:
* stock.symbols : Comma-separated list of symbols to fetch * stock.symbols : Comma-separated list of symbols to fetch
* stock.change : Should we fetch change in stock value (defaults to True) * stock.change : Should we fetch change in stock value (defaults to True)
* stock.currencies : List of symbols to go with the values (default $)
""" """
import bumblebee.input import bumblebee.input
@ -17,6 +16,7 @@ import bumblebee.output
import bumblebee.engine import bumblebee.engine
import bumblebee.util import bumblebee.util
import json
import requests import requests
import logging import logging
@ -28,36 +28,27 @@ class Module(bumblebee.engine.Module):
) )
self._symbols = self.parameter('symbols', '') self._symbols = self.parameter('symbols', '')
self._change = bumblebee.util.asbool(self.parameter('change', True)) self._change = bumblebee.util.asbool(self.parameter('change', True))
self._currencies = self.parameter('currencies', None) self._value = None
self._baseurl = 'http://download.finance.yahoo.com/d/quotes.csv'
self._value = self.fetch()
self.interval(60) self.interval(60)
if not self._currencies:
self._currencies = '$' * len(self._symbols)
# The currencies could be unicode, like the € symbol. Convert to a unicode object.
if hasattr(self._currencies, 'decode'):
self._currencies = self._currencies.decode('utf-8', 'ignore')
def value(self, widget): def value(self, widget):
results = [] results = []
if not self._value: if not self._value:
return 'n/a' return 'n/a'
for i, val in enumerate(self._value.split('\n')): data = json.loads(self._value)
try:
currency_symbol = self._currencies[i] for symbol in data['quoteResponse']['result']:
except: valkey = 'regularMarketChange' if self._change else 'regularMarketPrice'
currency_symbol = '$' sym = 'n/a' if not 'symbol' in symbol else symbol['symbol']
results.append('%s%s' % (currency_symbol, val)) currency = 'USD' if not 'currency' in symbol else symbol['currency']
val = 'n/a' if not valkey in symbol else '{:.2f}'.format(symbol[valkey])
results.append('{} {} {}'.format(sym, val, currency))
return u' '.join(results) return u' '.join(results)
def fetch(self): def fetch(self):
if self._symbols: if self._symbols:
url = self._baseurl url = 'https://query1.finance.yahoo.com/v7/finance/quote?symbols='
url += '?s=%s&f=l1' % self._symbols url += self._symbols + '&fields=regularMarketPrice,currency,regularMarketChange'
if self._change:
url += 'c1'
return requests.get(url).text.strip() return requests.get(url).text.strip()
else: else:
logging.error('unable to retrieve stock exchange rate') logging.error('unable to retrieve stock exchange rate')

View file

@ -7,15 +7,14 @@ import json
import uuid import uuid
import bumblebee.store import bumblebee.store
import bumblebee.util
_TrueValues = ["true", "t", "yes", "y", "1"]
def scrollable(func): def scrollable(func):
def wrapper(module, widget): def wrapper(module, widget):
text = func(module, widget) text = func(module, widget)
if not text: return text if not text: return text
width = widget.get("theme.width", module.parameter("width", 30)) width = widget.get("theme.width", module.parameter("width", 30))
if module.parameter("scrolling.makewide", "true").lower() in _TrueValues: if bumblebee.util.asbool(module.parameter("scrolling.makewide", "true")):
widget.set("theme.minwidth", "A"*width) widget.set("theme.minwidth", "A"*width)
if len(text) <= width: if len(text) <= width:
return text return text

View file

@ -69,5 +69,15 @@ class TestUtil(unittest.TestCase):
# test if which also works with garbage input # test if which also works with garbage input
self.assertTrue(bu.which("qwertygarbage") is None) self.assertTrue(bu.which("qwertygarbage") is None)
def test_asbool(self):
for val in ("t", "true", "y", "yes", "on", "1", 1, True):
self.assertTrue(bu.asbool(val))
if isinstance(val, str):
self.assertTrue(bu.asbool(val.upper()))
for val in ("f", "false", "n", "no", "off", "0", 0, False):
self.assertFalse(bu.asbool(val))
if isinstance(val, str):
self.assertFalse(bu.asbool(val.upper()))
# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 # vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

View file

@ -247,6 +247,9 @@
"github": { "github": {
"prefix": "github" "prefix": "github"
}, },
"deezer": {
"prefix": ""
},
"spotify": { "spotify": {
"prefix": "" "prefix": ""
}, },

View file

@ -172,6 +172,9 @@
"github": { "github": {
"prefix": "  " "prefix": "  "
}, },
"deezer": {
"prefix": "  "
},
"spotify": { "spotify": {
"prefix": "  " "prefix": "  "
}, },

View file

@ -153,6 +153,9 @@
"github": { "github": {
"prefix": "\uf233" "prefix": "\uf233"
}, },
"deezer": {
"prefix": "\uf305"
},
"spotify": { "spotify": {
"prefix": "\uf305" "prefix": "\uf305"
}, },