From: Kaliko Jack Date: Wed, 14 Nov 2018 18:22:03 +0000 (+0100) Subject: Add sphinx doc (closes #3) X-Git-Tag: v0.4.3~7 X-Git-Url: http://git.kaliko.me/?p=python-musicpd.git;a=commitdiff_plain;h=966e3a848b9d545530cc7c7a78c5185c69183b22 Add sphinx doc (closes #3) --- diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..54134f0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +# python +__pycache__ +*.pyc. +/*.egg-info +# project +/build/ +/dist/ +/doc/build/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ff576c0..8ed0998 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -44,3 +44,14 @@ tag_release: name: "$CI_PROJECT_NAME-$CI_COMMIT_TAG" only: - tags + +pages: + stage: build + script: + - pip install sphinx sphinx_rtd_theme + - sphinx-build -d ./build/doctrees doc/source -b html ./public -D html_theme=sphinx_rtd_theme + artifacts: + paths: + - public + only: + - master diff --git a/README.rst b/README.rst index 95e6ff5..45be050 100644 --- a/README.rst +++ b/README.rst @@ -1,118 +1,13 @@ -============== -python-musicpd -============== +Python MusicPlayerDaemon client module +*************************************** -Getting python-musicpd ----------------------- +An MPD (Music Player Daemon) client library written in pure Python. -The latest release of python-musicpd can be found at -http://pypi.python.org/pypi/python-musicpd. +---- - -Getting the latest source code ------------------------------- - -If you would instead like to use the latest source code, you can grab a copy -of the development version from git by running the command: - - git clone git://git.kaliko.me/python-musicpd.git - - -Installing from source ----------------------- - -To install python-musicpd from source, simply run the command:: - - python3 setup.py install - -You can use the `--help` switch to `setup.py` for a complete list of commands -and their options. See the `Installing Python Modules`_ document for more details. - - -Using the client library ------------------------- - -The client library can be used as follows:: - - client = musicpd.MPDClient() # create client object - client.connect() # use MPD_HOST/MPD_PORT if set else - # test ${XDG_RUNTIME_DIR}/mpd/socket for existence - # fallback to localhost:6600 - # `connect` support host/port argument as well - print client.mpd_version # print the mpd version - print client.cmd('one', 2) # print result of the command "cmd one 2" - client.close() # send the close command - client.disconnect() # disconnect from the server - -A list of supported commands, their arguments (as MPD currently understands -them), and the functions used to parse their responses can be found in -`doc/commands.txt`. See the `MPD protocol documentation`_ for more -details. - -Command lists are also supported using `command_list_ok_begin()` and -`command_list_end()` :: - - client.command_list_ok_begin() # start a command list - client.update() # insert the update command into the list - client.status() # insert the status command into the list - results = client.command_list_end() # results will be a list with the results - -Provide a 2-tuple as argument for command supporting ranges (cf. `MPD protocol documentation`_ for more details). -Possible ranges are: "START:END", "START:" and ":" :: - - # An intelligent clear - # clears played track in the queue, currentsong included - pos = client.currentsong().get('pos', 0) - # the 2-tuple range object accepts str, no need to convert to int - client.delete((0, pos)) - # missing end interpreted as highest value possible, pay attention still need a tuple. - client.delete((pos,)) # purge queue from current to the end - -A notable case is the `rangeid` command allowing an empty range specified -as a single colon as argument (i.e. sending just ":"):: - - # sending "rangeid :" to clear the range, play everything - client.rangeid(()) # send an empty tuple - -Empty start in range (i.e. ":END") are not possible and will raise a CommandError. - - -Commands may also return iterators instead of lists if `iterate` is set to -`True`:: - - client.iterate = True - for song in client.playlistinfo(): - print song['file'] - -Each command have a *send\_* and a *fetch\_* variant, which allows to -send a MPD command and then fetch the result later. -This is useful for the idle command:: - - >>> client.send_idle() - # do something else or use function like select() - # http://docs.python.org/howto/sockets.html#non-blocking-sockets - # ex. select([client], [], []) - >>> events = client.fetch_idle() - - # more complex use for example, with glib/gobject: - >>> def callback(source, condition): - >>> changes = client.fetch_idle() - >>> print changes - >>> return False # removes the IO watcher - - >>> client.send_idle() - >>> gobject.io_add_watch(client, gobject.IO_IN, callback) - >>> gobject.MainLoop().run() - -Contacting authors ------------------- - -You can contact the original author by emailing J. Alexander Treuman -. He can also be found idling in #mpd on -irc.freenode.net as jat. - -The current maintainer can be found on xmpp chat room -or you can contact him by email/xmpp . - - .. _Installing Python Modules: http://docs.python.org/3/install/ - .. _MPD protocol documentation: http://www.musicpd.org/doc/protocol/ +:Documentation: https://kaliko.gitlab.io/python-musicpd +:MPD Protocol: https://www.musicpd.org/doc/html/protocol.html +:Code: https://gitlab.com/kaliko/python-musicpd +:Dependencies: None +:Compatibility: Python 3.4+ +:Licence: GNU LGPLv3 diff --git a/doc/source/conf.py b/doc/source/conf.py new file mode 100644 index 0000000..9038c86 --- /dev/null +++ b/doc/source/conf.py @@ -0,0 +1,443 @@ +# coding: utf-8 +# +# Python ListenBrainz Module documentation build configuration file, created by +# sphinx-quickstart on Mon Mar 12 14:37:32 2018. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +# 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. +# +import os +import sys +# sys.path.insert(0, os.path.abspath('.')) +sys.path.insert(0, os.path.abspath('../../')) +from musicpd import VERSION +__author__ = 'kaliko' +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# 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.intersphinx', + #'sphinx.ext.coverage', + 'sphinx.ext.viewcode', + 'sphinx.ext.todo', +] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The encoding of source files. +# +# source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'Python ListenBrainz Module' +copyright = u'2018, {}'.format(__author__) +author = __author__ + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = VERSION +# The full version, including alpha/beta/rc tags. +release = VERSION + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +# +# today = '' +# +# Else, today_fmt is used as the format for a strftime call. +# +# today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This patterns also effect to html_static_path and html_extra_path +exclude_patterns = [] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +# +# default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +# +# add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +# +# add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +# +# show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +# modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +# keep_warnings = False + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = 'alabaster' +html_theme = 'classic' +#html_theme = "sphinx_rtd_theme" +#html_theme = 'bootstrap' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +# +# html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +# html_theme_path = [] +#html_theme_path = ['/usr/lib/python3/dist-packages/sphinx_bootstrap_theme'] + +# The name for this set of Sphinx documents. +# " v documentation" by default. +# +# html_title = u'Python ListenBrainz Module v0.0.1' + +# A shorter title for the navigation bar. Default is the same as html_title. +# +# html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +# +# html_logo = None + +# The name of an image file (relative to this directory) to use as a favicon of +# the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +# +# html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +#chtml_static_path = ['_static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +# +# html_extra_path = [] + +# If not None, a 'Last updated on:' timestamp is inserted at every page +# bottom, using the given strftime format. +# The empty string is equivalent to '%b %d, %Y'. +# +# html_last_updated_fmt = None + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +# +# html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +# +# html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +# +# html_additional_pages = {} + +# If false, no module index is generated. +# +# html_domain_indices = True + +# If false, no index is generated. +# +# html_use_index = True + +# If true, the index is split into individual pages for each letter. +# +# html_split_index = False + +# If true, links to the reST sources are added to the pages. +# +# html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +# +# html_show_sphinx = True +html_show_sphinx = False + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +# +# html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +# +# html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +# html_file_suffix = None + +# Language to be used for generating the HTML full-text search index. +# Sphinx supports the following languages: +# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' +# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh' +# +# html_search_language = 'en' + +# A dictionary with options for the search language support, empty by default. +# 'ja' uses this config value. +# 'zh' user can custom change `jieba` dictionary path. +# +# html_search_options = {'type': 'default'} + +# The name of a javascript file (relative to the configuration directory) that +# implements a search results scorer. If empty, the default will be used. +# +# html_search_scorer = 'scorer.js' + +# Output file base name for HTML help builder. +htmlhelp_basename = 'PythonListenBrainzModuledoc' + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + # + # 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt'). + # + # 'pointsize': '10pt', + + # Additional stuff for the LaTeX preamble. + # + # 'preamble': '', + + # Latex figure (float) alignment + # + # 'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'PythonListenBrainzModule.tex', u'Python ListenBrainz Module Documentation', + u'kaliko', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +# +# latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +# +# latex_use_parts = False + +# If true, show page references after internal links. +# +# latex_show_pagerefs = False + +# If true, show URL addresses after external links. +# +# latex_show_urls = False + +# Documents to append as an appendix to all manuals. +# +# latex_appendices = [] + +# It false, will not define \strong, \code, itleref, \crossref ... but only +# \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added +# packages. +# +# latex_keep_old_macro_names = True + +# If false, no module index is generated. +# +# latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'pythonlistenbrainzmodule', u'Python ListenBrainz Module Documentation', + [author], 1) +] + +# If true, show URL addresses after external links. +# +# man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'PythonListenBrainzModule', u'Python ListenBrainz Module Documentation', + author, 'PythonListenBrainzModule', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +# +# texinfo_appendices = [] + +# If false, no module index is generated. +# +# texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +# +# texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +# +# texinfo_no_detailmenu = False + + +# -- Options for Epub output ---------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = project +epub_author = author +epub_publisher = author +epub_copyright = copyright + +# The basename for the epub file. It defaults to the project name. +# epub_basename = project + +# The HTML theme for the epub output. Since the default themes are not +# optimized for small screen space, using the same theme for HTML and epub +# output is usually not wise. This defaults to 'epub', a theme designed to save +# visual space. +# +# epub_theme = 'epub' + +# The language of the text. It defaults to the language option +# or 'en' if the language is not set. +# +# epub_language = '' + +# The scheme of the identifier. Typical schemes are ISBN or URL. +# epub_scheme = '' + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +# +# epub_identifier = '' + +# A unique identification for the text. +# +# epub_uid = '' + +# A tuple containing the cover image and cover page html template filenames. +# +# epub_cover = () + +# A sequence of (type, uri, title) tuples for the guide element of content.opf. +# +# epub_guide = () + +# HTML files that should be inserted before the pages created by sphinx. +# The format is a list of tuples containing the path and title. +# +# epub_pre_files = [] + +# HTML files that should be inserted after the pages created by sphinx. +# The format is a list of tuples containing the path and title. +# +# epub_post_files = [] + +# A list of files that should not be packed into the epub file. +epub_exclude_files = ['search.html'] + +# The depth of the table of contents in toc.ncx. +# +# epub_tocdepth = 3 + +# Allow duplicate toc entries. +# +# epub_tocdup = True + +# Choose between 'default' and 'includehidden'. +# +# epub_tocscope = 'default' + +# Fix unsupported image types using the Pillow. +# +# epub_fix_images = False + +# Scale large images. +# +# epub_max_image_width = 0 + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +# +# epub_show_urls = 'inline' + +# If false, no index is generated. +# +# epub_use_index = True + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'https://docs.python.org/': None} + +# autodoc config +autodoc_member_order = 'bysource' diff --git a/doc/source/contribute.rst b/doc/source/contribute.rst new file mode 100644 index 0000000..cf87c1c --- /dev/null +++ b/doc/source/contribute.rst @@ -0,0 +1,33 @@ +Contributing +============= + +Use git, `learn if needed`_. + +Git Workflow +------------- +* ``master`` branch holds latest stable|release code +* ``dev`` branch holds current development code +* Work on a dedicated branch starting off ``dev`` +* I like fast forward merges, **please rebase on** ``dev`` **branch** +* Advertise your work (cf. Note) + +.. NOTE:: + **Git merge Workflow** |br| + I currently don't care about a specific workflow concerning changes submission. |br| + gitlab merge request, gh pull request, plain email pointing out a repo/ref. All we need is a public git repo and a ref to fetch from as long you rebased on ``dev`` branch. + +Coding +------- + +* follow pep8 +* write unittest +* actually test your code (unit and functional testing) + + +.. _`learn if needed`: https://git-scm.com/book/ + +.. |br| raw:: html + +
+ +.. vim: spell spelllang=en diff --git a/doc/source/doc.rst b/doc/source/doc.rst new file mode 100644 index 0000000..f0205c5 --- /dev/null +++ b/doc/source/doc.rst @@ -0,0 +1,10 @@ +MPD client class +================= + +.. autoclass:: musicpd.MPDClient + :members: + :noindex: + + + +.. vim: spell spelllang=en diff --git a/doc/source/index.rst b/doc/source/index.rst new file mode 100644 index 0000000..c55d08d --- /dev/null +++ b/doc/source/index.rst @@ -0,0 +1,55 @@ +.. include:: ../../README.rst + +Installation +============= + +**Latest stable release** from `PyPi `_: + +.. code:: bash + + pip install python-musicpd + +**Latest development version** using pip + git: + +.. code:: bash + + pip install git+https://gitlab.com/kaliko/python-musicpd.git + + + +Build documentation +-------------------- + +.. code:: bash + + # Get the source + git clone https://gitlab.com/kaliko/python-musicpd.git && cd python-musicpd + # Installs sphinx if needed + python3 -m venv venv && . ./venv/bin/activate + pip install sphinx + # And build + python3 setup.py build_sphinx + # Or call sphinx + sphinx-build -d ./doc/build/doctrees doc/source -b html ./doc/build/html + + +Contents +========= + +.. toctree:: + :maxdepth: 2 + + use.rst + doc.rst + contribute.rst + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + + +.. vim: spell spelllang=en diff --git a/doc/source/use.rst b/doc/source/use.rst new file mode 100644 index 0000000..fdc1317 --- /dev/null +++ b/doc/source/use.rst @@ -0,0 +1,77 @@ +Using the client library +========================= + +The client library can be used as follows:: + + client = musicpd.MPDClient() # create client object + client.connect() # use MPD_HOST/MPD_PORT if set else + # test ${XDG_RUNTIME_DIR}/mpd/socket for existence + # fallback to localhost:6600 + # connect support host/port argument as well + print client.mpd_version # print the mpd version + print client.cmd('one', 2) # print result of the command "cmd one 2" + client.close() # send the close command + client.disconnect() # disconnect from the server + +A list of supported commands, their arguments (as MPD currently understands +them), and the functions used to parse their responses can be found in +`doc/commands.txt`. See the `MPD protocol documentation`_ for more +details. + +Command lists are also supported using `command_list_ok_begin()` and +`command_list_end()` :: + + client.command_list_ok_begin() # start a command list + client.update() # insert the update command into the list + client.status() # insert the status command into the list + results = client.command_list_end() # results will be a list with the results + +Provide a 2-tuple as argument for command supporting ranges (cf. `MPD protocol documentation`_ for more details). +Possible ranges are: "START:END", "START:" and ":" :: + + # An intelligent clear + # clears played track in the queue, currentsong included + pos = client.currentsong().get('pos', 0) + # the 2-tuple range object accepts str, no need to convert to int + client.delete((0, pos)) + # missing end interpreted as highest value possible, pay attention still need a tuple. + client.delete((pos,)) # purge queue from current to the end + +A notable case is the `rangeid` command allowing an empty range specified +as a single colon as argument (i.e. sending just ":"):: + + # sending "rangeid :" to clear the range, play everything + client.rangeid(()) # send an empty tuple + +Empty start in range (i.e. ":END") are not possible and will raise a CommandError. + + +Commands may also return iterators instead of lists if `iterate` is set to +`True`:: + + client.iterate = True + for song in client.playlistinfo(): + print song['file'] + +Each command have a *send\_* and a *fetch\_* variant, which allows to +send a MPD command and then fetch the result later. +This is useful for the idle command:: + + >>> client.send_idle() + # do something else or use function like select() + # http://docs.python.org/howto/sockets.html#non-blocking-sockets + # ex. select([client], [], []) + >>> events = client.fetch_idle() + + # more complex use for example, with glib/gobject: + >>> def callback(source, condition): + >>> changes = client.fetch_idle() + >>> print changes + >>> return False # removes the IO watcher + + >>> client.send_idle() + >>> gobject.io_add_watch(client, gobject.IO_IN, callback) + >>> gobject.MainLoop().run() + + +.. _MPD protocol documentation: http://www.musicpd.org/doc/protocol/ diff --git a/musicpd.py b/musicpd.py index 10b15cb..1a7fd97 100644 --- a/musicpd.py +++ b/musicpd.py @@ -104,6 +104,11 @@ class _NotConnected: raise ConnectionError("Not connected") class MPDClient: + """MPDClient instance will look for ``MPD_HOST``/``MPD_PORT`` environment + variables and set instance attribute ``host``, ``port`` and ``password`` + accordingly. + """ + def __init__(self): self.iterate = False self._reset() @@ -523,6 +528,24 @@ class MPDClient: return self._fetch_list() def connect(self, host=None, port=None): + """Connects the MPD server + + :param str host: hostname, IP or FQDN (defaults to `localhost` or socket, see below for details) + :param str port: port number (defaults to 6600) + + The connect method honors MPD_HOST/MPD_PORT environment variables. + + .. note:: Default host/port + + If host evaluate to :py:obj:`False` + * if ``MPD_HOST`` env. var. is set, use it for host + * else looks for a existing file in ``${XDG_RUNTIME_DIR:-/run/}/mpd/socket`` + * finally set host to ``localhost`` + + If port evaluate to :py:obj:`False` + * if ``MPD_PORT`` env. var. is set, use it for port + * else use ``6600`` + """ if not host: host = self.host if not port: @@ -542,6 +565,10 @@ class MPDClient: raise def disconnect(self): + """Closes the MPD connection. + The client closes the actual socket and not using the + 'close' request from MPD protocol as suggested in documentation. + """ if hasattr(self._rfile, 'close'): self._rfile.close() if hasattr(self._wfile, 'close'): diff --git a/setup.py b/setup.py index afcbf23..9686eb0 100755 --- a/setup.py +++ b/setup.py @@ -1,4 +1,5 @@ #! /usr/bin/env python3 +# coding: utf-8 from setuptools import setup @@ -22,24 +23,6 @@ CLASSIFIERS = [ "Topic :: Software Development :: Libraries :: Python Modules", ] -LICENSE = """\ -Copyright (C) 2008-2010 J. Alexander Treuman -Copyright (C) 2012-2018 Kaliko Jack - -python-musicpd is free software: you can redistribute it and/or modify -it under the terms of the GNU Lesser General Public License as published by -the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. - -python-musicpd is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public License -along with python-musicpd. If not, see .\ -""" - setup( name='python-musicpd', @@ -52,7 +35,7 @@ setup( download_url='http://pypi.python.org/pypi/python-musicpd/', py_modules=['musicpd'], classifiers=CLASSIFIERS, - license=LICENSE, + license='LGPLv3+', keywords=['mpd', 'Music Player Daemon'], platforms=['Independant'], test_suite='test.py',