Moved all docs to sphinx. Nothing changes for module authors.

This commit is contained in:
enkore 2014-10-12 01:32:29 +02:00
parent 1b3db989ed
commit 344ad4647f
13 changed files with 321 additions and 1635 deletions

View File

@ -2,6 +2,7 @@ language: python
python:
- "3.3"
install:
- "apt-get install python-mock"
- "pip install -r requirements.txt"
script:
- "PYTHONPATH=. py.test" # run unit tests

1097
README.rst

File diff suppressed because it is too large Load Diff

View File

@ -1,394 +0,0 @@
.. Always edit README.tpl.rst. Do not change the module reference manually.
i3pystatus
==========
.. image:: https://travis-ci.org/enkore/i3pystatus.svg?branch=master
:target: https://travis-ci.org/enkore/i3pystatus
i3pystatus is a (hopefully growing) collection of python scripts for
status output compatible to i3status / i3bar of the i3 window manager.
- `Release Notes`_
- `Configuration`_
- `Modules`_
- `Contribute`_
Installation
------------
.. admonition:: Note
i3pystatus requires Python 3.2 or newer and is not compatible with
Python 2.x. Some modules require additional dependencies
documented below (see `Modules`_).
From PyPI package `i3pystatus <https://pypi.python.org/pypi/i3pystatus>`_
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
::
pip install i3pystatus
Packages for your OS
++++++++++++++++++++
* `Arch Linux <https://aur.archlinux.org/packages/i3pystatus-git/>`_
Release Notes
-------------
Contributors
++++++++++++
* aaron-lebo
* afics
* al45tair
* Argish42
* Arvedui
* atalax
* bparmentier
* cganas
* crwood
* dubwoc
* enkore (current maintainer)
* gwarf
* janoliver (former maintainer)
* jasonmhite
* jedrz
* jorio
* kageurufu
* mekanix
* Mic92
* micha-a-schmidt
* naglis
* philipdexter
* sbrunner
* siikamiika
* simon04
* talwrii
* teto
* tomkenmag
* tomxtobin
* tony
* xals
* yemu
* zzatkin
next
++++
* Added `uptime`_ module
* `cpu\_usage`_: Add multicore support
* `cpu\_usage\_bar`_: Add multicore support
* `network`_: Add unknown_up setting
* `parcel`_: Document lxml dependency
* Added `network\_traffic`_ module
* `mpd`_: Play song on left click even if stopped
* Fixed issues with internet-related modules
* `battery`_: Added no_text_full option
* Unexpected exceptions are now displayed in the status bar
* `mail`_: db_path option made optional
* Core: added mouse wheel handling for upcoming i3 version
* `alsa`_: mouse wheel changes volume
* `pulseaudio`_: Added color_muted and color_unmuted options
3.30
++++
* Added `bitcoin`_ module
* Added `now\_playing`_ module
* Added `reddit`_ module
* Added `shell`_ module
* Core: fixed custom statusline colors not working properly (see issue #74)
* `alsa`_ and `pulseaudio`_: added optional "formated_muted"
audio is muted.
* `battery`_: add bar formatter, add not_present_text, full_color,
charging_color, not_present_color settings
* `disk`_: add color and round_size options
* maildir: use os.listdir instead of ls
* `mem`_: add round_size option
* `mpd`_: add color setting
* `mpd`_: add filename formatter
* `mpd`_: next song on right click
* `network`_ and `wireless`_: support interfaces enslaved to a bonding master
* `network`_: detached_down is now True by default
* `network`_: fixed some issues with interface up/down detection
* `parcel`_: added support for Itella (Finnish national postal service)
setting. If provided, it will be used instead of "format" when the
* `temp`_: add file setting
* `temp`_: fixed issue with Linux kernels 3.15 and newer
* `temp`_: removed color_critical and high_factor options
* `text`_: add cmd_leftclick and cmd_rightclick options
* `weather`_: add colorize option
* `wireless`_: Add quality_bar formatter
3.29
++++
* `network`_: prefer non link-local v6 addresses
* `mail`_: Open email client and refresh email with mouse click
* `disk`_: Add display and critical limit
* `battery`_: fix errors if CURRENT_NOW is not present
* `battery`_: add configurable colors
* `load`_: add configurable colors and limit
* `parcel`_: rewrote DHL tracker
* Add `spotify`_ module
3.28
++++
* **If you're currently using the i3pystatus command to run your i3bar**:
Replace ``i3pystatus`` command in your i3 configuration with ``python ~/path/to/your/config.py``
* Do not name your script i3pystatus.py or it will break imports.
* New options for `mem`_
* Added `cpu\_usage`_
* Improved error handling
* Removed ``i3pystatus`` binary
* pulseaudio: changed context name to "i3pystatus_pulseaudio"
* Add maildir backend for mails
* Code changes
* Removed DHL tracker of parcel module, because it doesn't work anymore.
3.27
++++
* Add weather module
* Add text module
* PulseAudio module: Add muted/unmuted options
3.26
++++
* Add mem module
3.24
++++
**This release introduced changes that may require manual changes to your
configuration file**
* Introduced TimeWrapper
* battery module: removed remaining\_* formatters in favor of
TimeWrapper, as it can not only reproduce all the variants removed,
but can do much more.
* mpd: Uses TimeWrapper for song_length, song_elapsed
Configuration
-------------
The config file is just a normal Python script.
A simple configuration file could look like this (note the additional
dependencies from `network`_, `wireless`_ and `pulseaudio`_ in this
example):
::
# -*- coding: utf-8 -*-
import subprocess
from i3pystatus import Status
status = Status(standalone=True)
# Displays clock like this:
# Tue 30 Jul 11:59:46 PM KW31
# ^-- calendar week
status.register("clock",
format="%a %-d %b %X KW%V",)
# Shows the average load of the last minute and the last 5 minutes
# (the default value for format is used)
status.register("load")
# Shows your CPU temperature, if you have a Intel CPU
status.register("temp",
format="{temp:.0f}°C",)
# The battery monitor has many formatting options, see README for details
# This would look like this, when discharging (or charging)
# ↓14.22W 56.15% [77.81%] 2h:41m
# And like this if full:
# =14.22W 100.0% [91.21%]
#
# This would also display a desktop notification (via dbus) if the percentage
# goes below 5 percent while discharging. The block will also color RED.
status.register("battery",
format="{status}/{consumption:.2f}W {percentage:.2f}% [{percentage_design:.2f}%] {remaining:%E%hh:%Mm}",
alert=True,
alert_percentage=5,
status={
"DIS": "↓",
"CHR": "↑",
"FULL": "=",
},)
# This would look like this:
# Discharging 6h:51m
status.register("battery",
format="{status} {remaining:%E%hh:%Mm}",
alert=True,
alert_percentage=5,
status={
"DIS": "Discharging",
"CHR": "Charging",
"FULL": "Bat full",
},)
# Displays whether a DHCP client is running
status.register("runwatch",
name="DHCP",
path="/var/run/dhclient*.pid",)
# Shows the address and up/down state of eth0. If it is up the address is shown in
# green (the default value of color_up) and the CIDR-address is shown
# (i.e. 10.10.10.42/24).
# If it's down just the interface name (eth0) will be displayed in red
# (defaults of format_down and color_down)
#
# Note: the network module requires PyPI package netifaces
status.register("network",
interface="eth0",
format_up="{v4cidr}",)
# Has all the options of the normal network and adds some wireless specific things
# like quality and network names.
#
# Note: requires both netifaces and basiciw
status.register("wireless",
interface="wlan0",
format_up="{essid} {quality:03.0f}%",)
# Shows disk usage of /
# Format:
# 42/128G [86G]
status.register("disk",
path="/",
format="{used}/{total}G [{avail}G]",)
# Shows pulseaudio default sink volume
#
# Note: requires libpulseaudio from PyPI
status.register("pulseaudio",
format="♪{volume}",)
# Shows mpd status
# Format:
# Cloud connected▶Reroute to Remain
status.register("mpd",
format="{title}{status}{album}",
status={
"pause": "▷",
"play": "▶",
"stop": "◾",
},)
status.run()
Also change your i3wm config to the following:
::
# i3bar
bar {
status_command python ~/.path/to/your/config/file.py
position top
workspace_buttons yes
}
Formatting
++++++++++
All modules let you specifiy the exact output formatting using a
`format string <http://docs.python.org/3/library/string.html#formatstrings>`_, which
gives you a great deal of flexibility.
If a module gives you a float, it probably has a ton of
uninteresting decimal places. Use ``{somefloat:.0f}`` to get the integer
value, ``{somefloat:0.2f}`` gives you two decimal places after the
decimal dot
formatp
~~~~~~~
Some modules use an extended format string syntax (the mpd module, for example).
Given the format string below the output adapts itself to the available data.
::
[{artist}/{album}/]{title}{status}
Only if both the artist and album is known they're displayed. If only one or none
of them is known the entire group between the brackets is excluded.
"is known" is here defined as "value evaluating to True in Python", i.e. an empty
string or 0 (or 0.0) counts as "not known".
Inside a group always all format specifiers must evaluate to true (logical and).
You can nest groups. The inner group will only become part of the output if both
the outer group and the inner group are eligible for output.
TimeWrapper
~~~~~~~~~~~
Some modules that output times use TimeWrapper to format these. TimeWrapper is
a mere extension of the standard formatting method.
The time format that should be used is specified using the format specifier, i.e.
with some_time being 3951 seconds a format string like ``{some_time:%h:%m:%s}``
would produce ``1:5:51``.
* ``%h``, ``%m`` and ``%s`` are the hours, minutes and seconds without
leading zeros (i.e. 0 to 59 for minutes and seconds)
* ``%H``, ``%M`` and ``%S`` are padded with a leading zero to two digits,
i.e. 00 to 59
* ``%l`` and ``%L`` produce hours non-padded and padded but only if hours
is not zero. If the hours are zero it produces an empty string.
* ``%%`` produces a literal %
* ``%E`` (only valid on beginning of the string) if the time is null,
don't format anything but rather produce an empty string. If the
time is non-null it is removed from the string.
* When the module in question also uses formatp, 0 seconds counts as
"not known".
* The formatted time is stripped, i.e. spaces on both ends of the
result are removed.
Modules
-------
:System: `clock`_ - `disk`_ - `load`_ - `mem`_ - `cpu\_usage`_
:Audio: `alsa`_ - `pulseaudio`_
:Hardware: `battery`_ - `backlight`_ - `temp`_
:Network: `network`_ - `wireless`_
:Music: `now\_playing`_ - `mpd`_
:Websites & stuff: `weather`_ - `bitcoin`_ - `reddit`_ - `parcel`_
:Other: `mail`_ - `pyload`_ - `text`_
:Advanced: `file`_ - `regex`_ - `runwatch`_ - `shell`_
!!module_doc!!
Contribute
----------
To contribute a module, make sure it uses one of the Module classes. Most modules
use IntervalModule, which just calls a function repeatedly in a specified interval.
The output attribute should be set to a dictionary which represents your modules output,
the protocol is documented `here <http://i3wm.org/docs/i3bar-protocol.html>`_.
To update this readme run ``python -m i3pystatus.mkdocs`` in the
repository root and you're done :)
Developer documentation is available in the source code and `here
<http://i3pystatus.readthedocs.org/en/latest/>`_.
**Patches and pull requests are very welcome :-)**
Table of contents
-----------------
.. contents:: Overview of this rather long README

