From c055ff596761f4800c932f61822888f1f3e189a0 Mon Sep 17 00:00:00 2001 From: Kaliko Jack Date: Sat, 24 Aug 2024 19:39:16 +0200 Subject: [PATCH] Improved documentation Add supported commands returned type, generated doc from src: python3 ./doc/extract_supported_commands.py > ./doc/source/_commands.rst --- CHANGES.txt | 5 + doc/extract_supported_commands.py | 68 +++++++++++ doc/source/_commands.rst | 192 ++++++++++++++++++++++++++++++ doc/source/commands.rst | 6 +- doc/source/index.rst | 2 +- doc/source/use.rst | 4 +- musicpd.py | 28 ++--- 7 files changed, 285 insertions(+), 20 deletions(-) create mode 100644 doc/extract_supported_commands.py create mode 100644 doc/source/_commands.rst diff --git a/CHANGES.txt b/CHANGES.txt index fe285d3..449772c 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,6 +1,11 @@ python-musicpd Changes List =========================== +Changes in 0.9.1 +---------------- + + * Improved documentation, add supported commands rtype + Changes in 0.9.0 ---------------- diff --git a/doc/extract_supported_commands.py b/doc/extract_supported_commands.py new file mode 100644 index 0000000..afe2c4a --- /dev/null +++ b/doc/extract_supported_commands.py @@ -0,0 +1,68 @@ +#!/usr/bin/python3 +"""python3 ./doc/extract_supported_commands.py > ./doc/source/_commands.rst +""" +import pathlib +import re +import sys +sys.path.insert(0,pathlib.Path('.').absolute().as_posix()) +import musicpd + +START = 'self._commands = {' +END = '}' +LATEST_PROTOCOL = 'https://mpd.readthedocs.io/en/latest/protocol.html' +TYPE_MAPPING = { + 'fetch_nothing': 'None', + 'fetch_object': 'dict', + 'fetch_list': 'list', + 'fetch_item': 'str', + 'fetch_playlist': 'list', + 'fetch_songs': 'list[dict]', + 'fetch_changes': 'list[dict]', + 'fetch_composite': 'dict', + 'fetch_playlists': 'dict', + 'fetch_database': 'list[dict]', + 'fetch_mounts': 'list[dict]', + 'fetch_neighbors': 'list[dict]', + 'fetch_outputs': 'list[dict]', + 'fetch_plugins': 'list[dict]', + 'fetch_messages': 'list[dict]', +} + + +def find_start(fd): + line = fd.readline() + while START not in line: + line = fd.readline() + if not line: + break + if not line: + print('Reach end of file!', file=sys.stderr) + sys.exit(1) + + +def main(): + with open('musicpd.py', 'r', encoding='utf-8') as fd: + # fast forward to find self._commands + find_start(fd) + cmd_patt = '"(?P.*)":' + cmd_patt = r'"(?P.*?)": +self\._(?P.+?),' + tit_patt = '# (?P[^#]+?) ?# ?(?P<anchor>.+?)$' + cmd_regex = re.compile(cmd_patt) + tit_regex = re.compile(tit_patt) + print(f'Below the commands list last updated for v{musicpd.VERSION}.') + # Now extract supported commands + line = 'foo' + while line and END not in line: + line = fd.readline() + cmd = cmd_regex.search(line) + tit = tit_regex.search(line) + if tit: + print(f'\n{tit[1]}') + print('^'*len(tit[1])) + print(f'\nProtocol documentation: `{tit[1]} <{LATEST_PROTOCOL}#{tit[2]}>`_\n') + if cmd: + print(f'* **{cmd[1]}** -> {TYPE_MAPPING.get(cmd[2], "ukn")}') + + +if __name__ == '__main__': + main() diff --git a/doc/source/_commands.rst b/doc/source/_commands.rst new file mode 100644 index 0000000..18a7343 --- /dev/null +++ b/doc/source/_commands.rst @@ -0,0 +1,192 @@ +Below the commands list last updated for v0.9.1. + +Querying MPD’s status +^^^^^^^^^^^^^^^^^^^^^ + +Protocol documentation: `Querying MPD’s status <https://mpd.readthedocs.io/en/latest/protocol.html#querying-mpd-s-status>`_ + +* **clearerror** -> None +* **currentsong** -> dict +* **idle** -> list +* **status** -> dict +* **stats** -> dict + +Playback Option +^^^^^^^^^^^^^^^ + +Protocol documentation: `Playback Option <https://mpd.readthedocs.io/en/latest/protocol.html#playback-options>`_ + +* **consume** -> None +* **crossfade** -> None +* **mixrampdb** -> None +* **mixrampdelay** -> None +* **random** -> None +* **repeat** -> None +* **setvol** -> None +* **getvol** -> dict +* **single** -> None +* **replay_gain_mode** -> None +* **replay_gain_status** -> str +* **volume** -> None + +Controlling playback +^^^^^^^^^^^^^^^^^^^^ + +Protocol documentation: `Controlling playback <https://mpd.readthedocs.io/en/latest/protocol.html#controlling-playback>`_ + +* **next** -> None +* **pause** -> None +* **play** -> None +* **playid** -> None +* **previous** -> None +* **seek** -> None +* **seekid** -> None +* **seekcur** -> None +* **stop** -> None + +The Queue +^^^^^^^^^ + +Protocol documentation: `The Queue <https://mpd.readthedocs.io/en/latest/protocol.html#the-queue>`_ + +* **add** -> None +* **addid** -> str +* **clear** -> None +* **delete** -> None +* **deleteid** -> None +* **move** -> None +* **moveid** -> None +* **playlist** -> list +* **playlistfind** -> list[dict] +* **playlistid** -> list[dict] +* **playlistinfo** -> list[dict] +* **playlistsearch** -> list[dict] +* **plchanges** -> list[dict] +* **plchangesposid** -> list[dict] +* **prio** -> None +* **prioid** -> None +* **rangeid** -> None +* **shuffle** -> None +* **swap** -> None +* **swapid** -> None +* **addtagid** -> None +* **cleartagid** -> None + +Stored playlists +^^^^^^^^^^^^^^^^ + +Protocol documentation: `Stored playlists <https://mpd.readthedocs.io/en/latest/protocol.html#stored-playlists>`_ + +* **listplaylist** -> list +* **listplaylistinfo** -> list[dict] +* **listplaylists** -> dict +* **load** -> None +* **playlistadd** -> None +* **playlistclear** -> None +* **playlistdelete** -> None +* **playlistmove** -> None +* **rename** -> None +* **rm** -> None +* **save** -> None + +The music database +^^^^^^^^^^^^^^^^^^ + +Protocol documentation: `The music database <https://mpd.readthedocs.io/en/latest/protocol.html#the-music-database>`_ + +* **albumart** -> dict +* **count** -> dict +* **getfingerprint** -> dict +* **find** -> list[dict] +* **findadd** -> None +* **list** -> list +* **listall** -> list[dict] +* **listallinfo** -> list[dict] +* **listfiles** -> list[dict] +* **lsinfo** -> list[dict] +* **readcomments** -> dict +* **readpicture** -> dict +* **search** -> list[dict] +* **searchadd** -> None +* **searchaddpl** -> None +* **update** -> str +* **rescan** -> str + +Mounts and neighbors +^^^^^^^^^^^^^^^^^^^^ + +Protocol documentation: `Mounts and neighbors <https://mpd.readthedocs.io/en/latest/protocol.html#mounts-and-neighbors>`_ + +* **mount** -> None +* **unmount** -> None +* **listmounts** -> list[dict] +* **listneighbors** -> list[dict] + +Stickers +^^^^^^^^ + +Protocol documentation: `Stickers <https://mpd.readthedocs.io/en/latest/protocol.html#stickers>`_ + +* **sticker get** -> str +* **sticker set** -> None +* **sticker delete** -> None +* **sticker list** -> list +* **sticker find** -> list[dict] + +Connection settings +^^^^^^^^^^^^^^^^^^^ + +Protocol documentation: `Connection settings <https://mpd.readthedocs.io/en/latest/protocol.html#connection-settings>`_ + +* **password** -> None +* **ping** -> None +* **binarylimit** -> None +* **tagtypes** -> list +* **tagtypes disable** -> None +* **tagtypes enable** -> None +* **tagtypes clear** -> None +* **tagtypes all** -> None + +Partition Commands +^^^^^^^^^^^^^^^^^^ + +Protocol documentation: `Partition Commands <https://mpd.readthedocs.io/en/latest/protocol.html#partition-commands>`_ + +* **partition** -> None +* **listpartitions** -> list +* **newpartition** -> None +* **delpartition** -> None +* **moveoutput** -> None + +Audio output devices +^^^^^^^^^^^^^^^^^^^^ + +Protocol documentation: `Audio output devices <https://mpd.readthedocs.io/en/latest/protocol.html#audio-output-devices>`_ + +* **disableoutput** -> None +* **enableoutput** -> None +* **toggleoutput** -> None +* **outputs** -> list[dict] +* **outputset** -> None + +Reflection +^^^^^^^^^^ + +Protocol documentation: `Reflection <https://mpd.readthedocs.io/en/latest/protocol.html#reflection>`_ + +* **config** -> dict +* **commands** -> list +* **notcommands** -> list +* **urlhandlers** -> list +* **decoders** -> list[dict] + +Client to Client +^^^^^^^^^^^^^^^^ + +Protocol documentation: `Client to Client <https://mpd.readthedocs.io/en/latest/protocol.html#client-to-client>`_ + +* **subscribe** -> None +* **unsubscribe** -> None +* **channels** -> list +* **readmessages** -> list[dict] +* **sendmessage** -> None diff --git a/doc/source/commands.rst b/doc/source/commands.rst index 95ae748..c20e11f 100644 --- a/doc/source/commands.rst +++ b/doc/source/commands.rst @@ -1,4 +1,4 @@ -.. SPDX-FileCopyrightText: 2018-2023 kaliko <kaliko@azylum.org> +.. SPDX-FileCopyrightText: 2018-2024 kaliko <kaliko@azylum.org> .. SPDX-License-Identifier: LGPL-3.0-or-later .. _commands: @@ -13,6 +13,4 @@ Get current available commands: import musicpd print(' '.join([cmd for cmd in musicpd.MPDClient()._commands.keys()])) -List, last updated for v0.8.0: - -.. literalinclude:: commands.txt +.. include:: _commands.rst diff --git a/doc/source/index.rst b/doc/source/index.rst index d16644b..276f92c 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -68,8 +68,8 @@ Contents self use.rst doc.rst - commands.rst examples.rst + commands.rst contribute.rst diff --git a/doc/source/use.rst b/doc/source/use.rst index 88728ef..ff15ff2 100644 --- a/doc/source/use.rst +++ b/doc/source/use.rst @@ -38,7 +38,9 @@ on object string representation. :py:class:`musicpd.MPDClient` methods returns different kinds of objects depending on the command. Could be :py:obj:`None`, a single object as a -:py:obj:`str` or a :py:obj:`dict`, a list of :py:obj:`dict`. +:py:obj:`str`, a :py:obj:`list`, a :py:obj:`dict` or a list of :py:obj:`dict`. +See :ref:`commands exposed in the module<commands>` for more about returned +type. Then :py:class:`musicpd.MPDClient` **methods signatures** are not hard coded within this module since the protocol is handled on the server side. Please diff --git a/musicpd.py b/musicpd.py index e24b51d..96f8c86 100644 --- a/musicpd.py +++ b/musicpd.py @@ -19,7 +19,7 @@ ERROR_PREFIX = "ACK " SUCCESS = "OK" NEXT = "list_OK" #: Module version -VERSION = '0.9.0' +VERSION = '0.9.1' #: Seconds before a connection attempt times out #: (overriden by :envvar:`MPD_TIMEOUT` env. var.) CONNECTION_TIMEOUT = 30 @@ -185,14 +185,14 @@ class MPDClient: .. note:: This is the version of the protocol spoken, not the real version of the daemon.""" self._reset() self._commands = { - # Status Commands + # Querying MPD’s status # querying-mpd-s-status "clearerror": self._fetch_nothing, "currentsong": self._fetch_object, "idle": self._fetch_list, #"noidle": None, "status": self._fetch_object, "stats": self._fetch_object, - # Playback Option Commands + # Playback Option # playback-options "consume": self._fetch_nothing, "crossfade": self._fetch_nothing, "mixrampdb": self._fetch_nothing, @@ -205,7 +205,7 @@ class MPDClient: "replay_gain_mode": self._fetch_nothing, "replay_gain_status": self._fetch_item, "volume": self._fetch_nothing, - # Playback Control Commands + # Controlling playback # controlling-playback "next": self._fetch_nothing, "pause": self._fetch_nothing, "play": self._fetch_nothing, @@ -215,7 +215,7 @@ class MPDClient: "seekid": self._fetch_nothing, "seekcur": self._fetch_nothing, "stop": self._fetch_nothing, - # Queue Commands + # The Queue # the-queue "add": self._fetch_nothing, "addid": self._fetch_item, "clear": self._fetch_nothing, @@ -238,7 +238,7 @@ class MPDClient: "swapid": self._fetch_nothing, "addtagid": self._fetch_nothing, "cleartagid": self._fetch_nothing, - # Stored Playlist Commands + # Stored playlists # stored-playlists "listplaylist": self._fetch_list, "listplaylistinfo": self._fetch_songs, "listplaylists": self._fetch_playlists, @@ -250,7 +250,7 @@ class MPDClient: "rename": self._fetch_nothing, "rm": self._fetch_nothing, "save": self._fetch_nothing, - # Database Commands + # The music database # the-music-database "albumart": self._fetch_composite, "count": self._fetch_object, "getfingerprint": self._fetch_object, @@ -268,18 +268,18 @@ class MPDClient: "searchaddpl": self._fetch_nothing, "update": self._fetch_item, "rescan": self._fetch_item, - # Mounts and neighbors + # Mounts and neighbors # mounts-and-neighbors "mount": self._fetch_nothing, "unmount": self._fetch_nothing, "listmounts": self._fetch_mounts, "listneighbors": self._fetch_neighbors, - # Sticker Commands + # Stickers # stickers "sticker get": self._fetch_item, "sticker set": self._fetch_nothing, "sticker delete": self._fetch_nothing, "sticker list": self._fetch_list, "sticker find": self._fetch_songs, - # Connection Commands + # Connection settings # connection-settings "close": None, "kill": None, "password": self._fetch_nothing, @@ -290,25 +290,25 @@ class MPDClient: "tagtypes enable": self._fetch_nothing, "tagtypes clear": self._fetch_nothing, "tagtypes all": self._fetch_nothing, - # Partition Commands + # Partition Commands # partition-commands "partition": self._fetch_nothing, "listpartitions": self._fetch_list, "newpartition": self._fetch_nothing, "delpartition": self._fetch_nothing, "moveoutput": self._fetch_nothing, - # Audio Output Commands + # Audio output devices # audio-output-devices "disableoutput": self._fetch_nothing, "enableoutput": self._fetch_nothing, "toggleoutput": self._fetch_nothing, "outputs": self._fetch_outputs, "outputset": self._fetch_nothing, - # Reflection Commands + # Reflection # reflection "config": self._fetch_object, "commands": self._fetch_list, "notcommands": self._fetch_list, "urlhandlers": self._fetch_list, "decoders": self._fetch_plugins, - # Client to Client + # Client to Client # client-to-client "subscribe": self._fetch_nothing, "unsubscribe": self._fetch_nothing, "channels": self._fetch_list, -- 2.39.5