From 344ad4647fcd285cec8684c8e7953f057cd44bf6 Mon Sep 17 00:00:00 2001 From: enkore Date: Sun, 12 Oct 2014 01:32:29 +0200 Subject: [PATCH] Moved all docs to sphinx. Nothing changes for module authors. --- .travis.yml | 1 + README.rst | 1097 +---------------------------------- README.tpl.rst | 394 ------------- docs/conf.py | 17 +- docs/configuration.rst | 124 ++++ docs/formatting.rst | 62 ++ docs/i3pystatus.rst | 9 + docs/index.rst | 9 +- docs/module_docs.py | 93 +++ i3pystatus/cpu_usage_bar.py | 4 +- i3pystatus/mkdocs.py | 138 ----- i3pystatus/mpd.py | 4 +- i3pystatus/now_playing.py | 4 +- 13 files changed, 321 insertions(+), 1635 deletions(-) delete mode 100644 README.tpl.rst create mode 100644 docs/configuration.rst create mode 100644 docs/formatting.rst create mode 100644 docs/i3pystatus.rst create mode 100644 docs/module_docs.py delete mode 100755 i3pystatus/mkdocs.py diff --git a/.travis.yml b/.travis.yml index 7296f6f..d8772d4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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 diff --git a/README.rst b/README.rst index 4dcc1e3..c52697d 100644 --- a/README.rst +++ b/README.rst @@ -35,6 +35,13 @@ Packages for your OS * `Arch Linux `_ +Modules +------- + +The module docs have been moved to `here `_ + + + Release Notes ------------- @@ -174,1090 +181,6 @@ configuration file** 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 `_, 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`_ - - -alsa -++++ - - -Shows volume of ALSA mixer. You can also use this for inputs, btw. - -Requires pyalsaaudio - -Available formatters: - -* `{volume}` — the current volume in percent -* `{muted}` — the value of one of the `muted` or `unmuted` settings -* `{card}` — the associated soundcard -* `{mixer}` — the associated ALSA mixer - - -Settings: - -:format: (default: ``♪: {volume}``) -:format_muted: optional format string to use when muted (default: ``None``) -:mixer: ALSA mixer (default: ``Master``) -:mixer_id: ALSA mixer id (default: ``0``) -:card: ALSA sound card (default: ``0``) -:increment: integer percentage of max volume to in/decrement volume on mousewheel (default: ``5``) -:muted: (default: ``M``) -:unmuted: (default: ````) -:color_muted: (default: ``#AAAAAA``) -:color: (default: ``#FFFFFF``) -:channel: (default: ``0``) -:interval: (default: ``1``) - - - -backlight -+++++++++ - - -Screen backlight info - -Available formatters: - -* `{brightness}` — current brightness relative to max_brightness -* `{max_brightness}` — maximum brightness value -* `{percentage}` — current brightness in percent - - -Settings: - -:format: format string, formatters: brightness, max_brightness, percentage (default: ``{brightness}/{max_brightness}``) -:backlight: backlight, see `/sys/class/backlight/` (default: ``acpi_video0``) -:color: (default: ``#FFFFFF``) -:interval: (default: ``5``) - - - -battery -+++++++ - - -This class uses the /sys/class/power_supply/…/uevent interface to check for the -battery status - -Available formatters: - -* `{remaining}` — remaining time for charging or discharging, uses TimeWrapper formatting, default format is `%E%h:%M` -* `{percentage}` — battery percentage relative to the last full value -* `{percentage_design}` — absolute battery charge percentage -* `{consumption (Watts)}` — current power flowing into/out of the battery -* `{status}` -* `{battery_ident}` — the same as the setting -* `{bar}` —bar displaying the percentage graphically - - -Settings: - -:battery_ident: The name of your battery, usually BAT0 or BAT1 (default: ``BAT0``) -:format: (default: ``{status} {remaining}``) -:not_present_text: Text displayed if the battery is not present. No formatters are available (default: ``Battery not present``) -:alert: Display a libnotify-notification on low battery (default: ``False``) -:alert_percentage: (default: ``10``) -:alert_format_title: The title of the notification, all formatters can be used (default: ``Low battery``) -:alert_format_body: The body text of the notification, all formatters can be used (default: ``Battery {battery_ident} has only {percentage:.2f}% ({remaining:%E%hh:%Mm}) remaining!``) -:path: Override the default-generated path (default: ``None``) -:status: A dictionary mapping ('DIS', 'CHR', 'FULL') to alternative names (default: ``{'DIS': 'DIS', 'CHR': 'CHR', 'FULL': 'FULL'}``) -:color: The text color (default: ``#ffffff``) -:full_color: The full color (default: ``#00ff00``) -:charging_color: The charging color (default: ``#00ff00``) -:critical_color: The critical color (default: ``#ff0000``) -:not_present_color: The not present color. (default: ``#ffffff``) -:no_text_full: Don't display text when battery is full - 100% (default: ``False``) -:interval: (default: ``5``) - - - -bitcoin -+++++++ - - -This module fetches and displays current Bitcoin market prices and -optionally monitors transactions to and from a list of user-specified -wallet addresses. Market data is pulled from the BitcoinAverage Price -Index API while transaction data is pulled -from blockchain.info . - -Available formatters: - -* {last_price} -* {ask_price} -* {bid_price} -* {daily_average} -* {volume} -* {status} -* {last_tx_type} -* {last_tx_addr} -* {last_tx_value} -* {balance_btc} -* {balance_fiat} - - - -Settings: - -:format: Format string used for output. (default: ``฿ {status}{last_price}``) -:currency: Base fiat currency used for pricing. (default: ``USD``) -:wallet_addresses: List of wallet address(es) to monitor. (default: ````) -:color: Standard color (default: ``#FFFFFF``) -:colorize: Enable color change on price increase/decrease (default: ``False``) -:color_up: Color for price increases (default: ``#00FF00``) -:color_down: Color for price decreases (default: ``#FF0000``) -:leftclick: URL to visit or command to run on left click (default: ``electrum``) -:rightclick: URL to visit or command to run on right click (default: ``https://bitcoinaverage.com/``) -:interval: Update interval. (default: ``600``) -:status: (default: ``{'price_up': '▲', 'price_down': '▼'}``) - - - -clock -+++++ - - -This class shows a clock - - -Settings: - -:format: list of tuple (stftime format string, optional timezone), `None` means to use the default, locale-dependent format. Can cycle between formats with mousewheel (default: ``None``) -:color: RGB hexadecimal code color specifier, default to #ffffff, set to `i3Bar` to use i3 bar default (default: ``#ffffff``) -:interval: (default: ``1``) - - - -cpu_usage -+++++++++ - - -Shows CPU usage. -The first output will be inacurate. - -Linux only - -Available formatters: - -* {usage} usage average of all cores -* {usage_cpu*} usage of one specific core. replace "*" by core number starting at 0 -* {usage_all} usage of all cores separate. usess natsort when available(relevant for more than 10 cores) - - - -Settings: - -:format: format string. (default: ``{usage:02}%``) -:format_all: format string used for {usage_all} per core. Available formaters are {core} and {usage}. (default: ``{core}:{usage:02}%``) -:exclude_average: If True usage average of all cores will not be in format_all. (default: ``False``) -:interval: (default: ``5``) - - - -cpu_usage_bar -+++++++++++++ - - -Shows CPU usage as a bar (made with unicode box characters). -The first output will be inacurate. - -Linux only - -Available formatters: - -* {usage_bar} usage average of all cores -* {usage_bar_cpu*} usage of one specific core. replace "*" -by core number starting at 0 - - - -Settings: - -:format: format string (default: ``{usage_bar}``) -:interval: (default: ``5``) - - - -disk -++++ - - -Gets ``{used}``, ``{free}``, ``{available}`` and ``{total}`` amount of bytes on the given mounted filesystem. - -These values can also be expressed as percentages with the ``{percentage_used}``, ``{percentage_free}`` -and ``{percentage_avail}`` formats. - - -Settings: - -:format: (default: ``{free}/{avail}``) -:path: (required) -:divisor: divide all byte values by this value, default is 1024**3 (gigabyte) (default: ``1073741824``) -:display_limit: if more space is available than this limit the module is hidden (default: ``inf``) -:critical_limit: critical space limit (see critical_color) (default: ``0``) -:critical_color: the critical color (default: ``#FF0000``) -:color: the common color (default: ``#FFFFFF``) -:round_size: precision, None for INT (default: ``2``) -:interval: (default: ``5``) - - - -file -++++ - - -Rip information from text files - -components is a dict of pairs of the form: - -:: - - name => (callable, file) - -* Where `name` is a valid identifier, which is used in the format string to access - the value of that component. -* `callable` is some callable to convert the contents of `file`. A common choice is - float or int. -* `file` names a file, relative to `base_path`. - -transforms is a optional dict of callables taking a single argument (a dictionary containing the values -of all components). The return value is bound to the key. - - -Settings: - -:format: (required) -:components: (required) -:transforms: (default: ``{}``) -:base_path: (default: ``/``) -:color: (default: ``#FFFFFF``) -:interval: (default: ``5``) - - - -load -++++ - - -Shows system load - - -Settings: - -:format: format string used for output. {avg1}, {avg5} and {avg15} are the load average of the last one, five and fifteen minutes, respectively. {tasks} is the number of tasks (i.e. 1/285, which indiciates that one out of 285 total tasks is runnable). (default: ``{avg1} {avg5}``) -:color: The text color (default: ``#ffffff``) -:critical_limit: Limit above which the load is considered critical (default: ``1``) -:critical_color: The critical color (default: ``#ff0000``) -:interval: (default: ``5``) - - - -mail -++++ - - -Generic mail checker - -The `backends` setting determines the backends to use. - - -Settings: - -:backends: List of backends (instances of ``i3pystatus.mail.xxx.zzz``, i.e. ``i3pystatus.mail.imap.IMAP``) -:color: (default: ``#ffffff``) -:color_unread: (default: ``#ff0000``) -:format: (default: ``{unread} new email``) -:format_plural: (default: ``{unread} new emails``) -:hide_if_null: Don't output anything if there are no new mails (default: ``True``) -:email_client: The email client to open on left click (default: ``None``) -:interval: (default: ``5``) - - -imap.IMAP -~~~~~~~~~ - - -Checks for mail on a IMAP server - - -Settings: - -:host: (required) -:port: (default: ``993``) -:username: (required) -:password: (required) -:ssl: (default: ``True``) -:mailbox: (default: ``INBOX``) - - - -maildir.MaildirMail -~~~~~~~~~~~~~~~~~~~ - - -Checks for local mail in Maildir - - -Settings: - -:directory: (required) - - - -mbox.MboxMail -~~~~~~~~~~~~~ - - -Checks for local mail in mbox - - -Settings: - - - - - -notmuchmail.Notmuch -~~~~~~~~~~~~~~~~~~~ - - -This class uses the notmuch python bindings to check for the -number of messages in the notmuch database with the tags "inbox" -and "unread" - - -Settings: - -:db_path: Path to the directory of your notmuch database (default: ``None``) - - - -thunderbird.Thunderbird -~~~~~~~~~~~~~~~~~~~~~~~ - - -This class listens for dbus signals emitted by -the dbus-sender extension for thunderbird. - -Requires python-dbus - - -Settings: - - - - - - -mem -+++ - - -Shows memory load - -Available formatters: - -* {avail_mem} -* {percent_used_mem} -* {used_mem} -* {total_mem} - -Requires psutil (from PyPI) - - -Settings: - -:format: format string used for output. (default: ``{avail_mem} MiB``) -:divisor: divide all byte values by this value, default 1024**2(mebibytes (default: ``1048576``) -:warn_percentage: minimal percentage for warn state (default: ``50``) -:alert_percentage: minimal percentage for alert state (default: ``80``) -:color: standard color (default: ``#00FF00``) -:warn_color: defines the color used wann warn percentage ist exceeded (default: ``#FFFF00``) -:alert_color: defines the color used when alert percentage is exceeded (default: ``#FF0000``) -:round_size: defines number of digits in round (default: ``1``) -:interval: (default: ``5``) - - - -mem_bar -+++++++ - - -Shows memory load as a bar. - -Available formatters: -* {used_mem_bar} - -Requires psutil (from PyPI) - - -Settings: - -:format: format string used for output. (default: ``{used_mem_bar}``) -:warn_percentage: minimal percentage for warn state (default: ``50``) -:alert_percentage: minimal percentage for alert state (default: ``80``) -:color: standard color (default: ``#00FF00``) -:warn_color: defines the color used wann warn percentage ist exceeded (default: ``#FFFF00``) -:alert_color: defines the color used when alert percentage is exceeded (default: ``#FF0000``) -:interval: (default: ``5``) - - - -modsde -++++++ - - -This class returns i3status parsable output of the number of -unread posts in any bookmark in the mods.de forums. - - -Settings: - -:format: Use {unread} as the formatter for number of unread posts (default: ``{unread} new posts in bookmarks``) -:offset: subtract number of posts before output (default: ``0``) -:color: (default: ``#7181fe``) -:username: (required) -:password: (required) -:interval: (default: ``5``) - - - -mpd -+++ - - -Displays various information from MPD (the music player daemon) - -Available formatters (uses `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_length}` — (Length of the current song, same as song_elapsed) -* `{pos}` — (Position of current song in playlist, one-based) -* `{len}` — (Songs in playlist) -* `{status}` — (play, pause, stop mapped through the `status` dictionary) -* `{bitrate}` — (Current bitrate in kilobit/s) -* `{volume}` — (Volume set in MPD) - -Left click on the module play/pauses, right click (un)mutes. - - -Settings: - -:host: (default: ``localhost``) -:port: MPD port (default: ``6600``) -:format: formatp string (default: ``{title} {status}``) -:status: Dictionary mapping pause, play and stop to output (default: ``{'pause': '▷', 'stop': '◾', 'play': '▶'}``) -:color: The color of the text (default: ``#FFFFFF``) -:interval: (default: ``1``) - - - -network -+++++++ - - -Display network information about a interface. - -Requires the PyPI package `netifaces`. - -Available formatters: - -* `{interface}` — same as setting -* `{name}` — same as setting -* `{v4}` — IPv4 address -* `{v4mask}` — subnet mask -* `{v4cidr}` — IPv4 address in cidr notation (i.e. 192.168.2.204/24) -* `{v6}` — IPv6 address -* `{v6mask}` — subnet mask -* `{v6cidr}` — IPv6 address in cidr notation -* `{mac}` — MAC of interface - -Not available addresses (i.e. no IPv6 connectivity) are replaced with empty strings. - - -Settings: - -:interface: Interface to obtain information for (default: ``eth0``) -:format_up: (default: ``{interface}: {v4}``) -:color_up: (default: ``#00FF00``) -:format_down: (default: ``{interface}``) -:color_down: (default: ``#FF0000``) -:detached_down: If the interface doesn't exist, display it as if it were down (default: ``True``) -:unknown_up: If the interface is in unknown state, display it as if it were up (default: ``False``) -:name: (default: ``eth0``) -:interval: (default: ``5``) - - - -network_traffic -+++++++++++++++ - - -Network traffic per interface, i.e., packets/bytes sent/received per second. - -Requires the PyPI packages `psutil`. - -Available formatters: - -* `{interface}` — the configured network interface -* `{bytes_sent}` — bytes sent per second (divided by divisor) -* `{bytes_recv}` — bytes received per second (divided by divisor) -* `{packets_sent}` — bytes sent per second (divided by divisor) -* `{packets_recv}` — bytes received per second (divided by divisor) - - -Settings: - -:format: format string (default: ``{interface} ↗{bytes_sent}kB/s ↘{bytes_recv}kB/s``) -:interface: network interface (default: ``eth0``) -:divisor: divide all byte values by this value (default: ``1024``) -:round_size: defines number of digits in round (default: ``None``) -:interval: (default: ``1``) - - - -now_playing -+++++++++++ - - -Shows currently playing track information, supports most media players - -Available formatters (uses `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_length}` — (Length of the current song, same as song_elapsed) -* `{status}` — (play, pause, stop mapped through the `status` dictionary) -* `{volume}` — (Volume) - -Left click on the module play/pauses, right click goes to the next track. - -Requires python-dbus available from every distros' package manager. - - -Settings: - -:player: Player name (default: ``None``) -:status: Dictionary mapping pause, play and stop to output text (default: ``{'pause': '▷', 'stop': '◾', 'play': '▶'}``) -:color: Text color (default: ``#FFFFFF``) -:format: formatp string (default: ``{title} {status}``) -:interval: (default: ``1``) - - - -parcel -++++++ - - -Used to track parcel/shipments. - -Supported carriers: DHL, UPS, Itella - -- parcel.UPS("") -- parcel.DHL("") -- parcel.Itella(""[, "en"|"fi"|"sv"]) - Second parameter is language. Requires beautiful soup 4 (bs4) - -Requires lxml and cssselect. - - -Settings: - -:instance: Tracker instance, for example ``parcel.UPS('your_id_code')`` -:format: (default: ``{name}:{progress}``) -:name: -:interval: (default: ``60``) - - - -pulseaudio -++++++++++ - - -Shows volume of default PulseAudio sink (output). - -Available formatters: - -* `{volume}` — volume in percent (0...100) -* `{db}` — volume in decibels relative to 100 %, i.e. 100 % = 0 dB, 50 % = -18 dB, 0 % = -infinity dB - (the literal value for -infinity is `-∞`) -* `{muted}` — the value of one of the `muted` or `unmuted` settings - - -Settings: - -:format: (default: ``♪: {volume}``) -:format_muted: optional format string to use when muted (default: ``None``) -:muted: (default: ``M``) -:unmuted: (default: ````) -:color_muted: (default: ``#FF0000``) -:color_unmuted: (default: ``#FFFFFF``) - - - -pyload -++++++ - - -Shows pyLoad status - -Available formatters: - -* `{captcha}` (see captcha_true and captcha_false, which are the values filled in for this formatter) -* `{progress}` (average over all running downloads) -* `{progress_all}` (percentage of completed files/links in queue) -* `{speed}` (kilobytes/s) -* `{download}` (downloads enabled, also see download_true and download_false) -* `{total}` (number of downloads) -* `{free_space}` (free space in download directory in gigabytes) - - -Settings: - -:address: Address of pyLoad webinterface (default: ``http://127.0.0.1:8000``) -:format: (default: ``{captcha} {progress_all:.1f}% {speed:.1f} kb/s``) -:captcha_true: (default: ``Captcha waiting``) -:captcha_false: (default: ````) -:download_true: (default: ``Downloads enabled``) -:download_false: (default: ``Downloads disabled``) -:username: (required) -:password: (required) -:interval: (default: ``5``) - - - -reddit -++++++ - - -This module fetches and displays posts and/or user mail/messages from -reddit.com. Left-clicking on the display text opens the permalink/comments -page using webbrowser.open() while right-clicking opens the URL of the -submission directly. Depends on the Python Reddit API Wrapper (PRAW) -. - -Available formatters: - -* {submission_title} -* {submission_author} -* {submission_points} -* {submission_comments} -* {submission_permalink} -* {submission_url} -* {submission_domain} -* {submission_subreddit} -* {message_unread} -* {message_author} -* {message_subject} -* {message_body} - - - -Settings: - -:format: Format string used for output. (default: ``[{submission_subreddit}] {submission_title} ({submission_domain})``) -:username: Reddit username. (default: ````) -:password: Reddit password. (default: ````) -:subreddit: Subreddit to monitor. Uses frontpage if unspecified. (default: ````) -:sort_by: 'hot', 'new', 'rising', 'controversial', or 'top'. (default: ``hot``) -:color: Standard color. (default: ``#FFFFFF``) -:colorize: Enable color change on new message. (default: ``True``) -:color_orangered: Color for new messages. (default: ``#FF4500``) -:mail_brackets: Display unread message count in square-brackets. (default: ``False``) -:title_maxlen: Maximum number of characters to display in title. (default: ``80``) -:interval: Update interval. (default: ``300``) -:status: New message indicator. (default: ``{'new_mail': '✉', 'no_mail': ''}``) - - - -regex -+++++ - - -Simple regex file watcher - -The groups of the regex are passed to the format string as positional arguments. - - -Settings: - -:format: format string used for output (default: ``{0}``) -:regex: (required) -:file: file to search for regex matches -:flags: Python.re flags (default: ``0``) -:interval: (default: ``5``) - - - -runwatch -++++++++ - - -Expands the given path using glob to a pidfile and checks -if the process ID found inside is valid -(that is, if the process is running). -You can use this to check if a specific application, -such as a VPN client or your DHCP client is running. - -Available formatters are {pid} and {name}. - - -Settings: - -:format_up: (default: ``{name}``) -:format_down: (default: ``{name}``) -:color_up: (default: ``#00FF00``) -:color_down: (default: ``#FF0000``) -:path: (required) -:name: (required) -:interval: (default: ``5``) - - - -shell -+++++ - - -Shows output of shell command - - -Settings: - -:command: command to be executed -:color: standard color (default: ``#FFFFFF``) -:error_color: color to use when non zero exit code is returned (default: ``#FF0000``) -:interval: (default: ``5``) - - - -spotify -+++++++ - - -This class shows information from Spotify. - -Left click will toggle pause/play of the current song. -Right click will skip the song. - -Dependent on Playerctl ( https://github.com/acrisci/playerctl ) and GLib - - -Settings: - -:format: Format string. {artist}, {title}, {album}, {volume}, and {length} are available for output. (default: ``{artist} - {title}``) -:color: color of the output (default: ``#ffffff``) - - - -temp -++++ - - -Shows CPU temperature of Intel processors - -AMD is currently not supported as they can only report a relative temperature, which is pretty useless - - -Settings: - -:format: format string used for output. {temp} is the temperature in degrees celsius (default: ``{temp} °C``) -:color: (default: ``#FFFFFF``) -:file: (default: ``/sys/class/thermal/thermal_zone0/temp``) -:interval: (default: ``5``) - - - -text -++++ - - -Display static, colored text. - - -Settings: - -:text: (required) -:color: HTML color code #RRGGBB (default: ``None``) -:cmd_leftclick: Shell command to execute on left click (default: ``test``) -:cmd_rightclick: Shell command to execute on right click (default: ``test``) - - - -uptime -++++++ - - -Outputs Uptime - - -Settings: - -:format: Format string (default: ``up {uptime}``) -:color: String color (default: ``#ffffff``) -:alert: If you want the string to change color (default: ``False``) -:seconds_alert: How many seconds necessary to start the alert (default: ``3600``) -:color_alert: Alert color (default: ``#ff0000``) -:interval: (default: ``5``) - - - -weather -+++++++ - - -This module gets the weather from weather.com using pywapi module -First, you need to get the code for the location from the www.weather.com -Available formatters: - -* {current_temp} -* {current_wind} -* {humidity} - -Requires pywapi from PyPI. - - -Settings: - -:location_code: (required) -:colorize: Enable color with temperature and UTF-8 icons. (default: ``False``) -:units: Celsius (metric) or Fahrenheit (imperial) (default: ``metric``) -:format: (default: ``{current_temp}``) -:interval: (default: ``20``) - - - -wireless -++++++++ - - -Display network information about a interface. - -Requires the PyPI packages `netifaces` and `basiciw`. - -This is based on the network module, so all options and formatters are -the same, except for these additional formatters and that detached_down doesn't work. - -* `{essid}` — ESSID of currently connected wifi -* `{freq}` — Current frequency -* `{quality}` — Link quality in percent -* `{quality_bar}` —Bar graphically representing link quality - - -Settings: - -:interface: Interface to obtain information for (default: ``wlan0``) -:format_up: (default: ``{interface}: {v4}``) -:color_up: (default: ``#00FF00``) -:format_down: (default: ``{interface}``) -:color_down: (default: ``#FF0000``) -:detached_down: If the interface doesn't exist, display it as if it were down (default: ``True``) -:unknown_up: If the interface is in unknown state, display it as if it were up (default: ``False``) -:name: (default: ``eth0``) -:interval: (default: ``5``) - - - - Contribute ---------- @@ -1274,9 +197,3 @@ Developer documentation is available in the source code and `here `_. **Patches and pull requests are very welcome :-)** - -Table of contents ------------------ - -.. contents:: Overview of this rather long README - diff --git a/README.tpl.rst b/README.tpl.rst deleted file mode 100644 index e03be04..0000000 --- a/README.tpl.rst +++ /dev/null @@ -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 `_ -+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - -:: - - pip install i3pystatus - -Packages for your OS -++++++++++++++++++++ - -* `Arch Linux `_ - -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 `_, 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 `_. - -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 -`_. - -**Patches and pull requests are very welcome :-)** - -Table of contents ------------------ - -.. contents:: Overview of this rather long README diff --git a/docs/conf.py b/docs/conf.py index ad9c223..491c063 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -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'] diff --git a/docs/configuration.rst b/docs/configuration.rst new file mode 100644 index 0000000..06807ff --- /dev/null +++ b/docs/configuration.rst @@ -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 + } diff --git a/docs/formatting.rst b/docs/formatting.rst new file mode 100644 index 0000000..6304b7a --- /dev/null +++ b/docs/formatting.rst @@ -0,0 +1,62 @@ +Formatting +========== + +All modules let you specifiy the exact output formatting using a +`format string `_, 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. diff --git a/docs/i3pystatus.rst b/docs/i3pystatus.rst new file mode 100644 index 0000000..95afa45 --- /dev/null +++ b/docs/i3pystatus.rst @@ -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 + diff --git a/docs/index.rst b/docs/index.rst index f425879..1a6d7c7 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -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 diff --git a/docs/module_docs.py b/docs/module_docs.py new file mode 100644 index 0000000..58d8199 --- /dev/null +++ b/docs/module_docs.py @@ -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) diff --git a/i3pystatus/cpu_usage_bar.py b/i3pystatus/cpu_usage_bar.py index 2c3b037..640b367 100644 --- a/i3pystatus/cpu_usage_bar.py +++ b/i3pystatus/cpu_usage_bar.py @@ -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 + """ diff --git a/i3pystatus/mkdocs.py b/i3pystatus/mkdocs.py deleted file mode 100755 index 18ee1c2..0000000 --- a/i3pystatus/mkdocs.py +++ /dev/null @@ -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") diff --git a/i3pystatus/mpd.py b/i3pystatus/mpd.py index cf3dc3f..f65bc80 100644 --- a/i3pystatus/mpd.py +++ b/i3pystatus/mpd.py @@ -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) diff --git a/i3pystatus/now_playing.py b/i3pystatus/now_playing.py index 5cdfec9..9d31a20 100644 --- a/i3pystatus/now_playing.py +++ b/i3pystatus/now_playing.py @@ -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)