View File

@ -14,10 +14,15 @@
import sys, os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, os.path.abspath('.'))
sys.path.insert(0, os.path.abspath('..'))
# requires PyPI mock
import mock
MOCK_MODULES = ["alsaaudio", "netifaces", "psutil", "lxml", "lxml.html", "lxml.cssselect", "praw", "gi.repository", "pywapi", "basiciw"]
for mod_name in MOCK_MODULES:
sys.modules[mod_name] = mock.Mock()
# -- General configuration -----------------------------------------------------
@ -26,7 +31,11 @@ sys.path.insert(0, os.path.abspath('.'))
# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode']
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.viewcode',
'module_docs',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']

124
docs/configuration.rst Normal file
View File

@ -0,0 +1,124 @@
Configuration
=============
The config file is just a normal Python script.
A simple configuration file could look like this (note the additional
dependencies from :py:mod:`.network`, :py:mod:`.wireless` and :py:mod:`pulseaudio` in this
example):
::
# -*- coding: utf-8 -*-
import subprocess
from i3pystatus import Status
status = Status(standalone=True)
# Displays clock like this:
# Tue 30 Jul 11:59:46 PM KW31
# ^-- calendar week
status.register("clock",
format="%a %-d %b %X KW%V",)
# Shows the average load of the last minute and the last 5 minutes
# (the default value for format is used)
status.register("load")
# Shows your CPU temperature, if you have a Intel CPU
status.register("temp",
format="{temp:.0f}°C",)
# The battery monitor has many formatting options, see README for details
# This would look like this, when discharging (or charging)
# ↓14.22W 56.15% [77.81%] 2h:41m
# And like this if full:
# =14.22W 100.0% [91.21%]
#
# This would also display a desktop notification (via dbus) if the percentage
# goes below 5 percent while discharging. The block will also color RED.
status.register("battery",
format="{status}/{consumption:.2f}W {percentage:.2f}% [{percentage_design:.2f}%] {remaining:%E%hh:%Mm}",
alert=True,
alert_percentage=5,
status={
"DIS": "↓",
"CHR": "↑",
"FULL": "=",
},)
# This would look like this:
# Discharging 6h:51m
status.register("battery",
format="{status} {remaining:%E%hh:%Mm}",
alert=True,
alert_percentage=5,
status={
"DIS": "Discharging",
"CHR": "Charging",
"FULL": "Bat full",
},)
# Displays whether a DHCP client is running
status.register("runwatch",
name="DHCP",
path="/var/run/dhclient*.pid",)
# Shows the address and up/down state of eth0. If it is up the address is shown in
# green (the default value of color_up) and the CIDR-address is shown
# (i.e. 10.10.10.42/24).
# If it's down just the interface name (eth0) will be displayed in red
# (defaults of format_down and color_down)
#
# Note: the network module requires PyPI package netifaces
status.register("network",
interface="eth0",
format_up="{v4cidr}",)
# Has all the options of the normal network and adds some wireless specific things
# like quality and network names.
#
# Note: requires both netifaces and basiciw
status.register("wireless",
interface="wlan0",
format_up="{essid} {quality:03.0f}%",)
# Shows disk usage of /
# Format:
# 42/128G [86G]
status.register("disk",
path="/",
format="{used}/{total}G [{avail}G]",)
# Shows pulseaudio default sink volume
#
# Note: requires libpulseaudio from PyPI
status.register("pulseaudio",
format="♪{volume}",)
# Shows mpd status
# Format:
# Cloud connected▶Reroute to Remain
status.register("mpd",
format="{title}{status}{album}",
status={
"pause": "▷",
"play": "▶",
"stop": "◾",
},)
status.run()
Also change your i3wm config to the following:
::
# i3bar
bar {
status_command python ~/.path/to/your/config/file.py
position top
workspace_buttons yes
}

