summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG15
-rw-r--r--MANIFEST.in4
-rw-r--r--README.rst63
-rw-r--r--modules/__init__.py0
-rw-r--r--modules/battery-level.py68
-rw-r--r--modules/dpms.py (renamed from examples/dpms.py)0
-rw-r--r--modules/empty_class.py (renamed from examples/empty_class.py)0
-rw-r--r--modules/glpi.py (renamed from examples/glpi.py)0
-rw-r--r--modules/i3bar_click_events.py (renamed from examples/i3bar_click_events.py)0
-rw-r--r--modules/keyboard-layout.py73
-rw-r--r--modules/mpd_status.py117
-rw-r--r--modules/netdata.py (renamed from examples/netdata.py)2
-rw-r--r--modules/ns_checker.py (renamed from examples/ns_checker.py)0
-rw-r--r--modules/pingdom.py (renamed from examples/pingdom.py)0
-rw-r--r--modules/pomodoro.py (renamed from examples/pomodoro.py)0
-rw-r--r--modules/scratchpad-counter.py50
-rw-r--r--modules/sysdata.py (renamed from examples/sysdata.py)13
-rw-r--r--modules/weather_yahoo.py (renamed from examples/weather_yahoo.py)0
-rw-r--r--modules/whoami.py (renamed from examples/whoami.py)0
-rw-r--r--modules/window-title.py58
-rwxr-xr-xpy3status/__init__.py102
-rwxr-xr-xsetup.py3
22 files changed, 528 insertions, 40 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 6c00727..dba76a7 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,18 @@
+version 1.5 (2014-05-03)
+* add --version parameter wrt issue #29
+* switch back to RST for the README wrt pypi and issue #30 thx to @Weishaupt
+* include modules, changelog and license to sources on pypi
+* rename the examples folder to modules and include it in the installed files
+
+version 1.4 (2014-04-16)
+* new ordering mechanism with verbose logging. fixes rare cases where the modules methods were not always loaded in the same order and caused inconsistent ordering between reloads. thx to @guiniol for reporting/debugging and @IotaSpencer and @tasse for testing.
+* debug: dont catch print() on debug mode
+* debug: add position requested by modules
+* Merge pull request #25 from nawadanp/master
+* Add new module ns_checker.py, by @nawadanp
+* move README to markdown, change ordering
+* update the README with the new options from --help
+
version 1.3 (2014-02-23)
* new standalone mode allowing to bypass i3status when you need a py3status-modules-only i3bar
* debug mode add log info about py3status invocation config
diff --git a/MANIFEST.in b/MANIFEST.in
index 191f6ec..53676cb 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,2 +1,2 @@
-include *.rst
-recursive-include examples *.py
+include CHANGELOG LICENSE README.rst
+recursive-include modules *.py
diff --git a/README.rst b/README.rst
index 1d5cb60..eae22ff 100644
--- a/README.rst
+++ b/README.rst
@@ -1,25 +1,33 @@
-=========
+*********
py3status
-=========
+*********
+|version|
+
+.. |version| image:: https://pypip.in/version/py3status/badge.png
+
**py3status** is an extensible i3status wrapper written in python.
Using py3status, you can take control of your i3bar easily by:
- - writing your own modules and have their output displayed on your bar
- - handling click events on your i3bar and play with them in no time
- - seeing your clock tick every second whatever your i3status interval
+
+- writing your own modules and have their output displayed on your bar
+- handling click events on your i3bar and play with them in no time
+- seeing your clock tick every second whatever your i3status interval
No extra configuration file needed, just install & enjoy !
Documentation
=============
See the wiki for up to date documentation:
- https://github.com/ultrabug/py3status/wiki
+
+- https://github.com/ultrabug/py3status/wiki
Learn how to write your own modules:
- https://github.com/ultrabug/py3status/wiki/Write-your-own-modules
+
+- https://github.com/ultrabug/py3status/wiki/Write-your-own-modules
Get help or share your ideas on IRC:
- channel **#py3status** on **FreeNode**
+
+- channel **#py3status** on **FreeNode**
Requirements
============
@@ -31,33 +39,35 @@ You **must** set the `output_format` to `i3bar` in the general section of your i
output_format = "i3bar"
}
-Installation (all users)
-========================
-py3status is available on pypi:
+Usage
+=====
+In your i3 config file, simply switch from `i3status` to `py3status` in your `status_command`:
::
- $ pip install py3status
+ status_command py3status
-Installation (Gentoo users)
-===========================
-py3status is available on portage:
+Usually you have your own i3status configuration, just point to it:
::
- $ sudo emerge -a py3status
+ status_command py3status -c ~/.i3/i3status.conf
-Installation (Arch users)
-=========================
-Thanks to @waaaaargh, py3status is present in the Arch User Repository using this URL:
+Installation
+============
+Pypi
+----
+Using pip:
::
- https://aur.archlinux.org/packages/py3status-git/
+ $ pip install py3status
-Usage
-=====
-In your i3 config file, simply change the `status_command` with:
+Gentoo Linux
+------------
+Using emerge:
::
- status_command py3status
+ $ sudo emerge -a py3status
-Usually you have your own i3status configuration, just point to it:
+Arch Linux
+----------
+Thanks to @waaaaargh, py3status is present in the Arch User Repository using this URL:
::
- status_command py3status -c ~/.i3/i3status.conf
+ https://aur.archlinux.org/packages/py3status-git/
Options
=======
@@ -71,6 +81,7 @@ You can see the help of py3status by issuing `py3status -h`:
-s, --standalone standalone mode, do not use i3status
-t CACHE_TIMEOUT default injection cache timeout in seconds
(default 60 sec)
+ -v, --version show py3status version and exit
Control
=======
diff --git a/modules/__init__.py b/modules/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/modules/__init__.py
diff --git a/modules/battery-level.py b/modules/battery-level.py
new file mode 100644
index 0000000..6c30556
--- /dev/null
+++ b/modules/battery-level.py
@@ -0,0 +1,68 @@
+# -*- coding: utf8 -*-
+
+from __future__ import division # python2 compatibility
+from time import time
+
+import math
+import re
+import subprocess
+
+"""
+Module for displaying information about battery.
+
+Requires:
+ - the 'acpi' command line
+
+@author shadowprince
+@license Eclipse Public License
+"""
+
+CACHE_TIMEOUT = 30 # time to update battery
+HIDE_WHEN_FULL = False # hide any information when battery is fully charged
+
+MODE = "bar" # for primitive-one-char bar, or "text" for text percentage ouput
+
+BLOCKS = ["_", "▁", "▂", "▃", "▄", "▅", "▆", "▇", "█"] # block for bar
+TEXT_FORMAT = "Battery: {}" # text with "text" mode. percentage with % replaces {}
+
+CHARGING_CHARACTER = "⚡"
+
+# None means - get it from i3 config
+COLOR_BAD = None
+COLOR_CHARGING = "#FCE94F"
+COLOR_DEGRADED = None
+COLOR_GOOD = None
+
+
+class Py3status:
+ def battery_level(self, i3status_output_json, i3status_config):
+ response = {'name': 'battery-level'}
+
+ acpi = subprocess.check_output(["acpi"]).decode('utf-8')
+ proc = int(re.search(r"(\d+)%", acpi).group(1))
+
+ charging = bool(re.match(r".*Charging.*", acpi))
+ full = bool(re.match(r".*Unknown.*", acpi)) or bool(re.match(r".*Full.*", acpi))
+
+ if MODE == "bar":
+ character = BLOCKS[int(math.ceil(proc/100*(len(BLOCKS) - 1)))]
+ else:
+ character = TEXT_FORMAT.format(str(proc) + "%")
+
+ if proc < 30:
+ response['color'] = COLOR_DEGRADED if COLOR_DEGRADED else i3status_config['color_degraded']
+ if proc < 10:
+ response['color'] = COLOR_BAD if COLOR_BAD else i3status_config['color_bad']
+
+ if full:
+ response['color'] = COLOR_GOOD if COLOR_GOOD else i3status_config['color_good']
+ response['full_text'] = "" if HIDE_WHEN_FULL else BLOCKS[-1]
+ elif charging:
+ response['color'] = COLOR_CHARGING
+ response['full_text'] = CHARGING_CHARACTER
+ else:
+ response['full_text'] = character
+
+ response['cached_until'] = time() + CACHE_TIMEOUT
+
+ return (0, response)
diff --git a/examples/dpms.py b/modules/dpms.py
index 783c53c..783c53c 100644
--- a/examples/dpms.py
+++ b/modules/dpms.py
diff --git a/examples/empty_class.py b/modules/empty_class.py
index 077269c..077269c 100644
--- a/examples/empty_class.py
+++ b/modules/empty_class.py
diff --git a/examples/glpi.py b/modules/glpi.py
index 929749d..929749d 100644
--- a/examples/glpi.py
+++ b/modules/glpi.py
diff --git a/examples/i3bar_click_events.py b/modules/i3bar_click_events.py
index 792965c..792965c 100644
--- a/examples/i3bar_click_events.py
+++ b/modules/i3bar_click_events.py
diff --git a/modules/keyboard-layout.py b/modules/keyboard-layout.py
new file mode 100644
index 0000000..1ed3cee
--- /dev/null
+++ b/modules/keyboard-layout.py
@@ -0,0 +1,73 @@
+from subprocess import check_output
+from time import time
+
+"""
+Module for showing current keyboard layout.
+
+Requires:
+ - xkblayout-state
+ or
+ - setxkbmap
+
+@author shadowprince
+@license Eclipse Public License
+"""
+
+CACHE_TIMEOUT = 10 # refresh time to update indicator
+
+# colors of layouts, check your command's output to match keys
+LANG_COLORS = {
+ 'fr': '#268BD2', # solarized blue
+ 'ru': '#F75252', # red
+ 'ua': '#FCE94F', # yellow
+ 'us': '#729FCF', # light blue
+}
+
+
+def xbklayout():
+ """
+ check using xkblayout-state (preferred method)
+ """
+ return check_output(
+ ["xkblayout-state", "print", "%s"]
+ ).decode('utf-8')
+
+
+def setxkbmap():
+ """
+ check using setxkbmap >= 1.3.0
+
+ Please read issue 33 for more information :
+ https://github.com/ultrabug/py3status/pull/33
+ """
+ q = check_output(['setxkbmap', '-query']).decode('utf-8')
+ return q.replace(' ', '').split(':')[-1]
+
+
+class Py3status:
+ def __init__(self):
+ """
+ find the best implementation to get the keyboard's layout
+ """
+ try:
+ xbklayout()
+ except:
+ self.command = setxkbmap
+ else:
+ self.command = xbklayout
+
+ def keyboard_layout(self, i3status_output_json, i3status_config):
+ response = {
+ 'full_text': '',
+ 'name': 'keyboard-layout',
+ 'cached_until': time() + CACHE_TIMEOUT
+ }
+
+ lang = self.command().strip()
+ lang_color = LANG_COLORS.get(lang)
+
+ response['full_text'] = lang or '??'
+ if lang_color:
+ response['color'] = lang_color
+
+ return (0, response)
diff --git a/modules/mpd_status.py b/modules/mpd_status.py
new file mode 100644
index 0000000..28e99dc
--- /dev/null
+++ b/modules/mpd_status.py
@@ -0,0 +1,117 @@
+# -*- coding: utf-8 -*-
+
+import re
+
+from mpd import (MPDClient, CommandError)
+from socket import error as SocketError
+from time import time
+
+"""
+Mpd - module to show information from mpd to your's bar! Settings listed above.
+Reequires
+ - python-mpd2 (NOT python2-mpd2)
+ # pip install python-mpd2
+
+@author shadowprince
+@license Eclipse Public License
+"""
+
+# mpd settings
+HOST = "localhost"
+PORT = "6600"
+PASSWORD = None
+
+# time to update
+CACHE_TIMEOUT = 1
+
+# position
+POSITION = 0
+
+# if text length will be greater - it'll shrink it
+MAX_WIDTH = 120
+
+# hide any indicator, if
+HIDE_WHEN_PAUSED = False
+HIDE_WHEN_STOPPED = True
+
+# state characters (or strings). Actual of them replaces {state} placeholder in STRFORMAT
+STATE_CHARACTERS = {
+ "pause": "[pause]",
+ "play": "[play]",
+ "stop": "[stop]",
+}
+
+""" format of result string
+can contain:
+ {state} - current state from STATE_CHARACTERS
+ Track information:
+ {track}, {artist}, {title}, {time}, {album}, {pos}
+ In additional, information about next track also comes in, in analogue with current, but with next_ prefix,
+ like {next_title}
+"""
+STRFORMAT = "{state} №{pos}. {artist} - {title} [{time}] | {next_title}"
+
+
+class Py3status:
+ def __init__(self):
+ self.text = ''
+
+ def currentTrack(self, i3status_output_json, i3status_config):
+ try:
+ c = MPDClient()
+ c.connect(host=HOST, port=PORT)
+ if PASSWORD:
+ c.password(PASSWORD)
+
+ status = c.status()
+ song = int(status.get("song", 0))
+ next_song = int(status.get("nextsong", 0))
+
+ if (status["state"] == "pause" and HIDE_WHEN_PAUSED) or (status["state"] == "stop" and HIDE_WHEN_STOPPED):
+ text = ""
+ else:
+ try:
+ song = c.playlistinfo()[song]
+ song["time"] = "{0:.2f}".format(int(song.get("time", 1)) / 60)
+ except IndexError:
+ song = {}
+
+ try:
+ next_song = c.playlistinfo()[next_song]
+ except IndexError:
+ next_song = {}
+
+ format_args = song
+ format_args["state"] = STATE_CHARACTERS.get(status.get("state", None))
+ for k, v in next_song.items():
+ format_args["next_{}".format(k)] = v
+
+ text = STRFORMAT
+ for k, v in format_args.items():
+ text = text.replace("{" + k + "}", v)
+
+ for sub in re.findall(r"{\S+?}", text):
+ text = text.replace(sub, "")
+ except SocketError:
+ text = "Failed to connect to mpd!"
+ except CommandError:
+ text = "Failed to authenticate to mpd!"
+ c.disconnect()
+
+ if len(text) > MAX_WIDTH:
+ text = text[-MAX_WIDTH-3:] + "..."
+
+ if self.text != text:
+ transformed = True
+ self.text = text
+ else:
+ transformed = False
+
+ response = {
+ 'cached_until': time() + CACHE_TIMEOUT,
+ 'full_text': self.text,
+ 'name': 'scratchpad-count',
+ 'transformed': transformed
+ }
+
+ return (POSITION, response)
diff --git a/examples/netdata.py b/modules/netdata.py
index d923036..729983b 100644
--- a/examples/netdata.py
+++ b/modules/netdata.py
@@ -64,7 +64,7 @@ class GetData:
'eth0') and grab received/transmitted bytes.
"""
- net_data = self.execCMD('cat', '/proc/net/dev').split()
+ net_data = self.execCMD('cat', '/proc/net/dev').decode('utf-8').split()
interface_index = net_data.index(self.net_interface + ':')
received_bytes = int(net_data[interface_index + 1])
transmitted_bytes = int(net_data[interface_index + 9])
diff --git a/examples/ns_checker.py b/modules/ns_checker.py
index 4a332b1..4a332b1 100644
--- a/examples/ns_checker.py
+++ b/modules/ns_checker.py
diff --git a/examples/pingdom.py b/modules/pingdom.py
index cddf1a9..cddf1a9 100644
--- a/examples/pingdom.py
+++ b/modules/pingdom.py
diff --git a/examples/pomodoro.py b/modules/pomodoro.py
index 28b5ea1..28b5ea1 100644
--- a/examples/pomodoro.py
+++ b/modules/pomodoro.py
diff --git a/modules/scratchpad-counter.py b/modules/scratchpad-counter.py
new file mode 100644
index 0000000..390745f
--- /dev/null
+++ b/modules/scratchpad-counter.py
@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+
+import i3
+from time import time
+
+"""
+Module showing amount of windows at the scratchpad.
+
+@author shadowprince
+@license Eclipse Public License
+"""
+
+CACHE_TIMEOUT = 5
+HIDE_WHEN_NONE = False # hide indicator when there is no windows
+POSITION = 0
+STRFORMAT = "{} ⌫" # format of indicator. {} replaces with count of windows
+
+
+def find_scratch(tree):
+ if tree["name"] == "__i3_scratch":
+ return tree
+ else:
+ for x in tree["nodes"]:
+ result = find_scratch(x)
+ if result:
+ return result
+ return None
+
+
+class Py3status:
+ def __init__(self):
+ self.count = -1
+
+ def scratchpad_counter(self, i3status_output_json, i3status_config):
+ count = len(find_scratch(i3.get_tree()).get("floating_nodes", []))
+
+ if self.count != count:
+ transformed = True
+ self.count = count
+ else:
+ transformed = False
+
+ response = {
+ 'cached_until': time() + CACHE_TIMEOUT,
+ 'full_text': '' if HIDE_WHEN_NONE and count == 0 else STRFORMAT.format(count),
+ 'name': 'scratchpad-counter',
+ 'transformed': transformed
+ }
+
+ return (POSITION, response)
diff --git a/examples/sysdata.py b/modules/sysdata.py
index 14aefb3..5354fce 100644
--- a/examples/sysdata.py
+++ b/modules/sysdata.py
@@ -8,6 +8,10 @@
# i3wm homepage: http://i3wm.org
# py3status homepage: https://github.com/ultrabug/py3status
+# NOTE: If you want py3status to show you your CPU temperature, change value of CPUTEMP into True
+# in Py3status class - CPUInfo function
+# and REMEMBER that you must install lm_sensors if you want CPU temp!
+
# Copyright (C) <2013> <Shahin Azad [ishahinism at Gmail]>
# This program is free software: you can redistribute it and/or modify
@@ -109,8 +113,15 @@ class Py3status:
response['color'] = i3status_config['color_degraded']
else:
response['color'] = i3status_config['color_bad']
+ #cpu temp
+ CPUTEMP=False
+ if CPUTEMP:
+ cputemp=subprocess.check_output('sensors | grep "CPU Temp" | cut -f 2 -d "+" | cut -f 1 -d " "',shell=True)
+ cputemp=cputemp[:-1].decode('utf-8')
+ response['full_text'] = "CPU: %.2f%%" % (used_cpu_percent*100) +" "+cputemp
+ else:
+ response['full_text'] = "CPU: %.2f%%" % (used_cpu_percent*100)
- response['full_text'] = "CPU: %.2f%%" % (used_cpu_percent*100)
#cache the status for 10 seconds
response['cached_until'] = time() + 10
diff --git a/examples/weather_yahoo.py b/modules/weather_yahoo.py
index 6b91b04..6b91b04 100644
--- a/examples/weather_yahoo.py
+++ b/modules/weather_yahoo.py
diff --git a/examples/whoami.py b/modules/whoami.py
index f930991..f930991 100644
--- a/examples/whoami.py
+++ b/modules/whoami.py
diff --git a/modules/window-title.py b/modules/window-title.py
new file mode 100644
index 0000000..4f6f062
--- /dev/null
+++ b/modules/window-title.py
@@ -0,0 +1,58 @@
+import i3
+from time import time
+
+"""
+Py3status plugin - shows current window title.
+
+Requires:
+ - i3-py (https://github.com/ziberna/i3-py)
+ # pip install i3-py
+
+If payload from server contains wierd utf-8
+(for example one window have something bad in title) - the plugin will
+give empty output UNTIL this window is closed.
+I can't fix or workaround that in PLUGIN, problem is in i3-py library.
+
+@author shadowprince
+@license Eclipse Public License
+"""
+
+CACHE_TIMEOUT = 0.5 # maximum time to update indicator
+MAX_WIDTH = 120 # if width of title is greater, shrink it and add '...'
+POSITION = 0
+
+
+def find_focused(tree):
+ if type(tree) == list:
+ for el in tree:
+ res = find_focused(el)
+ if res:
+ return res
+
+ elif type(tree) == dict:
+ if tree['focused']:
+ return tree
+ else:
+ return find_focused(tree['nodes'] + tree['floating_nodes'])
+
+
+class Py3status:
+ def __init__(self):
+ self.text = ''
+
+ def window_title(self, i3_status_output_json, i3status_config):
+ window = find_focused(i3.get_tree())
+
+ transformed = False
+ if window and 'name' in window and window['name'] != self.text:
+ self.text = len(window['name']) > MAX_WIDTH and "..." + window['name'][-(MAX_WIDTH-3):] or window['name']
+ transformed = True
+
+ response = {
+ 'cached_until': time() + CACHE_TIMEOUT,
+ 'full_text': self.text,
+ 'name': 'window-title',
+ 'transformed': transformed
+ }
+
+ return (POSITION, response)
diff --git a/py3status/__init__.py b/py3status/__init__.py
index 4bad6bd..e453cda 100755
--- a/py3status/__init__.py
+++ b/py3status/__init__.py
@@ -549,7 +549,8 @@ class Module(Thread):
if self.config['debug']:
syslog(
LOG_INFO,
- 'method {} returned {}'.format(meth, result)
+ 'method {} returned {} '.format(meth, result) +
+ 'for position {}'.format(position)
)
except Exception:
err = sys.exc_info()[1]
@@ -597,6 +598,14 @@ class Py3statusWrapper():
'interval': 1
}
+ # package version
+ try:
+ import pkg_resources
+ version = pkg_resources.get_distribution('py3status').version
+ except:
+ version = 'unknown'
+ config['version'] = version
+
# command line options
parser = argparse.ArgumentParser(
description='The agile, python-powered, i3status wrapper')
@@ -625,8 +634,21 @@ class Py3statusWrapper():
default=config['cache_timeout'],
help="""default injection cache timeout in seconds
(default 60 sec)""")
+ parser.add_argument('-v', '--version', action="store_true",
+ help="""show py3status version and exit""")
options = parser.parse_args()
+ # only asked for version
+ if options.version:
+ from platform import python_version
+ print(
+ 'py3status version {} (python {})'.format(
+ config['version'],
+ python_version()
+ )
+ )
+ sys.exit(0)
+
# override configuration and helper variables
config['cache_timeout'] = options.cache_timeout
config['debug'] = options.debug
@@ -699,8 +721,9 @@ class Py3statusWrapper():
syslog(LOG_INFO, 'events thread started')
# suppress modules' ouput wrt issue #20
- sys.stdout = open('/dev/null', 'w')
- sys.stderr = open('/dev/null', 'w')
+ if not self.config['debug']:
+ sys.stdout = open('/dev/null', 'w')
+ sys.stderr = open('/dev/null', 'w')
# load and spawn modules threads
for include_path, f_name in self.list_modules():
@@ -777,27 +800,88 @@ class Py3statusWrapper():
"""
# prepopulate the list so that every usable index exists, thx @Lujeni
m_list = [
- '' for value in range(sum([len(x.methods) for x in self.modules]))
+ '' for value in range(
+ sum([len(x.methods) for x in self.modules]) + len(json_list)
+ )
]
- # append i3status json list to the modules' list
- m_list += json_list
+
+ # debug the ordering matrix
+ if self.config['debug']:
+ syslog(
+ LOG_INFO,
+ 'ordering matrix {}'.format(list(range(len(m_list))))
+ )
+
# run through modules/methods output and insert them in reverse order
+ debug_msg = ''
for m in reversed(self.modules):
for meth in m.methods:
position = m.methods[meth]['position']
last_output = m.methods[meth]['last_output']
try:
+ assert position in range(len(m_list))
if m_list[position] == '':
m_list[position] = last_output
else:
if '' in m_list:
m_list.remove('')
m_list.insert(position, last_output)
- except IndexError:
+ except (AssertionError, IndexError):
# out of range indexes get placed at the end of the output
m_list.append(last_output)
- # cleanup and return output list
- m_list = list(filter(lambda a: a != '', m_list))
+ finally:
+ # debug user module's index
+ if self.config['debug']:
+ debug_msg += '{}={} '.format(
+ meth,
+ m_list.index(last_output)
+ )
+
+ # debug the user modules ordering
+ if self.config['debug']:
+ syslog(
+ LOG_INFO,
+ 'ordering user modules positions {}'.format(debug_msg.strip())
+ )
+
+ # append i3status json list to the modules' list in empty slots
+ debug_msg = ''
+ for i3s_json in json_list:
+ for i in range(len(m_list)):
+ if m_list[i] == '':
+ m_list[i] = i3s_json
+ break
+ else:
+ # this should not happen !
+ m_list.append(i3s_json)
+
+ # debug i3status module's index
+ if self.config['debug']:
+ debug_msg += '{}={} '.format(
+ i3s_json['name'],
+ m_list.index(i3s_json)
+ )
+
+ # debug i3status modules ordering
+ if self.config['debug']:
+ syslog(
+ LOG_INFO,
+ 'ordering i3status modules positions {}'.format(
+ debug_msg.strip()
+ )
+ )
+
+ # cleanup and return output list, we also remove empty outputs
+ m_list = list(filter(lambda a: a != '' and a['full_text'], m_list))
+
+ # log the final ordering in debug mode
+ if self.config['debug']:
+ syslog(
+ LOG_INFO,
+ 'ordering result {}'.format([m['name'] for m in m_list])
+ )
+
+ # return the ordered result
return m_list
def run(self):
diff --git a/setup.py b/setup.py
index 73ed0ab..c92d580 100755
--- a/setup.py
+++ b/setup.py
@@ -15,7 +15,7 @@ def read(fname):
setup(
name='py3status',
- version='1.3',
+ version='1.5',
author='Ultrabug',
author_email='ultrabug@ultrabug.net',
description='py3status is an extensible i3status wrapper written in python',
@@ -42,6 +42,7 @@ setup(
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.2',
'Programming Language :: Python :: 3.3',
+ 'Programming Language :: Python :: 3.4',
'Topic :: Software Development :: Libraries :: Python Modules',
],
)