Hello community,
here is the log from the commit of package python-py3status for
openSUSE:Factory checked in at 2019-10-21 12:32:12
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-py3status (Old)
and /work/SRC/openSUSE:Factory/.python-py3status.new.2352 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-py3status"
Mon Oct 21 12:32:12 2019 rev:5 rq:741421 version:3.21
Changes:
--------
--- /work/SRC/openSUSE:Factory/python-py3status/python-py3status.changes
2019-09-11 10:39:35.827228562 +0200
+++
/work/SRC/openSUSE:Factory/.python-py3status.new.2352/python-py3status.changes
2019-10-21 12:32:16.796224548 +0200
@@ -1,0 +2,9 @@
+Mon Oct 21 02:51:56 UTC 2019 - John Vandenberg <[email protected]>
+
+- Recommend i3status, with note that it is optional
+- Add configuration.rst to docs
+- Update to v3.21
+ * New module networkmanager
+ * many other fixes, see CHANGELOG
+
+-------------------------------------------------------------------
Old:
----
py3status-3.20.tar.gz
New:
----
py3status-3.21.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-py3status.spec ++++++
--- /var/tmp/diff_new_pack.cfPobE/_old 2019-10-21 12:32:17.524225373 +0200
+++ /var/tmp/diff_new_pack.cfPobE/_new 2019-10-21 12:32:17.528225378 +0200
@@ -18,9 +18,9 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-py3status
-Version: 3.20
+Version: 3.21
Release: 0
-Summary: Extensible i3status wrapper written in python
+Summary: Python extensible i3status wrapper
License: BSD-3-Clause
Group: Development/Languages/Python
URL: https://github.com/ultrabug/py3status
@@ -32,6 +32,7 @@
BuildRequires: fdupes
BuildRequires: python-rpm-macros
Requires: python-setuptools
+Recommends: i3status
Recommends: python-gevent >= 1.1
Recommends: python-pyudev >= 0.21.0
BuildArch: noarch
@@ -51,6 +52,9 @@
- handling click events on your i3bar and play with them in no time
- seeing your clock tick every second whatever your i3status interval
+py3status has a standalone mode allowing to bypass i3status when you need
+a py3status-modules-only i3bar.
+
%prep
%setup -q -n py3status-%{version}
@@ -77,7 +81,7 @@
%files %{python_files}
%license LICENSE
-%doc README.rst CHANGELOG
+%doc README.rst CHANGELOG doc/configuration.rst
%python_alternative %{_bindir}/py3status
%python_alternative %{_bindir}/py3-cmd
%{python_sitelib}/*
++++++ py3status-3.20.tar.gz -> py3status-3.21.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py3status-3.20/CHANGELOG new/py3status-3.21/CHANGELOG
--- old/py3status-3.20/CHANGELOG 2019-08-06 21:16:55.000000000 +0200
+++ new/py3status-3.21/CHANGELOG 2019-10-13 12:33:03.000000000 +0200
@@ -1,3 +1,23 @@
+version 3.21 (2019-10-13)
+* implement global request_retry_times and request_retry_wait options (#1847)
+* arch_updates module: checkupdates throws exit code on zero updates (#1848),
by Daniel Jenssen
+* bitcoin_price module: change api request to http (#1836), by dosera
+* coin_market module: skip empty datas (#1849), by lasers
+* fix `long_description_content_type` missing
+* fix entry_point typo in docstring (#1830), by Oliver Bestwalter
+* fix project's long_description has invalid markup which will not be rendered
on PyPI
+* i3status: support memory module, remove valid_config_param (#1833), by lasers
+* new module networkmanager: display network status (#1766), by Kevin Pulo
+* module testing: fix testmode fails because it uses is_gevent property.
(#1832), by Valdur Kana
+* mpris module: fix KeyError exception closes #1827 (#1831), by lasers
+* nvidia_temp module: add safeformat for separator, rename separator (#1846),
by lasers
+* spotify module: add playback placeholder (#1829), by Bazyli Cyran
+* sysdata module: prevent a divide by zero on empty swap (#1838), by Pierre
GINDRAUD
+* weather_owm module: add safeformat for separator, rename separator (#1845),
by lasers
+* weather_own module: add thresholds for humidity (#1844), by lasers
+* wifi module: fix bug introduced in PR #1834 (#1835), by ownaginatious
+* wifi module: specify device by name or MAC address (#1834), by ownaginatious
+
version 3.20 (2019-08-06)
* IMPORTANT: py3status now supports importing modules from pypi packages, see
'writing modules' section on docs!
* introduce entry point based discovery of packaged custom modules (#1823), by
Oliver Bestwalter
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py3status-3.20/PKG-INFO new/py3status-3.21/PKG-INFO
--- old/py3status-3.20/PKG-INFO 2019-08-06 21:24:51.000000000 +0200
+++ new/py3status-3.21/PKG-INFO 2019-10-13 12:40:27.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: py3status
-Version: 3.20
+Version: 3.21
Summary: py3status: an extensible i3status wrapper written in python
Home-page: https://github.com/ultrabug/py3status
Author: Ultrabug
@@ -150,6 +150,6 @@
Classifier: Programming Language :: Python :: 3.7
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Description-Content-Type: text/x-rst
-Provides-Extra: all
-Provides-Extra: gevent
Provides-Extra: udev
+Provides-Extra: gevent
+Provides-Extra: all
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py3status-3.20/doc/configuration.rst
new/py3status-3.21/doc/configuration.rst
--- old/py3status-3.20/doc/configuration.rst 2019-06-27 15:59:41.000000000
+0200
+++ new/py3status-3.21/doc/configuration.rst 2019-10-13 12:31:22.000000000
+0200
@@ -937,9 +937,14 @@
by all package managers.
-Request Timeout
+Request Settings
--------------------------------------------------------------
+Handling timeouts
+^^^^^^^^^^^^^^^^^
+
+Timeouts are handled thanks to the global ``request_timeout`` setting.
+
.. note::
New in version 3.16
@@ -954,3 +959,34 @@
exchange_rate {
request_timeout = 10
}
+
+
+Handling retries
+^^^^^^^^^^^^^^^^
+
+Retries are handled thanks to the global ``request_retry_times`` and
+``request_retry_wait`` settings.
+
+.. note::
+ New in version 3.21
+
+Requests failing due to network unavailability or remote server timeouts are
+retried automatically ``request_retry_times`` times (default ``3``) at a
+``request_retry_wait`` (default ``2``) seconds interval.
+
+This allows to be more graceful to i3 startup when network is not up yet or to
+short network disruptions and not display an error on the bar in that case.
+
+To find out if your module supports that, look for ``self.py3.request`` in the
+code.
+
+.. code-block:: py3status
+ :caption: Example
+
+ # try to contact the OWM API 10 times every 5 seconds before displaying
+ # an error on the bar for the module
+ # that is equivalent to 50 seconds of retrying before an error occurs
+ weather_owm {
+ request_retry_times = 10
+ request_retry_wait = 5
+ }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py3status-3.20/py3status/constants.py
new/py3status-3.21/py3status/constants.py
--- old/py3status-3.20/py3status/constants.py 2019-06-27 15:59:41.000000000
+0200
+++ new/py3status-3.21/py3status/constants.py 2019-10-02 21:52:30.000000000
+0200
@@ -23,6 +23,7 @@
"cpu_temperature",
"disk",
"ethernet",
+ "memory",
"path_exists",
"run_watch",
"tztime",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py3status-3.20/py3status/core.py
new/py3status-3.21/py3status/core.py
--- old/py3status-3.20/py3status/core.py 2019-08-06 21:10:22.000000000
+0200
+++ new/py3status-3.21/py3status/core.py 2019-10-02 21:52:30.000000000
+0200
@@ -503,7 +503,7 @@
modules_list: ['weather_yahoo paris', 'pewpew', 'net_rate']
user_modules: {
'weather_yahoo': ('/etc/py3status.d/', 'weather_yahoo.py'),
- 'pewpew': (entry_point', <Py3Status class>),
+ 'pewpew': ('entry_point', <Py3Status class>),
}
"""
for module in modules_list:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py3status-3.20/py3status/i3status.py
new/py3status-3.21/py3status/i3status.py
--- old/py3status-3.20/py3status/i3status.py 2019-04-20 18:39:38.000000000
+0200
+++ new/py3status-3.21/py3status/i3status.py 2019-10-02 21:52:30.000000000
+0200
@@ -255,22 +255,6 @@
Thread.__init__(self)
self.error = None
self.i3modules = {}
- self.i3status_module_names = [
- "battery",
- "cpu_temperature",
- "cpu_usage",
- "ddate",
- "disk",
- "ethernet",
- "ipv6",
- "load",
- "path_exists",
- "run_watch",
- "time",
- "tztime",
- "volume",
- "wireless",
- ]
self.i3status_pipe = None
self.i3status_path = py3_wrapper.config["i3status_path"]
self.json_list = None
@@ -304,20 +288,6 @@
if module.is_time_module:
self.time_modules.append(module)
- def valid_config_param(self, param_name, cleanup=False):
- """
- Check if a given section name is a valid parameter for i3status.
- """
- if cleanup:
- valid_config_params = [
- _
- for _ in self.i3status_module_names
- if _ not in ["cpu_usage", "ddate", "ipv6", "load", "time"]
- ]
- else:
- valid_config_params = self.i3status_module_names + ["general",
"order"]
- return param_name.split(" ")[0] in valid_config_params
-
def set_responses(self, json_list):
"""
Set the given i3status responses on their respective configuration.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py3status-3.20/py3status/module.py
new/py3status-3.21/py3status/module.py
--- old/py3status-3.20/py3status/module.py 2019-08-06 21:10:22.000000000
+0200
+++ new/py3status-3.21/py3status/module.py 2019-10-13 12:16:40.000000000
+0200
@@ -60,6 +60,7 @@
self.testing = self.config.get("testing")
self.urgent = False
self.i3bar_gaps_urgent_options = {}
+ self.hidden = False
# create a nice name for the module that matches what the module is
# called in the user config
@@ -300,11 +301,23 @@
self.last_output = output
self._py3_wrapper.notify_update(self.module_full_name, urgent)
+ def hide(self):
+ self.hidden = True
+ self.force_update()
+
+
+ def unhide(self):
+ self.hidden = Falses
+ self.wake()
+
def get_latest(self):
"""
return latest output.
"""
- return self.last_output
+ if self.hidden:
+ return ""
+ else:
+ return self.last_output
def set_module_options(self, module):
"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py3status-3.20/py3status/module_test.py
new/py3status-3.21/py3status/module_test.py
--- old/py3status-3.20/py3status/module_test.py 2019-04-20 18:40:09.000000000
+0200
+++ new/py3status-3.21/py3status/module_test.py 2019-10-02 21:52:30.000000000
+0200
@@ -34,6 +34,7 @@
self.lock = Event()
self.output_modules = {}
self.running = True
+ self.is_gevent = False
self.lock.set()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py3status-3.20/py3status/modules/arch_updates.py
new/py3status-3.21/py3status/modules/arch_updates.py
--- old/py3status-3.20/py3status/modules/arch_updates.py 2019-06-27
15:59:41.000000000 +0200
+++ new/py3status-3.21/py3status/modules/arch_updates.py 2019-10-13
12:16:47.000000000 +0200
@@ -78,8 +78,8 @@
try:
updates = self.py3.command_output(["checkupdates"])
return len(updates.splitlines())
- except self.py3.CommandError:
- return None
+ except self.py3.CommandError as ce:
+ return None if ce.error else 0
def _get_auracle_updates(self):
try:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py3status-3.20/py3status/modules/bitcoin_price.py
new/py3status-3.21/py3status/modules/bitcoin_price.py
--- old/py3status-3.20/py3status/modules/bitcoin_price.py 2019-04-20
18:39:38.000000000 +0200
+++ new/py3status-3.21/py3status/modules/bitcoin_price.py 2019-10-02
21:52:30.000000000 +0200
@@ -40,7 +40,6 @@
"""
STRING_UNAVAILABLE = "N/A"
-STRING_ERROR = "bitcoin_price: site unreachable"
class Py3status:
@@ -104,7 +103,7 @@
"YEN": "¥",
}
self.last_price = 0
- self.url = "https://api.bitcoincharts.com/v1/markets.json"
+ self.url = "http://api.bitcoincharts.com/v1/markets.json"
def _get_price(self, data, market, field):
"""
@@ -116,15 +115,18 @@
return m[field]
def bitcoin_price(self):
+ response = {
+ "full_text": "",
+ "cached_until": self.py3.time_in(self.cache_timeout),
+ }
+
# get the data from bitcoincharts api
try:
data = self.py3.request(self.url).json()
- except self.py3.RequestException:
- return {
- "cached_until": self.py3.time_in(self.cache_timeout),
- "color": self.py3.COLOR_BAD,
- "full_text": "" if self.hide_on_error else STRING_ERROR,
- }
+ except self.py3.RequestException as err:
+ if self.hide_on_error:
+ return response
+ self.py3.error(str(err))
# get the rate for each market given
color_rate, rates, markets = None, [], self.markets.split(",")
@@ -151,8 +153,6 @@
)
)
- response = {"cached_until": self.py3.time_in(self.cache_timeout)}
-
# colorize if an index is given or only one market is selected
if len(rates) == 1 or self.color_index > -1:
if self.last_price == 0:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py3status-3.20/py3status/modules/coin_market.py
new/py3status-3.21/py3status/modules/coin_market.py
--- old/py3status-3.20/py3status/modules/coin_market.py 2019-04-20
18:40:09.000000000 +0200
+++ new/py3status-3.21/py3status/modules/coin_market.py 2019-10-13
12:16:47.000000000 +0200
@@ -222,7 +222,7 @@
# first_use bad? the user entered bad markets. stop here (error).
# otherwise, make a limit for first time on 1000+ coins.
- if data and self.first_use:
+ if self.first_use:
self.first_use = False
if not is_equal:
self.py3.error("bad markets")
@@ -271,7 +271,7 @@
def coin_market(self):
# first 1000+ coins (then %s coins)
coin_data = self._get_coin_data()
- if not self.limit:
+ if coin_data and not self.limit:
# strip, compare, and maybe update again
coin_data = self._organize_data(coin_data)
data = self._manipulate_data(coin_data)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py3status-3.20/py3status/modules/mpris.py
new/py3status-3.21/py3status/modules/mpris.py
--- old/py3status-3.20/py3status/modules/mpris.py 2019-06-27
15:59:41.000000000 +0200
+++ new/py3status-3.21/py3status/modules/mpris.py 2019-10-02
21:52:30.000000000 +0200
@@ -394,7 +394,10 @@
if not player_id.startswith(SERVICE_BUS):
return False
- player = self._dbus.get(player_id, SERVICE_BUS_URL)
+ try:
+ player = self._dbus.get(player_id, SERVICE_BUS_URL)
+ except KeyError:
+ return False
if player.Identity not in self._mpris_names:
self._mpris_names[player.Identity] = player_id.split(".")[-1]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py3status-3.20/py3status/modules/networkmanager.py
new/py3status-3.21/py3status/modules/networkmanager.py
--- old/py3status-3.20/py3status/modules/networkmanager.py 1970-01-01
01:00:00.000000000 +0100
+++ new/py3status-3.21/py3status/modules/networkmanager.py 2019-10-02
21:52:30.000000000 +0200
@@ -0,0 +1,184 @@
+# -*- coding: utf-8 -*-
+"""
+Display NetworkManager fields via nmcli, a command-line tool.
+
+Configuration parameters:
+ cache_timeout: refresh interval for this module (default 10)
+ devices: specify a list of devices to use (default ['[e|w]*'])
+ format: display format for this module (default '{format_device}')
+ format_device: format for devices
+ *(default "[\?if=general_connection {general_device}[\?soft ]"
+ "[\?color=ap1_signal {ap1_ssid} {ap1_bars} {ap1_signal}%][\?soft ]"
+ "[\?color=good {ip4_address1}]]")*
+ format_device_separator: show separator if more than one (default ' ')
+ thresholds: specify color thresholds to use
+ (default [(0, 'bad'), (30, 'degraded'), (65, 'good')])
+
+Format placeholders:
+ {format_device} format for devices
+
+Format_device placeholders:
+ {general_connection} eg Py3status, Wired Connection 1
+ {general_device} eg wlp3s0b1, enp2s0
+ {general_type} eg wifi, ethernet
+ {ap1_bars} signal strength in bars, eg ▂▄▆_
+ {ap1_chan} wifi channel, eg 6
+ {ap1_mode} network mode, eg Adhoc or Infra
+ {ap1_rate} bitrate, eg 54 Mbit/s
+ {ap1_security} signal security, eg WPA2
+ {ap1_signal} signal strength in percentage, eg 63
+ {ap1_ssid} ssid name, eg Py3status
+ {ip4_address1} eg 192.168.1.108
+ {ip6_address1} eg 0000::0000:0000:0000:0000
+
+ Use `nmcli --terse --fields=general,ap,ip4,ip6 device show` for a full
list of
+ supported NetworkManager fields to use. Not all of NetworkManager fields
will
+ be usable. See `man nmcli` for more information.
+
+Color thresholds:
+ xxx: print a color based on the value of `xxx` placeholder
+
+Requires:
+ nmcli: cli configuration utility for NetworkManager
+
+Examples:
+```
+# specify devices to use
+networkmanager {
+ devices = ['e*'] # ethernet only
+ devices = ['w*'] # wireless only
+ devices = [] # ethernet, wireless, lo, etc
+}
+```
+
+@author Kevin Pulo <[email protected]>
+@license BSD
+
+SAMPLE OUTPUT
+[{'full_text': 'enp2s0 '}, {'color': '#00FF00', 'full_text': '192.168.1.108'}]
+
+wifi
+[
+ {'full_text': 'wlp3s0b1 '},
+ {'color': '#FFFF00', 'full_text': 'Py3net ▂▄__ 54% '},
+ {'color': '#00FF00', 'full_text': '192.168.1.106'},
+]
+"""
+
+from fnmatch import fnmatch
+
+STRING_NOT_INSTALLED = "not installed"
+
+
+class Py3status:
+ """
+ """
+
+ # available configuration parameters
+ cache_timeout = 10
+ devices = ["[e|w]*"]
+ format = "{format_device}"
+ format_device = (
+ "[\?if=general_connection {general_device}[\?soft ]"
+ "[\?color=ap1_signal {ap1_ssid} {ap1_bars} {ap1_signal}%][\?soft ]"
+ "[\?color=good {ip4_address1}]]"
+ )
+ format_device_separator = " "
+ thresholds = [(0, "bad"), (30, "degraded"), (65, "good")]
+
+ def post_config_hook(self):
+ command = "nmcli --terse --colors=no"
+ if not self.py3.check_commands(command.split()[0]):
+ raise Exception(STRING_NOT_INSTALLED)
+
+ self.first_run = True
+
+ addresses = [
+ x.split("_")[0]
+ for x in self.py3.get_placeholders_list(
+ self.format_device, "ip[46]_address[0123456789]"
+ )
+ ]
+
+ self.nmcli_command = "{} --fields={} device show".format(
+ command, ",".join(["general", "ap"] + addresses)
+ ).split()
+ self.caches = {"lines": {}, "devices": {}}
+ self.devices = {"list": [], "devices": self.devices}
+
+ self.thresholds_init =
self.py3.get_color_names_list(self.format_device)
+
+ def _update_key(self, key):
+ for old, new in [("[", ""), ("]", ""), (".", "_"), ("-", "_")]:
+ key = key.replace(old, new)
+ return key.lower()
+
+ def networkmanager(self):
+ nm_data = self.py3.command_output(self.nmcli_command, localized=True)
+ new_device = []
+
+ for chunk in nm_data.split("\n\n"):
+ lines = chunk.splitlines()
+ key, value = lines[0].split(":", 1)
+ if self.first_run:
+ if self.devices["devices"]:
+ for _filter in self.devices["devices"]:
+ if fnmatch(value, _filter):
+ self.devices["list"].append(value)
+ if value not in self.devices["list"]:
+ continue
+
+ try:
+ key = self.caches["devices"][key]
+ except KeyError:
+ new_key = self._update_key(key)
+
+ self.caches["devices"][key] = new_key
+ key = self.caches["devices"][key]
+
+ device = {key: value}
+
+ for line in lines[1:]:
+ try:
+ key, value = self.caches["lines"][line]
+ except (KeyError, ValueError):
+ key, value = line.split(":", 1)
+ key = self._update_key(key)
+ if "IP" in line and "ADDRESS" in line:
+ value = value.split("/")[0]
+ else:
+ try:
+ value = int(value)
+ except ValueError:
+ pass
+
+ self.caches["lines"][line] = (key, value)
+
+ device[key] = value
+
+ for x in self.thresholds_init:
+ if x in device:
+ self.py3.threshold_get_color(device[x], x)
+
+ new_device.append(self.py3.safe_format(self.format_device, device))
+
+ format_device_separator =
self.py3.safe_format(self.format_device_separator)
+ format_device = self.py3.composite_join(format_device_separator,
new_device)
+
+ self.first_run = False
+
+ return {
+ "cache_until": self.py3.time_in(self.cache_timeout),
+ "full_text": self.py3.safe_format(
+ self.format, {"format_device": format_device}
+ ),
+ }
+
+
+if __name__ == "__main__":
+ """
+ Run module in test mode.
+ """
+ from py3status.module_test import module_test
+
+ module_test(Py3status)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py3status-3.20/py3status/modules/nvidia_temp.py
new/py3status-3.21/py3status/modules/nvidia_temp.py
--- old/py3status-3.20/py3status/modules/nvidia_temp.py 2019-04-20
18:40:09.000000000 +0200
+++ new/py3status-3.21/py3status/modules/nvidia_temp.py 2019-10-13
12:16:47.000000000 +0200
@@ -6,7 +6,7 @@
cache_timeout: refresh interval for this module (default 10)
format: display format for this module (default 'GPU: {format_temp}')
format_temp: display format for temperatures (default '{temp}°C')
- temp_separator: temperature separator (if more than one) (default '|')
+ format_temp_separator: show separator if more than one (default ' ')
Format placeholders:
{format_temp} format for temperatures
@@ -43,7 +43,7 @@
cache_timeout = 10
format = "GPU: {format_temp}"
format_temp = u"{temp}°C"
- temp_separator = "|"
+ format_temp_separator = " "
class Meta:
def deprecate_function(config):
@@ -54,7 +54,16 @@
out["format"] =
u"{}{{format_temp}}".format(config["format_prefix"])
return out
- deprecated = {"function": [{"function": deprecate_function}]}
+ deprecated = {
+ "function": [{"function": deprecate_function}],
+ "rename": [
+ {
+ "param": "temp_separator",
+ "new": "format_temp_separator",
+ "msg": "obsolete parameter, use format_temp_separator",
+ }
+ ],
+ }
def post_config_hook(self):
if not self.py3.check_commands("nvidia-smi"):
@@ -72,8 +81,10 @@
data = []
for temp in temps:
data.append(self.py3.safe_format(self.format_temp, {"temp": temp}))
- data = self.py3.composite_join(self.temp_separator, data)
- full_text = self.py3.safe_format(self.format, {"format_temp": data})
+
+ format_temp_separator =
self.py3.safe_format(self.format_temp_separator)
+ format_temp = self.py3.composite_join(format_temp_separator, data)
+ full_text = self.py3.safe_format(self.format, {"format_temp":
format_temp})
return {
"cached_until": self.py3.time_in(self.cache_timeout),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py3status-3.20/py3status/modules/spotify.py
new/py3status-3.21/py3status/modules/spotify.py
--- old/py3status-3.20/py3status/modules/spotify.py 2019-04-20
18:40:09.000000000 +0200
+++ new/py3status-3.21/py3status/modules/spotify.py 2019-10-02
21:52:30.000000000 +0200
@@ -21,6 +21,7 @@
Format placeholders:
{album} album name
{artist} artiste name (first one)
+ {playback} state of the playback: Playing, Paused
{time} time duration of the song
{title} name of the song
@@ -55,12 +56,12 @@
{'color': '#FF0000', 'full_text': 'Spotify stopped'}
"""
-import dbus
import re
-
from datetime import timedelta
from time import sleep
+import dbus
+
SPOTIFY_CMD = """dbus-send --print-reply --dest=org.mpris.MediaPlayer2.spotify
/org/mpris/MediaPlayer2 org.mpris.MediaPlayer2.Player.{cmd}"""
@@ -148,7 +149,7 @@
playback_status = self.player.Get(
"org.mpris.MediaPlayer2.Player", "PlaybackStatus"
)
- if playback_status.strip() == "Playing":
+ if playback_status == "Playing":
color = self.py3.COLOR_PLAYING or self.py3.COLOR_GOOD
else:
color = self.py3.COLOR_PAUSED or self.py3.COLOR_DEGRADED
@@ -161,7 +162,13 @@
return (
self.py3.safe_format(
self.format,
- dict(title=title, artist=artist, album=album, time=rtime),
+ dict(
+ title=title,
+ artist=artist,
+ album=album,
+ time=rtime,
+ playback=playback_status,
+ ),
),
color,
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py3status-3.20/py3status/modules/sysdata.py
new/py3status-3.21/py3status/modules/sysdata.py
--- old/py3status-3.20/py3status/modules/sysdata.py 2019-06-27
15:59:41.000000000 +0200
+++ new/py3status-3.21/py3status/modules/sysdata.py 2019-10-02
21:52:30.000000000 +0200
@@ -330,7 +330,10 @@
total_mem_kib = meminfo["SwapTotal:"]
used_mem_kib = total_mem_kib - meminfo["SwapFree:"]
- used_percent = 100 * used_mem_kib / total_mem_kib
+ if total_mem_kib == 0:
+ used_percent = 0
+ else:
+ used_percent = 100 * used_mem_kib / total_mem_kib
unit = "B" if unit == "dynamic" else unit
(total, total_unit) = self.py3.format_units(total_mem_kib * 1024, unit)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py3status-3.20/py3status/modules/weather_owm.py
new/py3status-3.21/py3status/modules/weather_owm.py
--- old/py3status-3.20/py3status/modules/weather_owm.py 2019-07-04
23:21:16.000000000 +0200
+++ new/py3status-3.21/py3status/modules/weather_owm.py 2019-10-13
12:16:47.000000000 +0200
@@ -44,8 +44,6 @@
(default 3)
forecast_include_today: Include today in the forecast? (Boolean)
(default False)
- forecast_text_separator: Separator between entries in the forecast
- (default ' ')
format: How to display the weather
This also dictates the type of forecast. The placeholders here refer to
the format_[...] variables found below.
@@ -64,6 +62,8 @@
for future weather. Notably, this does not include information about
sunrise or sunset times.
(default '{icon}')
+ format_forecast_separator: Separator between entries in the forecast
+ (default ' ')
format_humidity: Formatting for humidity (percentage)
Available placeholders:
icon, humidity
@@ -317,10 +317,10 @@
country = None
forecast_days = 3
forecast_include_today = False
- forecast_text_separator = " "
format = "{city} {icon} {temperature}[ {rain}], {description} {forecast}"
format_clouds = "{icon} {coverage}%"
format_forecast = "{icon}"
+ format_forecast_separator = " "
format_humidity = "{icon} {humidity}%"
format_pressure = "{icon} {pressure} hPa"
format_rain = "[\?if=amount {icon} {amount:.0f} {unit}]"
@@ -352,7 +352,16 @@
unit_wind = "mph"
class Meta:
- deprecated = {"remove": [{"param": "offset_gmt", "msg": "obsolete"}]}
+ deprecated = {
+ "remove": [{"param": "offset_gmt", "msg": "obsolete"}],
+ "rename": [
+ {
+ "param": "forecast_text_separator",
+ "new": "format_forecast_separator",
+ "msg": "obsolete parameter, use format_forecast_separator",
+ }
+ ],
+ }
def _get_icons(self):
if self.icons is None:
@@ -425,6 +434,13 @@
if name not in self.thresholds:
self.thresholds[name] = self.thresholds[THRESHOLDS_ALL]
+ # Initialize per-format thresholds
+ self.thresholds_init = {}
+ for name in ("format_humidity",):
+ self.thresholds_init[name] = self.py3.get_color_names_list(
+ getattr(self, name)
+ )
+
def _make_req(self, url, params=None):
# Make a request expecting a JSON response
req = self.py3.request(url, params=params)
@@ -618,11 +634,16 @@
def _format_humidity(self, wthr):
# Format the humidity (default zero humidity)
- humidity = self._jpath(wthr, OWM_HUMIDITY, 0)
+ humidity_data = {
+ "icon": self.icon_humidity,
+ "humidity": self._jpath(wthr, OWM_HUMIDITY, 0),
+ }
- return self.py3.safe_format(
- self.format_humidity, {"icon": self.icon_humidity, "humidity":
humidity}
- )
+ for x in self.thresholds_init["format_humidity"]:
+ if x in humidity_data:
+ self.py3.threshold_get_color(humidity_data[x], x)
+
+ return self.py3.safe_format(self.format_humidity, humidity_data)
def _format_pressure(self, wthr):
# Get data and add the icon
@@ -725,8 +746,9 @@
forecasts.append(self.py3.safe_format(self.format_forecast,
future))
# Give the final format
+ format_forecast_separator =
self.py3.safe_format(self.format_forecast_separator)
today["forecast"] = self.py3.composite_join(
- self.forecast_text_separator, forecasts
+ format_forecast_separator, forecasts
)
return self.py3.safe_format(self.format, today)
@@ -806,6 +828,6 @@
"format_forecast": ("{icon} " + all_string),
# Miscellaneous
"forecast_days": 1,
- "forecast_text_separator": "//",
+ "format_forecast_separator": "//",
},
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py3status-3.20/py3status/modules/wifi.py
new/py3status-3.21/py3status/modules/wifi.py
--- old/py3status-3.20/py3status/modules/wifi.py 2019-06-27
15:59:41.000000000 +0200
+++ new/py3status-3.21/py3status/modules/wifi.py 2019-10-02
21:52:30.000000000 +0200
@@ -8,7 +8,8 @@
blocks: a string, where each character represents quality level
(default "_▁▂▃▄▅▆▇█")
cache_timeout: Update interval in seconds (default 10)
- device: specify device name to use, otherwise auto (default None)
+ device: specify name or MAC address of device to use, otherwise auto
+ (default None)
down_color: Output color when disconnected, possible values:
"good", "degraded", "bad" (default "bad")
format: Display format for this module
@@ -106,11 +107,16 @@
data = self.py3.command_output([iw, "dev"])
except self.py3.CommandError as ce:
raise Exception(ce.error.strip())
+ last_device = None
for line in data.splitlines()[1:]:
- if "Interface" in line:
- device = line.split()[-1]
- if not self.device or device == self.device:
- self.device = device
+ if not line.startswith("\t\t"):
+ last_device = None
+ if "Interface" in line or ("addr" in line and last_device is not
None):
+ intf_or_addr = line.split()[-1]
+ if "Interface" in line:
+ last_device = intf_or_addr
+ if not self.device or intf_or_addr.lower() ==
self.device.lower():
+ self.device = last_device
break
else:
device = " `{}`".format(self.device) if self.device else ""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py3status-3.20/py3status/py3.py
new/py3status-3.21/py3status/py3.py
--- old/py3status-3.20/py3status/py3.py 2019-07-04 10:58:01.000000000 +0200
+++ new/py3status-3.21/py3status/py3.py 2019-10-13 12:31:22.000000000 +0200
@@ -1254,6 +1254,8 @@
timeout=None,
auth=None,
cookiejar=None,
+ retry_times=None,
+ retry_wait=None,
):
"""
Make a request to a url and retrieve the results.
@@ -1270,6 +1272,8 @@
:param timeout: timeout for the request in seconds
:param auth: authentication info as tuple `(username, password)`
:param cookiejar: an object of a CookieJar subclass
+ :param retry_times: how many times to retry the request
+ :param retry_wait: how long to wait between retries in seconds
:returns: HttpResponse
"""
@@ -1289,15 +1293,36 @@
if timeout is None:
timeout = getattr(self._py3status_module, "request_timeout", 10)
+ if retry_times is None:
+ retry_times = getattr(self._py3status_module,
"request_retry_times", 3)
+
+ if retry_wait is None:
+ retry_wait = getattr(self._py3status_module, "request_retry_wait",
2)
+
if "User-Agent" not in headers:
headers["User-Agent"] = "py3status/{} {}".format(version,
self._uid)
- return HttpResponse(
- url,
- params=params,
- data=data,
- headers=headers,
- timeout=timeout,
- auth=auth,
- cookiejar=cookiejar,
- )
+ def get_http_response():
+ return HttpResponse(
+ url,
+ params=params,
+ data=data,
+ headers=headers,
+ timeout=timeout,
+ auth=auth,
+ cookiejar=cookiejar,
+ )
+
+ for n in range(1, retry_times):
+ try:
+ return get_http_response()
+ except (self.RequestTimeout, self.RequestURLError):
+ if self.is_gevent():
+ from gevent import sleep
+ else:
+ from time import sleep
+ self.log("HTTP request retry {}/{}".format(n, retry_times))
+ sleep(retry_wait)
+ self.log("HTTP request retry {}/{}".format(retry_times, retry_times))
+ sleep(retry_wait)
+ return get_http_response()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py3status-3.20/py3status/tester.py
new/py3status-3.21/py3status/tester.py
--- old/py3status-3.20/py3status/tester.py 1970-01-01 01:00:00.000000000
+0100
+++ new/py3status-3.21/py3status/tester.py 2019-10-12 18:01:48.000000000
+0200
@@ -0,0 +1,30 @@
+import json
+from time import sleep
+import sys
+from syslog import syslog
+
+o = sys.__stdout__
+
+def out(msg):
+ o.write(msg + "\n")
+ o.flush()
+
+out('{"version":1}')
+out('[')
+
+j = {
+ "name": "test",
+ "instance": "",
+ "full_text": "M",
+ "short_text": ".",
+}
+
+N = 1
+
+out("[" + json.dumps(j) + "]")
+while True:
+ if len(j["full_text"]) < 137:
+ j["full_text"] += "M"
+# syslog("{}".format(len(j["full_text"])))
+ out(",[" + json.dumps(j) + "]")
+ sleep(0.005)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py3status-3.20/py3status/version.py
new/py3status-3.21/py3status/version.py
--- old/py3status-3.20/py3status/version.py 2019-08-06 21:16:20.000000000
+0200
+++ new/py3status-3.21/py3status/version.py 2019-10-13 12:33:15.000000000
+0200
@@ -1 +1 @@
-version = "3.20"
+version = "3.21"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py3status-3.20/py3status.egg-info/PKG-INFO
new/py3status-3.21/py3status.egg-info/PKG-INFO
--- old/py3status-3.20/py3status.egg-info/PKG-INFO 2019-08-06
21:24:51.000000000 +0200
+++ new/py3status-3.21/py3status.egg-info/PKG-INFO 2019-10-13
12:40:26.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: py3status
-Version: 3.20
+Version: 3.21
Summary: py3status: an extensible i3status wrapper written in python
Home-page: https://github.com/ultrabug/py3status
Author: Ultrabug
@@ -150,6 +150,6 @@
Classifier: Programming Language :: Python :: 3.7
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Description-Content-Type: text/x-rst
-Provides-Extra: all
-Provides-Extra: gevent
Provides-Extra: udev
+Provides-Extra: gevent
+Provides-Extra: all
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/py3status-3.20/py3status.egg-info/SOURCES.txt
new/py3status-3.21/py3status.egg-info/SOURCES.txt
--- old/py3status-3.20/py3status.egg-info/SOURCES.txt 2019-08-06
21:24:51.000000000 +0200
+++ new/py3status-3.21/py3status.egg-info/SOURCES.txt 2019-10-13
12:40:26.000000000 +0200
@@ -55,6 +55,7 @@
py3status/request.py
py3status/screenshots.py
py3status/storage.py
+py3status/tester.py
py3status/udev_monitor.py
py3status/util.py
py3status/version.py
@@ -123,6 +124,7 @@
py3status/modules/net_iplist.py
py3status/modules/net_rate.py
py3status/modules/netdata.py
+py3status/modules/networkmanager.py
py3status/modules/ns_checker.py
py3status/modules/nvidia_smi.py
py3status/modules/nvidia_temp.py