62
docs/formatting.rst Normal file
View File

@ -0,0 +1,62 @@
Formatting
==========
All modules let you specifiy the exact output formatting using a
`format string <http://docs.python.org/3/library/string.html#formatstrings>`_, which
gives you a great deal of flexibility.
If a module gives you a float, it probably has a ton of
uninteresting decimal places. Use ``{somefloat:.0f}`` to get the integer
value, ``{somefloat:0.2f}`` gives you two decimal places after the
decimal dot
.. _formatp:
formatp
-------
Some modules use an extended format string syntax (the mpd module, for example).
Given the format string below the output adapts itself to the available data.
::
[{artist}/{album}/]{title}{status}
Only if both the artist and album is known they're displayed. If only one or none
of them is known the entire group between the brackets is excluded.
"is known" is here defined as "value evaluating to True in Python", i.e. an empty
string or 0 (or 0.0) counts as "not known".
Inside a group always all format specifiers must evaluate to true (logical and).
You can nest groups. The inner group will only become part of the output if both
the outer group and the inner group are eligible for output.
.. _TimeWrapper:
TimeWrapper
-----------
Some modules that output times use TimeWrapper to format these. TimeWrapper is
a mere extension of the standard formatting method.
The time format that should be used is specified using the format specifier, i.e.
with some_time being 3951 seconds a format string like ``{some_time:%h:%m:%s}``
would produce ``1:5:51``.
* ``%h``, ``%m`` and ``%s`` are the hours, minutes and seconds without
leading zeros (i.e. 0 to 59 for minutes and seconds)
* ``%H``, ``%M`` and ``%S`` are padded with a leading zero to two digits,
i.e. 00 to 59
* ``%l`` and ``%L`` produce hours non-padded and padded but only if hours
is not zero. If the hours are zero it produces an empty string.
* ``%%`` produces a literal %
* ``%E`` (only valid on beginning of the string) if the time is null,
don't format anything but rather produce an empty string. If the
time is non-null it is removed from the string.
* When the module in question also uses formatp, 0 seconds counts as
"not known".
* The formatted time is stripped, i.e. spaces on both ends of the
result are removed.

9
docs/i3pystatus.rst Normal file
View File

@ -0,0 +1,9 @@
Module reference
================
.. The contents of this file are automatically extended in-memory by
the module_docs extension (see docs/module_docs.py).
Do not change the whitespace after .. admonition. Sincerely, your past self.
.. admonition:: All modules

View File

@ -1,14 +1,17 @@
Welcome to i3pystatus's documentation!
======================================
Welcome to the i3pystatus documentation!
========================================
Contents:
.. toctree::
:maxdepth: 4
module
configuration
formatting
i3pystatus
i3pystatus.core
module
Indices and tables

93
docs/module_docs.py Normal file
View File

@ -0,0 +1,93 @@
import pkgutil
import sphinx.application
import i3pystatus.core.settings
def is_module(obj):
return isinstance(obj, type) \
and issubclass(obj, i3pystatus.core.settings.SettingsBase) \
and not obj.__module__.startswith("i3pystatus.core.")
def process_docstring(app, what, name, obj, options, lines):
class Setting:
doc = ""
required = False
default = sentinel = object()
empty = object()
def __init__(self, cls, setting):
if isinstance(setting, tuple):
self.name = setting[0]
self.doc = setting[1]
else:
self.name = setting
if setting in cls.required:
self.required = True
elif hasattr(cls, self.name):
default = getattr(cls, self.name)
if isinstance(default, str) and not len(default)\
or default is None:
default = self.empty
self.default = default
def __str__(self):
attrs = []
if self.required:
attrs.append("required")
if self.default not in [self.sentinel, self.empty]:
attrs.append("default: ``{default}``".format(default=self.default))
if self.default is self.empty:
attrs.append("default: *empty*")
formatted = "* **{name}** {doc}".format(name=self.name, doc=self.doc)
if attrs:
formatted += " ({attrs})".format(attrs=", ".join(attrs))
return formatted
if is_module(obj):
lines.append(".. rubric:: Settings")
lines.append("")
for setting in obj.settings:
lines.append(str(Setting(obj, setting)))
def process_signature(app, what, name, obj, options, signature, return_annotation):
if is_module(obj):
return ("", return_annotation)
def source_read(app, docname, source):
ignore_modules = ("__main__", "mkdocs", "core")
def get_modules(path):
modules = []
for finder, modname, is_pkg in pkgutil.iter_modules(path):
if modname not in ignore_modules:
modules.append("i3pystatus." + modname)
return modules
if docname == "i3pystatus":
modules = sorted(get_modules(i3pystatus.__path__))
for mod in modules:
# sphinx seems to discard .append()ed items
source[0] += " * :py:class:`~{}`\n".format(mod)
for mod in modules:
source[0] += (".. automodule:: " + mod + "\n" +
" :members:\n\n")
def setup(app: sphinx.application.Sphinx):
app.connect("source-read", source_read)
app.connect("autodoc-process-docstring", process_docstring)
app.connect("autodoc-process-signature", process_signature)

View File

@ -13,8 +13,8 @@ class CpuUsageBar(CpuUsage):
Available formatters:
* {usage_bar} usage average of all cores
* {usage_bar_cpu*} usage of one specific core. replace "*"
by core number starting at 0
* {usage_bar_cpuN} usage of one specific core. replace "N" by core number starting at 0
"""

View File

@ -1,138 +0,0 @@
#!/usr/bin/env python
import pkgutil
import textwrap
import i3pystatus
import i3pystatus.mail
from .core.imputil import ClassFinder
IGNORE = ("__main__", "mkdocs", "core")
MODULE_FORMAT = """
{name}
{heading}
{doc}
Settings:
{settings}
{endstring}\n"""
class Module:
name = ""
doc = ""
endstring = ""
def __init__(self, cls, neighbours, module_name, module, heading):
self.settings = []
self.cls = cls
self.heading = heading
if neighbours == 1:
self.name = module_name
else:
self.name = "{module}.{cls}".format(
module=module_name, cls=self.cls.__name__)
self.doc = self.cls.__doc__ or module.__doc__ or ""
if hasattr(self.cls, "_endstring"):
self.endstring = self.cls._endstring
self.read_settings()
def read_settings(self):
for setting in self.cls.settings:
self.settings.append(Setting(self.cls, setting))
def format_settings(self):
return "\n".join(map(str, self.settings))
def __str__(self):
return MODULE_FORMAT.format(
name=self.name,
doc=textwrap.dedent(self.doc),
settings=self.format_settings(),
heading=self.heading * len(self.name),
endstring=self.endstring
)
class Setting:
doc = ""
required = False
default = sentinel = object()
def __init__(self, cls, setting):
if isinstance(setting, tuple):
self.name = setting[0]
self.doc = setting[1]
else:
self.name = setting
if setting in cls.required:
self.required = True
elif hasattr(cls, self.name):
self.default = getattr(cls, self.name)
def __str__(self):
attrs = []
if self.required:
attrs.append("required")
if self.default is not self.sentinel:
attrs.append("default: ``{default}``".format(default=self.default))
formatted = ":{name}: {doc}".format(name=self.name, doc=self.doc)
if attrs:
formatted += " ({attrs})".format(attrs=", ".join(attrs))
return formatted
def get_modules(path):
modules = []
for finder, modname, ispkg in pkgutil.iter_modules(path):
if modname not in IGNORE:
modules.append(get_module(finder, modname))
return modules
def get_module(finder, modname):
fullname = "i3pystatus.{modname}".format(modname=modname)
return (modname, finder.find_loader(fullname)[0].load_module(fullname))
def get_all(module_path, heading, finder=None, ignore=None):
mods = []
if not finder:
finder = ClassFinder(i3pystatus.Module)
for name, module in get_modules(module_path):
classes = finder.get_matching_classes(module)
found = []
for cls in classes:
if cls.__name__ not in found:
found.append(cls.__name__)
mods.append(
Module(cls, neighbours=len(classes), module_name=name, module=module, heading=heading))
return sorted(mods, key=lambda module: module.name)
def generate_doc_for_module(module_path, heading="+", finder=None, ignore=None):
return "".join(map(str, get_all(module_path, heading, finder, ignore or [])))
with open("README.tpl.rst", "r") as template:
tpl = template.read()
tpl = tpl.replace(
"!!module_doc!!", generate_doc_for_module(i3pystatus.__path__))
finder = ClassFinder(baseclass=i3pystatus.mail.Backend)
tpl = tpl.replace("!!i3pystatus.mail!!", generate_doc_for_module(
i3pystatus.mail.__path__, "~", finder, ["Backend"]))
with open("README.rst", "w") as output:
output.write(tpl + "\n")

View File

@ -9,13 +9,13 @@ class MPD(IntervalModule):
"""
Displays various information from MPD (the music player daemon)
Available formatters (uses `formatp`_)
Available formatters (uses :ref:`formatp`)
* `{title}` (the title of the current song)
* `{album}` (the album of the current song, can be an empty string (e.g. for online streams))
* `{artist}` (can be empty, too)
* `{filename}` (file name with out extension and path; empty unless title is empty)
* `{song_elapsed}` (Position in the currently playing song, uses `TimeWrapper`_, default is `%m:%S`)
* `{song_elapsed}` (Position in the currently playing song, uses :ref:`TimeWrapper`, default is `%m:%S`)
* `{song_length}` (Length of the current song, same as song_elapsed)
* `{pos}` (Position of current song in playlist, one-based)
* `{len}` (Songs in playlist)

View File

@ -12,13 +12,13 @@ class NowPlaying(IntervalModule):
"""
Shows currently playing track information, supports most media players
Available formatters (uses `formatp`_)
Available formatters (uses :ref:`formatp`)
* `{title}` (the title of the current song)
* `{album}` (the album of the current song, can be an empty string (e.g. for online streams))
* `{artist}` (can be empty, too)
* `{filename}` (file name with out extension and path; empty unless title is empty)
* `{song_elapsed}` (Position in the currently playing song, uses `TimeWrapper`_, default is `%m:%S`)
* `{song_elapsed}` (Position in the currently playing song, uses :ref:`TimeWrapper`, default is `%m:%S`)
* `{song_length}` (Length of the current song, same as song_elapsed)
* `{status}` (play, pause, stop mapped through the `status` dictionary)
* `{volume}` (Volume)