././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1625703636.7250621 Mopidy-3.2.0/0000755000175100001710000000000000000000000012315 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1625703636.6970599 Mopidy-3.2.0/.github/0000755000175100001710000000000000000000000013655 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1625703636.7010603 Mopidy-3.2.0/.github/ISSUE_TEMPLATE/0000755000175100001710000000000000000000000016040 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/.github/ISSUE_TEMPLATE/bug.md0000644000175100001710000000221100000000000017133 0ustar00runnerdocker--- name: Bug report about: Create a bug report to help us improve. title: '' labels: '' assignees: '' --- If you are not sure about anything below then please post on our [forum](https://discourse.mopidy.com/) first. **Describe the bug** A clear and concise description of what the bug is. Is this specific to a particular Backend (e.g. Mopidy-Spotify), Frontend (e.g. Mopidy-MPD) or client? **How to reproduce** Steps to reproduce the behaviour including any error messages that occur. **Expected behaviour** A clear and concise description of what you expected to happen. **Environment** Please complete the following information: - Operating system (e.g. Debian Buster, Ubuntu 20.04) - [Running Mopidy](https://docs.mopidy.com/en/latest/running/) as a service or in the terminal? - Your config (output of `sudo mopidyctl config`) - Software versions (output of `sudo mopidyctl deps`) - Any specific hardware (e.g. an exotic USB soundcard) **Additional context** Add any other context about the problem here. If appropriate, upload an [appropriately verbose](https://docs.mopidy.com/en/latest/troubleshooting/#debug-logging) log file showing the bug. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/.github/ISSUE_TEMPLATE/config.yml0000644000175100001710000000024300000000000020027 0ustar00runnerdockerblank_issues_enabled: true contact_links: - name: Mopidy Discourse forum url: https://discourse.mopidy.com/ about: Please ask and answer questions here. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/.github/ISSUE_TEMPLATE/extension.md0000644000175100001710000000117600000000000020403 0ustar00runnerdocker--- name: Extension request about: Share your idea for a new Mopidy extension. title: '' labels: C-extension-request assignees: '' --- Please explain your idea and provide any information on how the extension might be implemented. See [here](https://discourse.mopidy.com/t/supporting-new-streaming-services-and-other-music-sources/22) for more information. Note: these issues are closed as they cannot be fixed in Mopidy itself. However, they will be added to our [Extension wishlist](https://github.com/mopidy/mopidy/issues?utf8=%E2%9C%93&q=label%3AC-extension-request+) label for potential authors/collaborators to find and discuss. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/.github/ISSUE_TEMPLATE/feature.md0000644000175100001710000000043700000000000020021 0ustar00runnerdocker--- name: Feature request about: Suggest an idea for this project. title: '' labels: '' assignees: '' --- Mopidy's GitHub Issues are reserved for well-defined feature requests. If this is a more general idea or question, please post on the [forum](https://discourse.mopidy.com) first. ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1625703636.7010603 Mopidy-3.2.0/.github/workflows/0000755000175100001710000000000000000000000015712 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/.github/workflows/ci.yml0000644000175100001710000000326600000000000017037 0ustar00runnerdockername: CI on: [push, pull_request] jobs: main: strategy: fail-fast: false matrix: include: - name: "Test: Python 3.7" python: "3.7" tox: py37 - name: "Test: Python 3.8" python: "3.8" tox: py38 - name: "Test: Python 3.9" python: "3.9" tox: py39 coverage: true - name: "Lint: check-manifest" python: "3.9" tox: check-manifest - name: "Lint: flake8" python: "3.9" tox: flake8 - name: "Lint: mypy" python: "3.9" tox: mypy - name: "Docs" python: "3.9" tox: docs name: ${{ matrix.name }} runs-on: ubuntu-20.04 container: ghcr.io/mopidy/ci:latest steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 with: python-version: ${{ matrix.python }} - name: Fix home dir permissions to enable pip caching run: chown -R root /github/home - name: Cache pip uses: actions/cache@v2 with: path: ~/.cache/pip key: ${{ runner.os }}-${{ matrix.python }}-${{ matrix.tox }}-pip-${{ hashFiles('setup.cfg') }}-${{ hashFiles('tox.ini') }} restore-keys: | ${{ runner.os }}-${{ matrix.python }}-${{ matrix.tox }}-pip- - run: python -m pip install pygobject tox - run: python -m tox -e ${{ matrix.tox }} if: ${{ ! matrix.coverage }} - run: python -m tox -e ${{ matrix.tox }} -- --cov-report=xml if: ${{ matrix.coverage }} - uses: codecov/codecov-action@v1 if: ${{ matrix.coverage }} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/.github/workflows/codeql-analysis.yml0000644000175100001710000000067500000000000021535 0ustar00runnerdockername: "CodeQL" on: push: branches: [ develop, master ] pull_request: branches: [ develop, master ] schedule: - cron: '32 4 * * 4' jobs: analyze: name: Analyze Python runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - uses: github/codeql-action/init@v1 with: languages: "python" - uses: github/codeql-action/autobuild@v1 - uses: github/codeql-action/analyze@v1 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/.github/workflows/release.yml0000644000175100001710000000076500000000000020065 0ustar00runnerdockername: Release on: release: types: [published] jobs: release: runs-on: ubuntu-20.04 steps: - uses: actions/checkout@v2 - uses: actions/setup-python@v2 with: python-version: "3.9" - name: "Install dependencies" run: python3 -m pip install build - name: "Build package" run: python3 -m build - uses: pypa/gh-action-pypi-publish@v1.4.1 with: user: __token__ password: ${{ secrets.PYPI_TOKEN }} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/.github/workflows/ubuntu-devel.yml0000644000175100001710000000132400000000000021054 0ustar00runnerdockername: "Ubuntu devel" on: schedule: # Every Friday at 18:20 UTC, so we can fix the issue over the weekend - cron: "20 18 * * 5" workflow_dispatch: jobs: main: name: "Test: Python 3.9" runs-on: ubuntu-20.04 # The container should be automatically updated from time to time. container: ubuntu:devel steps: - uses: actions/checkout@v2 - name: Install dependencies run: | apt-get update DEBIAN_FRONTEND=noninteractive apt-get install -y \ gstreamer1.0-plugins-bad \ gstreamer1.0-plugins-good \ gstreamer1.0-plugins-ugly \ python3-gst-1.0 \ python3 \ tox - run: tox -e py39 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/.mailmap0000644000175100001710000000477100000000000013747 0ustar00runnerdockerThomas Adamcik Thomas Adamcik Thomas Adamcik Thomas Adacmik Kristian Klette Johannes Knutsen Johannes Knutsen John Bäckstrand David Caruso Adam Rigg Ernst Bammer Alli Witheford Alexandre Petitjean Alexandre Petitjean Javier Domingo Cansino Lasse Bigum Nick Steel Nick Steel Nick Steel Nick Steel Janez Troha Janez Troha Luke Giuliani Colin Montgomerie Nathan Harper Ignasi Fosch Christopher Schirner Laura Barber John Cass Ronald Zielaznicki Kyle Heyne Tom Roth Eric Jahn Loïck Bonniot Jens Lütjen Jens Lütjen Daniel T Ismael Asensio Brendan Jones Marvin Preuss Bernhard Gehl Caysho Nick Aquina Jarryd Tilbrook Matthieu Melquiond Geoffroy Youri Berret Hugo van Kemenade Tobias Girstmair Jonathan Jefferies Matthew H. Flamm ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/.readthedocs.yml0000644000175100001710000000031400000000000015401 0ustar00runnerdockerversion: 2 python: version: 3.7 install: - method: pip path: . extra_requirements: - docs sphinx: builder: htmldir configuration: docs/conf.py formats: - pdf - epub ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/AUTHORS0000644000175100001710000001221000000000000013361 0ustar00runnerdocker- Stein Magnus Jodal - Johannes Knutsen - Thomas Adamcik - Kristian Klette - Martins Grunskis - Henrik Olsson - Antoine Pierlot-Garcin - John Bäckstrand - Fred Hatfull - Erling Børresen - David Caruso - Christian Johansen - Matt Bray - Trygve Aaberge - Wouter van Wijk - Jeremy B. Merrill - Adam Rigg - Ernst Bammer - Nick Steel - Zan Dobersek - Thomas Refis - Janez Troha - Tobias Sauerwein - Alli Witheford - Alexandre Petitjean - Terje Larsen - Javier Domingo Cansino - Pavol Babincak - Javier Domingo - Lasse Bigum - David Eisner - Pål Ruud - Thomas Kemmer - Paul Connolley - Luke Giuliani - Colin Montgomerie - Simon de Bakker - Arnaud Barisain-Monrose - Nathan Harper - Pierpaolo Frasa - Thomas Scholtes - Sam Willcocks - Ignasi Fosch - Arjun Naik - Christopher Schirner - Dmitry Sandalov - Lukas Vogel - Thomas Amland - Deni Bertovic - Ali Ukani - Dirk Groenen - John Cass - Laura Barber - Jakab Kristóf - Ronald Zielaznicki - Wojciech Wnętrzak - Camilo Nova - Dražen Lučanin - Naglis Jonaitis - Kyle Heyne - Tom Roth - Mark Greenwood - Stein Karlsen - Dejan Prokić - Eric Jahn - Mikhail Golubev - Danilo Bargen - Bjørnar Snoksrud - Giorgos Logiotatidis - Ben Evans - vrs01 - Cadel Watson - Loïck Bonniot - Gustaf Hallberg - kozec - Jelle van der Waa - Alex Malone - Daniel Hahler - Bryan Bennett - Jens Lütjen - Lina He - Daniel T - Lars Kruse - Benjamin Chrétien - SeppSTA - Ismael Asensio - Tom Parker - Nantas Nardelli - Naglis Jonaitis - Alexander Jaworowski - Don Armstrong - Nadav Tau - Aleksandar Benic - Tom Swirly - Piotr Dobrowolski - Tomas Susanka - James Barnsley - Caysho - Brendan Jones - Marvin Preuss - Bernhard Gehl - CL123123 - Piotr Dobrowolski - Nick Aquina - Marcus Götling - Dominique Tardif - Alexey Murz Korepov - Jarryd Tilbrook - Dan Brough - Jonathan Jefferies - Matthieu Melquiond - Damien Cassou - Leonid Bogdanov - Geoffroy Youri Berret - Dan Stowell - Gildas Le Nadan - Zvonimir Fras - Simon - Vivien Henry - Hugo van Kemenade - Tobias Girstmair - Jakub Fijałkowski - Jonathan Jefferies - Prajjwal Nijhara - Asmi Jafar <47150162+asmijafar20@users.noreply.github.com> - Saloni Gupta <60188408+salonigupta1@users.noreply.github.com> - Parth Verma - Flamm, Matthew H - Matthew Gamble - very-amused ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/AUTHORS.update0000755000175100001710000000027100000000000014651 0ustar00runnerdocker#!/bin/bash set -euo pipefail IFS=$'\n\t' # Keep authors in the order of appearance and use awk to filter out dupes git log --format='- %aN <%aE>' --reverse | awk '!x[$0]++' > AUTHORS ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/LICENSE0000644000175100001710000002613600000000000013332 0ustar00runnerdocker Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/MANIFEST.in0000644000175100001710000000073200000000000014055 0ustar00runnerdockerinclude *.py include *.rst include *.toml include .mailmap include .readthedocs.yml include AUTHORS include AUTHORS.update include LICENSE include MANIFEST.in include mopidy/py.typed include pyproject.toml include tox.ini recursive-include .github * recursive-include docs * prune docs/_build prune docs/.doctrees recursive-include extra * recursive-include mopidy *.conf recursive-include mopidy/http/data * recursive-include tests *.py recursive-include tests/data * ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1625703636.7050605 Mopidy-3.2.0/Mopidy.egg-info/0000755000175100001710000000000000000000000015250 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703636.0 Mopidy-3.2.0/Mopidy.egg-info/PKG-INFO0000644000175100001710000001114200000000000016344 0ustar00runnerdockerMetadata-Version: 2.1 Name: Mopidy Version: 3.2.0 Summary: Mopidy is an extensible music server written in Python Home-page: https://mopidy.com/ Author: Stein Magnus Jodal Author-email: stein.magnus@jodal.no License: Apache License, Version 2.0 Project-URL: Documentation, https://docs.mopidy.com/ Project-URL: Discourse forum, https://discourse.mopidy.com/ Project-URL: Zulip chat, https://mopidy.zulipchat.com/ Project-URL: Source, https://github.com/mopidy/mopidy Project-URL: Issues, https://github.com/mopidy/mopidy/issues Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: No Input/Output (Daemon) Classifier: Intended Audience :: End Users/Desktop Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: MacOS :: MacOS X Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Topic :: Multimedia :: Sound/Audio :: Players Requires-Python: >=3.7 Provides-Extra: docs Provides-Extra: lint Provides-Extra: test Provides-Extra: dev License-File: LICENSE ****** Mopidy ****** `Mopidy`_ is an extensible music server written in Python. Mopidy plays music from local disk, Spotify, SoundCloud, Google Play Music, and more. You edit the playlist from any phone, tablet, or computer using a variety of MPD and web clients. **Stream music from the cloud** Vanilla Mopidy only plays music from files and radio streams. Through `extensions`_, Mopidy can play music from cloud services like Spotify, SoundCloud, and Google Play Music. With Mopidy's extension support, backends for new music sources can be easily added. **Mopidy is just a server** Mopidy is a Python application that runs in a terminal or in the background on Linux computers or Macs that have network connectivity and audio output. Out of the box, Mopidy is an HTTP server. If you install the `Mopidy-MPD`_ extension, it becomes an MPD server too. Many additional frontends for controlling Mopidy are available as extensions. **Pick your favorite client** You and the people around you can all connect their favorite MPD or web client to the Mopidy server to search for music and manage the playlist together. With a browser or MPD client, which is available for all popular operating systems, you can control the music from any phone, tablet, or computer. **Mopidy on Raspberry Pi** The `Raspberry Pi`_ is an popular device to run Mopidy on, either using Raspbian, Ubuntu, or Arch Linux. Pimoroni recommends Mopidy for use with their `Pirate Audio`_ audio gear for Raspberry Pi. Mopidy is also a significant building block in the `Pi Musicbox`_ integrated audio jukebox system for Raspberry Pi. **Mopidy is hackable** Mopidy's extension support and Python, JSON-RPC, and JavaScript APIs make Mopidy a perfect base for your projects. In one hack, a Raspberry Pi was embedded in an old cassette player. The buttons and volume control are wired up with GPIO on the Raspberry Pi, and is used to control playback through a custom Mopidy extension. The cassettes have NFC tags used to select playlists from Spotify. .. _Mopidy: https://mopidy.com/ .. _extensions: https://mopidy.com/ext/ .. _Mopidy-MPD: https://mopidy.com/ext/mpd/ .. _Raspberry Pi: https://www.raspberrypi.org/ .. _Pirate Audio: https://shop.pimoroni.com/collections/pirate-audio .. _Pi Musicbox: https://www.pimusicbox.com/ **Getting started** To get started with Mopidy, begin by reading the `installation docs `_. **Project resources** - `Documentation `_ - `Discourse forum `_ - `Zulip chat `_ - `Source code `_ - `Issue tracker `_ .. image:: https://img.shields.io/pypi/v/Mopidy.svg?style=flat :target: https://pypi.python.org/pypi/Mopidy/ :alt: Latest PyPI version .. image:: https://img.shields.io/github/workflow/status/mopidy/mopidy/CI :target: https://github.com/mopidy/mopidy/actions :alt: CI build status .. image:: https://img.shields.io/readthedocs/mopidy.svg :target: https://docs.mopidy.com/ :alt: Read the Docs build status .. image:: https://img.shields.io/codecov/c/github/mopidy/mopidy/develop.svg :target: https://codecov.io/gh/mopidy/mopidy :alt: Test coverage .. image:: https://img.shields.io/badge/chat-on%20zulip-brightgreen :target: https://mopidy.zulipchat.com/ :alt: Chat on Zulip ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703636.0 Mopidy-3.2.0/Mopidy.egg-info/SOURCES.txt0000644000175100001710000001540400000000000017140 0ustar00runnerdocker.mailmap .readthedocs.yml AUTHORS AUTHORS.update LICENSE MANIFEST.in README.rst pyproject.toml setup.cfg setup.py tox.ini .github/ISSUE_TEMPLATE/bug.md .github/ISSUE_TEMPLATE/config.yml .github/ISSUE_TEMPLATE/extension.md .github/ISSUE_TEMPLATE/feature.md .github/workflows/ci.yml .github/workflows/codeql-analysis.yml .github/workflows/release.yml .github/workflows/ubuntu-devel.yml Mopidy.egg-info/PKG-INFO Mopidy.egg-info/SOURCES.txt Mopidy.egg-info/dependency_links.txt Mopidy.egg-info/entry_points.txt Mopidy.egg-info/not-zip-safe Mopidy.egg-info/requires.txt Mopidy.egg-info/top_level.txt docs/Makefile docs/audiosinks.rst docs/authors.rst docs/changelog.rst docs/clients.rst docs/codestyle.rst docs/command.rst docs/conf.py docs/config.rst docs/contributing.rst docs/devenv.rst docs/extensiondev.rst docs/glossary.rst docs/icecast.rst docs/index.rst docs/releasing.rst docs/sponsors.rst docs/troubleshooting.rst docs/upnp.rst docs/versioning.rst docs/_static/mopidy.png docs/api/architecture.rst docs/api/audio.rst docs/api/backend.rst docs/api/commands.rst docs/api/config.rst docs/api/core.rst docs/api/ext.rst docs/api/frontend.rst docs/api/http-server.rst docs/api/http.rst docs/api/httpclient.rst docs/api/index.rst docs/api/js.rst docs/api/mixer.rst docs/api/models.rst docs/api/zeroconf.rst docs/ext/file.rst docs/ext/http.rst docs/ext/m3u.rst docs/ext/softwaremixer.rst docs/ext/stream.rst docs/history/changelog-0.x.rst docs/history/changelog-1.x.rst docs/history/changelog-2.x.rst docs/history/index.rst docs/installation/arch.rst docs/installation/debian.rst docs/installation/fedora.rst docs/installation/index.rst docs/installation/macos.rst docs/installation/pypi.rst docs/installation/raspberrypi.rst docs/running/index.rst docs/running/service.rst docs/running/terminal.rst extra/desktop/mopidy.desktop extra/mopidyctl/mopidyctl extra/mopidyctl/mopidyctl.8 extra/systemd/mopidy.service mopidy/__init__.py mopidy/__main__.py mopidy/backend.py mopidy/commands.py mopidy/exceptions.py mopidy/ext.py mopidy/httpclient.py mopidy/listener.py mopidy/mixer.py mopidy/py.typed mopidy/zeroconf.py mopidy/audio/__init__.py mopidy/audio/actor.py mopidy/audio/constants.py mopidy/audio/listener.py mopidy/audio/scan.py mopidy/audio/tags.py mopidy/audio/utils.py mopidy/config/__init__.py mopidy/config/default.conf mopidy/config/keyring.py mopidy/config/schemas.py mopidy/config/types.py mopidy/config/validators.py mopidy/core/__init__.py mopidy/core/actor.py mopidy/core/history.py mopidy/core/library.py mopidy/core/listener.py mopidy/core/mixer.py mopidy/core/playback.py mopidy/core/playlists.py mopidy/core/tracklist.py mopidy/file/__init__.py mopidy/file/backend.py mopidy/file/ext.conf mopidy/file/library.py mopidy/http/__init__.py mopidy/http/actor.py mopidy/http/ext.conf mopidy/http/handlers.py mopidy/http/data/clients.html mopidy/http/data/favicon.ico mopidy/http/data/mopidy.css mopidy/internal/__init__.py mopidy/internal/deprecation.py mopidy/internal/deps.py mopidy/internal/formatting.py mopidy/internal/gi.py mopidy/internal/http.py mopidy/internal/jsonrpc.py mopidy/internal/log.py mopidy/internal/models.py mopidy/internal/network.py mopidy/internal/path.py mopidy/internal/playlists.py mopidy/internal/process.py mopidy/internal/storage.py mopidy/internal/timer.py mopidy/internal/validation.py mopidy/internal/versioning.py mopidy/internal/xdg.py mopidy/m3u/__init__.py mopidy/m3u/backend.py mopidy/m3u/ext.conf mopidy/m3u/playlists.py mopidy/m3u/translator.py mopidy/models/__init__.py mopidy/models/fields.py mopidy/models/immutable.py mopidy/models/serialize.py mopidy/softwaremixer/__init__.py mopidy/softwaremixer/ext.conf mopidy/softwaremixer/mixer.py mopidy/stream/__init__.py mopidy/stream/actor.py mopidy/stream/ext.conf tests/__init__.py tests/dummy_audio.py tests/dummy_backend.py tests/dummy_mixer.py tests/test_commands.py tests/test_exceptions.py tests/test_ext.py tests/test_help.py tests/test_httpclient.py tests/test_mixer.py tests/test_version.py tests/audio/__init__.py tests/audio/test_actor.py tests/audio/test_listener.py tests/audio/test_scan.py tests/audio/test_tags.py tests/audio/test_utils.py tests/backend/__init__.py tests/backend/test_backend.py tests/backend/test_listener.py tests/config/__init__.py tests/config/test_config.py tests/config/test_defaults.py tests/config/test_schemas.py tests/config/test_types.py tests/config/test_validator.py tests/core/__init__.py tests/core/test_actor.py tests/core/test_events.py tests/core/test_history.py tests/core/test_library.py tests/core/test_listener.py tests/core/test_mixer.py tests/core/test_playback.py tests/core/test_playlists.py tests/core/test_tracklist.py tests/data/blank.flac tests/data/blank.mp3 tests/data/blank.ogg tests/data/blank.wav tests/data/comment-ext.m3u tests/data/comment.m3u tests/data/empty-ext.m3u tests/data/empty.m3u tests/data/encoding-ext.m3u tests/data/encoding.m3u tests/data/file1.conf tests/data/file2.conf tests/data/file3.conf tests/data/file4.conf tests/data/one-ext.m3u tests/data/one.m3u tests/data/song1.flac tests/data/song1.mp3 tests/data/song1.ogg tests/data/song1.wav tests/data/song2.flac tests/data/song2.mp3 tests/data/song2.ogg tests/data/song2.wav tests/data/song3.flac tests/data/song3.mp3 tests/data/song3.ogg tests/data/song3.wav tests/data/song4.wav tests/data/two-ext.m3u tests/data/conf1.d/file1.conf tests/data/conf1.d/file2.conf tests/data/conf2.d/file1.conf tests/data/conf2.d/file2.conf.disabled tests/data/scanner/empty.wav tests/data/scanner/example.log tests/data/scanner/plain.txt tests/data/scanner/playlist.m3u tests/data/scanner/sample.mp3 tests/data/scanner/advanced/song1.mp3 tests/data/scanner/advanced/song2.mp3 tests/data/scanner/advanced/song3.mp3 tests/data/scanner/advanced/subdir1/song4.mp3 tests/data/scanner/advanced/subdir1/song5.mp3 tests/data/scanner/advanced/subdir1/subsubdir/song8.mp3 tests/data/scanner/advanced/subdir1/subsubdir/song9.mp3 tests/data/scanner/advanced/subdir2/song6.mp3 tests/data/scanner/advanced/subdir2/song7.mp3 tests/data/scanner/empty/.gitignore tests/data/scanner/image/test.png tests/data/scanner/simple/song1.mp3 tests/data/scanner/simple/song1.ogg tests/file/__init__.py tests/file/conftest.py tests/file/test_browse.py tests/file/test_lookup.py tests/http/__init__.py tests/http/test_events.py tests/http/test_handlers.py tests/http/test_server.py tests/internal/__init__.py tests/internal/test_deps.py tests/internal/test_http.py tests/internal/test_jsonrpc.py tests/internal/test_models.py tests/internal/test_network.py tests/internal/test_path.py tests/internal/test_playlists.py tests/internal/test_validation.py tests/internal/test_xdg.py tests/m3u/__init__.py tests/m3u/test_playlists.py tests/m3u/test_translator.py tests/models/test_fields.py tests/models/test_legacy.py tests/models/test_models.py tests/stream/__init__.py tests/stream/test_library.py tests/stream/test_playback.py././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703636.0 Mopidy-3.2.0/Mopidy.egg-info/dependency_links.txt0000644000175100001710000000000100000000000021316 0ustar00runnerdocker ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703636.0 Mopidy-3.2.0/Mopidy.egg-info/entry_points.txt0000644000175100001710000000034400000000000020547 0ustar00runnerdocker[console_scripts] mopidy = mopidy.__main__:main [mopidy.ext] file = mopidy.file:Extension http = mopidy.http:Extension m3u = mopidy.m3u:Extension softwaremixer = mopidy.softwaremixer:Extension stream = mopidy.stream:Extension ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703636.0 Mopidy-3.2.0/Mopidy.egg-info/not-zip-safe0000644000175100001710000000000100000000000017476 0ustar00runnerdocker ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703636.0 Mopidy-3.2.0/Mopidy.egg-info/requires.txt0000644000175100001710000000071400000000000017652 0ustar00runnerdockerPykka>=2.0.1 requests>=2.0 setuptools tornado>=4.4 [dev] pygraphviz sphinx sphinx_rtd_theme black check-manifest flake8 flake8-black flake8-bugbear flake8-isort isort mypy pep8-naming types-requests types-setuptools pytest pytest-cov responses tox [docs] pygraphviz sphinx sphinx_rtd_theme [lint] black check-manifest flake8 flake8-black flake8-bugbear flake8-isort isort mypy pep8-naming types-requests types-setuptools [test] pytest pytest-cov responses ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703636.0 Mopidy-3.2.0/Mopidy.egg-info/top_level.txt0000644000175100001710000000000700000000000017777 0ustar00runnerdockermopidy ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1625703636.7250621 Mopidy-3.2.0/PKG-INFO0000644000175100001710000001114200000000000013411 0ustar00runnerdockerMetadata-Version: 2.1 Name: Mopidy Version: 3.2.0 Summary: Mopidy is an extensible music server written in Python Home-page: https://mopidy.com/ Author: Stein Magnus Jodal Author-email: stein.magnus@jodal.no License: Apache License, Version 2.0 Project-URL: Documentation, https://docs.mopidy.com/ Project-URL: Discourse forum, https://discourse.mopidy.com/ Project-URL: Zulip chat, https://mopidy.zulipchat.com/ Project-URL: Source, https://github.com/mopidy/mopidy Project-URL: Issues, https://github.com/mopidy/mopidy/issues Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: No Input/Output (Daemon) Classifier: Intended Audience :: End Users/Desktop Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: MacOS :: MacOS X Classifier: Operating System :: POSIX :: Linux Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.7 Classifier: Programming Language :: Python :: 3.8 Classifier: Programming Language :: Python :: 3.9 Classifier: Topic :: Multimedia :: Sound/Audio :: Players Requires-Python: >=3.7 Provides-Extra: docs Provides-Extra: lint Provides-Extra: test Provides-Extra: dev License-File: LICENSE ****** Mopidy ****** `Mopidy`_ is an extensible music server written in Python. Mopidy plays music from local disk, Spotify, SoundCloud, Google Play Music, and more. You edit the playlist from any phone, tablet, or computer using a variety of MPD and web clients. **Stream music from the cloud** Vanilla Mopidy only plays music from files and radio streams. Through `extensions`_, Mopidy can play music from cloud services like Spotify, SoundCloud, and Google Play Music. With Mopidy's extension support, backends for new music sources can be easily added. **Mopidy is just a server** Mopidy is a Python application that runs in a terminal or in the background on Linux computers or Macs that have network connectivity and audio output. Out of the box, Mopidy is an HTTP server. If you install the `Mopidy-MPD`_ extension, it becomes an MPD server too. Many additional frontends for controlling Mopidy are available as extensions. **Pick your favorite client** You and the people around you can all connect their favorite MPD or web client to the Mopidy server to search for music and manage the playlist together. With a browser or MPD client, which is available for all popular operating systems, you can control the music from any phone, tablet, or computer. **Mopidy on Raspberry Pi** The `Raspberry Pi`_ is an popular device to run Mopidy on, either using Raspbian, Ubuntu, or Arch Linux. Pimoroni recommends Mopidy for use with their `Pirate Audio`_ audio gear for Raspberry Pi. Mopidy is also a significant building block in the `Pi Musicbox`_ integrated audio jukebox system for Raspberry Pi. **Mopidy is hackable** Mopidy's extension support and Python, JSON-RPC, and JavaScript APIs make Mopidy a perfect base for your projects. In one hack, a Raspberry Pi was embedded in an old cassette player. The buttons and volume control are wired up with GPIO on the Raspberry Pi, and is used to control playback through a custom Mopidy extension. The cassettes have NFC tags used to select playlists from Spotify. .. _Mopidy: https://mopidy.com/ .. _extensions: https://mopidy.com/ext/ .. _Mopidy-MPD: https://mopidy.com/ext/mpd/ .. _Raspberry Pi: https://www.raspberrypi.org/ .. _Pirate Audio: https://shop.pimoroni.com/collections/pirate-audio .. _Pi Musicbox: https://www.pimusicbox.com/ **Getting started** To get started with Mopidy, begin by reading the `installation docs `_. **Project resources** - `Documentation `_ - `Discourse forum `_ - `Zulip chat `_ - `Source code `_ - `Issue tracker `_ .. image:: https://img.shields.io/pypi/v/Mopidy.svg?style=flat :target: https://pypi.python.org/pypi/Mopidy/ :alt: Latest PyPI version .. image:: https://img.shields.io/github/workflow/status/mopidy/mopidy/CI :target: https://github.com/mopidy/mopidy/actions :alt: CI build status .. image:: https://img.shields.io/readthedocs/mopidy.svg :target: https://docs.mopidy.com/ :alt: Read the Docs build status .. image:: https://img.shields.io/codecov/c/github/mopidy/mopidy/develop.svg :target: https://codecov.io/gh/mopidy/mopidy :alt: Test coverage .. image:: https://img.shields.io/badge/chat-on%20zulip-brightgreen :target: https://mopidy.zulipchat.com/ :alt: Chat on Zulip ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/README.rst0000644000175100001710000000657700000000000014023 0ustar00runnerdocker****** Mopidy ****** `Mopidy`_ is an extensible music server written in Python. Mopidy plays music from local disk, Spotify, SoundCloud, Google Play Music, and more. You edit the playlist from any phone, tablet, or computer using a variety of MPD and web clients. **Stream music from the cloud** Vanilla Mopidy only plays music from files and radio streams. Through `extensions`_, Mopidy can play music from cloud services like Spotify, SoundCloud, and Google Play Music. With Mopidy's extension support, backends for new music sources can be easily added. **Mopidy is just a server** Mopidy is a Python application that runs in a terminal or in the background on Linux computers or Macs that have network connectivity and audio output. Out of the box, Mopidy is an HTTP server. If you install the `Mopidy-MPD`_ extension, it becomes an MPD server too. Many additional frontends for controlling Mopidy are available as extensions. **Pick your favorite client** You and the people around you can all connect their favorite MPD or web client to the Mopidy server to search for music and manage the playlist together. With a browser or MPD client, which is available for all popular operating systems, you can control the music from any phone, tablet, or computer. **Mopidy on Raspberry Pi** The `Raspberry Pi`_ is an popular device to run Mopidy on, either using Raspbian, Ubuntu, or Arch Linux. Pimoroni recommends Mopidy for use with their `Pirate Audio`_ audio gear for Raspberry Pi. Mopidy is also a significant building block in the `Pi Musicbox`_ integrated audio jukebox system for Raspberry Pi. **Mopidy is hackable** Mopidy's extension support and Python, JSON-RPC, and JavaScript APIs make Mopidy a perfect base for your projects. In one hack, a Raspberry Pi was embedded in an old cassette player. The buttons and volume control are wired up with GPIO on the Raspberry Pi, and is used to control playback through a custom Mopidy extension. The cassettes have NFC tags used to select playlists from Spotify. .. _Mopidy: https://mopidy.com/ .. _extensions: https://mopidy.com/ext/ .. _Mopidy-MPD: https://mopidy.com/ext/mpd/ .. _Raspberry Pi: https://www.raspberrypi.org/ .. _Pirate Audio: https://shop.pimoroni.com/collections/pirate-audio .. _Pi Musicbox: https://www.pimusicbox.com/ **Getting started** To get started with Mopidy, begin by reading the `installation docs `_. **Project resources** - `Documentation `_ - `Discourse forum `_ - `Zulip chat `_ - `Source code `_ - `Issue tracker `_ .. image:: https://img.shields.io/pypi/v/Mopidy.svg?style=flat :target: https://pypi.python.org/pypi/Mopidy/ :alt: Latest PyPI version .. image:: https://img.shields.io/github/workflow/status/mopidy/mopidy/CI :target: https://github.com/mopidy/mopidy/actions :alt: CI build status .. image:: https://img.shields.io/readthedocs/mopidy.svg :target: https://docs.mopidy.com/ :alt: Read the Docs build status .. image:: https://img.shields.io/codecov/c/github/mopidy/mopidy/develop.svg :target: https://codecov.io/gh/mopidy/mopidy :alt: Test coverage .. image:: https://img.shields.io/badge/chat-on%20zulip-brightgreen :target: https://mopidy.zulipchat.com/ :alt: Chat on Zulip ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1625703636.7050605 Mopidy-3.2.0/docs/0000755000175100001710000000000000000000000013245 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/Makefile0000644000175100001710000001075600000000000014716 0ustar00runnerdocker# Makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = BUILDDIR = _build # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 PAPEROPT_letter = -D latex_paper_size=letter ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . .PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest help: @echo "Please use \`make ' where is one of" @echo " html to make standalone HTML files" @echo " dirhtml to make HTML files named index.html in directories" @echo " singlehtml to make a single large HTML file" @echo " pickle to make pickle files" @echo " json to make JSON files" @echo " htmlhelp to make HTML files and a HTML help project" @echo " qthelp to make HTML files and a qthelp project" @echo " devhelp to make HTML files and a Devhelp project" @echo " epub to make an epub" @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" @echo " latexpdf to make LaTeX files and run them through pdflatex" @echo " text to make text files" @echo " man to make manual pages" @echo " changes to make an overview of all changed/added/deprecated items" @echo " linkcheck to check all external links for integrity" @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: -rm -rf $(BUILDDIR)/* html: $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml @echo @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." singlehtml: $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml @echo @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." pickle: $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle @echo @echo "Build finished; now you can process the pickle files." json: $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json @echo @echo "Build finished; now you can process the JSON files." htmlhelp: $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp @echo @echo "Build finished; now you can run HTML Help Workshop with the" \ ".hhp project file in $(BUILDDIR)/htmlhelp." qthelp: $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp @echo @echo "Build finished; now you can run "qcollectiongenerator" with the" \ ".qhcp project file in $(BUILDDIR)/qthelp, like this:" @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Mopidy.qhcp" @echo "To view the help file:" @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Mopidy.qhc" devhelp: $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp @echo @echo "Build finished." @echo "To view the help file:" @echo "# mkdir -p $$HOME/.local/share/devhelp/Mopidy" @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Mopidy" @echo "# devhelp" epub: $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub @echo @echo "Build finished. The epub file is in $(BUILDDIR)/epub." latex: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." @echo "Run \`make' in that directory to run these through (pdf)latex" \ "(use \`make latexpdf' here to do that automatically)." latexpdf: $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex @echo "Running LaTeX files through pdflatex..." make -C $(BUILDDIR)/latex all-pdf @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." text: $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text @echo @echo "Build finished. The text files are in $(BUILDDIR)/text." man: $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man @echo @echo "Build finished. The manual pages are in $(BUILDDIR)/man." changes: $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes @echo @echo "The overview file is in $(BUILDDIR)/changes." linkcheck: $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck @echo @echo "Link check complete; look for any errors in the above output " \ "or in $(BUILDDIR)/linkcheck/output.txt." doctest: $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest @echo "Testing of doctests in the sources finished, look at the " \ "results in $(BUILDDIR)/doctest/output.txt." ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1625703636.7050605 Mopidy-3.2.0/docs/_static/0000755000175100001710000000000000000000000014673 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/_static/mopidy.png0000644000175100001710000000646600000000000016716 0ustar00runnerdockerPNG  IHDR<V~sRGBbKGD pHYs  tIME 6;tEXtCommentCreated with GIMPW IDATx{E?/rS@@/) Bf:vILitFTR QbLTDL eBHxOQxQ=9缇Μw/>=Q;7W[u L.nމQN*<l!S)vYDD1|0J&`π2_DU#Mܨ"/BhX]sv;嬂3P82c@"+yP1e$?3.<! ιA<Ȇ.bK,C %̹uVFWvSC[o⍫=&eH؋~Wű 6!BPߗfzV*КCæz{g 7kOau%BzBx_{j%k`OO9D$pfovcہo(<Vu+H" ~aI-=RLpr&9x%BDmB(`6.Gt$V%ccR\ ܛ"߅@6l˨ h`?S fSm ƣo%30Үk1@}VeׁRak5:[v `۰s)"<و*_Ϥ:~_i=zԷ.o{*fn%IF}?golELZR<LцBBGhUY=qɳ1dodJ%7CHZ*~&%]_%"~nd$%<.cG}bMn=0\YK3 q`ޔb3I  XIGю2'uBBc_JxZ5U9u-`p VGB J5k|Wx):!Mـp|A l7R[$cϵ{Q"ߛyB1V!zY 26JWJ8IX[]DG_d\T0L8g>8)!L ԶZ kG AjBr+ã6%.StMQG+58[ &\1'ħ5>$}< clA:Ɏi+8Qa3lA C0I[-d%i 8@ 0l&Zpu>QN&}XhB9+h T񐠈>6)fx BZrʹ;ͣ`޻ʸ&2AȻwBxRPf5~:vo[FRee>!lt3,X[1V!.6a7<#my -ޙ+EYlPŜ塴^v#<[60\\x\]zwV[gLxN&+ƷH!Z6.!) M4Pީ(+kSIP\x!!M/qsd#L!̈́Kn~ypv:BpM/ҭv`Nlwcs K9PAz9!͡/B,Rʀ:P_y-p^K0۪,!8k:ߑn:|ɷ zX3%퐀}o!Mh i^ |EH3`Ҏ"q'^ U!B0WOmb=%|7HIr+~=t@><V[P\iA QY !^J!7>Ҵ,gB+ yjs!> 1w>r+_T&چeP`i+W;.I#͒!)*é+_${ȫ}5`+)]F#4gw ta_B}78HD!$ x{fy>52 mRq9媜qaX 7fz'b1µ}Lޞ)b.ܺ,$}eJ>2yDvRbq&6)ek߉Qv%;<\Rz nmS Nv\Eǧ$[?!}\ AysbYb r@ҽ_3Q0EYUL&&<yZp9@) >CLu U4!YϋRXA/cDy~QޚkHB؆y\:B _jDBhj=a3qyJE7>?呍 g`W̥<_)r#>Q&^WIS#e{SDS`,n,=!/9Y$YrP59l4B!=K"$"Jq݁ 0n[myUBǦ1/I q?b3&* 9<_*}3{®-+Ls헸q8NvxKӉn^z_m۹@6IGcY?[}DQy%N@8:S㻈H!Pkzq3V<E q^̍jٚ !]DD$p4ٽ;+KGM,>.EDD `~J`yEDDB0saZGo_u&Şl sx9&L跈jC (IENDB`././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1625703636.7050605 Mopidy-3.2.0/docs/api/0000755000175100001710000000000000000000000014016 5ustar00runnerdocker././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/api/architecture.rst0000644000175100001710000000704100000000000017234 0ustar00runnerdocker.. _concepts: ************ Architecture ************ The overall architecture of Mopidy is organized around multiple frontends and backends. The frontends use the core API. The core actor makes multiple backends work as one. The backends connect to various music sources. The core actor use the mixer actor to control volume, while the backends use the audio actor to play audio. .. digraph:: overall_architecture "Multiple frontends" -> Core Core -> "Multiple backends" Core -> Mixer "Multiple backends" -> Audio Frontends ========= Frontends expose Mopidy to the external world. They can implement servers for protocols like HTTP, MPD and MPRIS, and they can be used to update other services when something happens in Mopidy, like the Last.fm scrobbler frontend does. See :ref:`frontend-api` for more details. .. digraph:: frontend_architecture "HTTP\nfrontend" -> Core "MPD\nfrontend" -> Core "MPRIS\nfrontend" -> Core "Scrobbler\nfrontend" -> Core Core ==== The core is organized as a set of controllers with responsiblity for separate sets of functionality. The core is the single actor that the frontends send their requests to. For every request from a frontend it calls out to one or more backends which does the real work, and when the backends respond, the core actor is responsible for combining the responses into a single response to the requesting frontend. The core actor also keeps track of the tracklist, since it doesn't belong to a specific backend. See :ref:`core-api` for more details. .. digraph:: core_architecture Core -> "Tracklist\ncontroller" Core -> "Library\ncontroller" Core -> "Playback\ncontroller" Core -> "Playlists\ncontroller" Core -> "History\ncontroller" "Library\ncontroller" -> "Local backend" "Library\ncontroller" -> "Spotify backend" "Playback\ncontroller" -> "Local backend" "Playback\ncontroller" -> "Spotify backend" "Playback\ncontroller" -> Audio "Playlists\ncontroller" -> "Local backend" "Playlists\ncontroller" -> "Spotify backend" Backends ======== The backends are organized as a set of providers with responsiblity for separate sets of functionality, similar to the core actor. Anything specific to i.e. Spotify integration or local storage is contained in the backends. To integrate with new music sources, you just add a new backend. See :ref:`backend-api` for more details. .. digraph:: backend_architecture "Local backend" -> "Local\nlibrary\nprovider" -> "Local disk" "Local backend" -> "Local\nplayback\nprovider" -> "Local disk" "Local backend" -> "Local\nplaylists\nprovider" -> "Local disk" "Local\nplayback\nprovider" -> Audio "Spotify backend" -> "Spotify\nlibrary\nprovider" -> "Spotify service" "Spotify backend" -> "Spotify\nplayback\nprovider" -> "Spotify service" "Spotify backend" -> "Spotify\nplaylists\nprovider" -> "Spotify service" "Spotify\nplayback\nprovider" -> Audio Audio ===== The audio actor is a thin wrapper around the parts of the GStreamer library we use. If you implement an advanced backend, you may need to implement your own playback provider using the :ref:`audio-api`, but most backends can use the default playback provider without any changes. Mixer ===== The mixer actor is responsible for volume control and muting. The default mixer use the audio actor to control volume in software. The alternative implementations are typically independent of the audio actor, but instead use some third party Python library or a serial interface to control other forms of volume controls. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/api/audio.rst0000644000175100001710000000205200000000000015650 0ustar00runnerdocker.. _audio-api: ********************************* :mod:`mopidy.audio` --- Audio API ********************************* .. module:: mopidy.audio :synopsis: Thin wrapper around the parts of GStreamer we use The audio API is the interface we have built around GStreamer to support our specific use cases. Most backends should be able to get by with simply setting the URI of the resource they want to play, for these cases the default playback provider should be used. For more advanced cases such as when the raw audio data is delivered outside of GStreamer or the backend needs to add metadata to the currently playing resource, developers should sub-class the base playback provider and implement the extra behaviour that is needed through the following API: .. autoclass:: mopidy.audio.Audio :members: Audio listener ============== .. autoclass:: mopidy.audio.AudioListener :members: Audio scanner ============= .. autoclass:: mopidy.audio.scan.Scanner :members: Audio utils =========== .. automodule:: mopidy.audio.utils :members: ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/api/backend.rst0000644000175100001710000000740700000000000016147 0ustar00runnerdocker.. _backend-api: ************************************* :mod:`mopidy.backend` --- Backend API ************************************* .. module:: mopidy.backend :synopsis: The API implemented by backends The backend API is the interface that must be implemented when you create a backend. If you are working on a frontend and need to access the backends, see the :ref:`core-api` instead. URIs and routing of requests to the backend =========================================== When Mopidy's core layer is processing a client request, it routes the request to one or more appropriate backends based on the URIs of the objects the request touches on. The objects' URIs are compared with the backends' :attr:`~mopidy.backend.Backend.uri_schemes` to select the relevant backends. An often used pattern when implementing Mopidy backends is to create your own URI scheme which you use for all tracks, playlists, etc. related to your backend. In most cases the Mopidy URI is translated to an actual URI that GStreamer knows how to play right before playback. For example: - Spotify already has its own URI scheme (``spotify:track:...``, ``spotify:playlist:...``, etc.) used throughout their applications, and thus Mopidy-Spotify simply uses the same URI scheme. Playback is handled by pushing raw audio data into a GStreamer ``appsrc`` element. - Mopidy-SoundCloud created it's own URI scheme, after the model of Spotify, and use URIs of the following forms: ``soundcloud:search``, ``soundcloud:user-...``, ``soundcloud:exp-...``, and ``soundcloud:set-...``. Playback is handled by converting the custom ``soundcloud:..`` URIs to ``http://`` URIs immediately before they are passed on to GStreamer for playback. - Mopidy differentiates between ``file://...`` URIs handled by :ref:`ext-stream` and ``local:...`` URIs handled by Mopidy-Local. :ref:`ext-stream` can play ``file://...`` URIs pointing to tracks and playlists located anywhere on your system, but it doesn't know a thing about the object before you play it. On the other hand, Mopidy-Local scans a predefined :confval:`local/media_dir` to build a meta data library of all known tracks. It is thus limited to playing tracks residing in the media library, but can provide additional features like directory browsing and search. In other words, we have two different ways of playing local music, handled by two different backends, and have thus created two different URI schemes to separate their handling. The ``local:...`` URIs are converted to ``file://...`` URIs immediately before they are passed on to GStreamer for playback. If there isn't an existing URI scheme that fits for your backend's purpose, you should create your own, and name it after your extension's :attr:`~mopidy.ext.Extension.ext_name`. Care should be taken not to conflict with already in use URI schemes. It is also recommended to design the format such that tracks, playlists and other entities can be distinguished easily. However, it's important to note that outside of the backend that created them, URIs are opaque values that neither Mopidy's core layer or Mopidy frontends should attempt to derive any meaning from. The only valid exception to this is checking the scheme. Backend class ============= .. autoclass:: mopidy.backend.Backend :members: Playback provider ================= .. autoclass:: mopidy.backend.PlaybackProvider :members: Playlists provider ================== .. autoclass:: mopidy.backend.PlaylistsProvider :members: Library provider ================ .. autoclass:: mopidy.backend.LibraryProvider :members: Backend listener ================ .. autoclass:: mopidy.backend.BackendListener :members: Backend implementations ======================= See the `extension registry `_. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/api/commands.rst0000644000175100001710000000034600000000000016354 0ustar00runnerdocker.. _commands-api: *************************************** :mod:`mopidy.commands` --- Commands API *************************************** .. automodule:: mopidy.commands :synopsis: Commands API for Mopidy CLI. :members: ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/api/config.rst0000644000175100001710000000122500000000000016015 0ustar00runnerdocker.. _config-api: *********************************** :mod:`mopidy.config` --- Config API *********************************** .. automodule:: mopidy.config :synopsis: Config API for config loading and validation :members: Config section schemas ====================== .. automodule:: mopidy.config.schemas :synopsis: Config section validation schemas :members: Config value types ================== .. automodule:: mopidy.config.types :synopsis: Config value validation types :members: Config value validators ======================= .. automodule:: mopidy.config.validators :synopsis: Config value validators :members: ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/api/core.rst0000644000175100001710000001355400000000000015510 0ustar00runnerdocker.. _core-api: ******************************* :mod:`mopidy.core` --- Core API ******************************* .. module:: mopidy.core :synopsis: Core API for use by frontends The core API is the interface that is used by frontends like :mod:`mopidy.http` and Mopidy-MPD. The core layer is in between the frontends and the backends. Don't forget that you will be accessing core as a Pykka actor. If you are only interested in being notified about changes in core see :class:`~mopidy.core.CoreListener`. .. versionchanged:: 1.1 All core API calls are now type checked. .. versionchanged:: 1.1 All backend return values are now type checked. .. autoclass:: mopidy.core.Core .. attribute:: tracklist Manages everything related to the list of tracks we will play. See :class:`~mopidy.core.TracklistController`. .. attribute:: playback Manages playback state and the current playing track. See :class:`~mopidy.core.PlaybackController`. .. attribute:: library Manages the music library, e.g. searching and browsing for music. See :class:`~mopidy.core.LibraryController`. .. attribute:: playlists Manages stored playlists. See :class:`~mopidy.core.PlaylistsController`. .. attribute:: mixer Manages volume and muting. See :class:`~mopidy.core.MixerController`. .. attribute:: history Keeps record of what tracks have been played. See :class:`~mopidy.core.HistoryController`. .. automethod:: get_uri_schemes .. automethod:: get_version Tracklist controller ==================== .. autoclass:: mopidy.core.TracklistController Manipulating ------------ .. automethod:: mopidy.core.TracklistController.add .. automethod:: mopidy.core.TracklistController.remove .. automethod:: mopidy.core.TracklistController.clear .. automethod:: mopidy.core.TracklistController.move .. automethod:: mopidy.core.TracklistController.shuffle Current state ------------- .. automethod:: mopidy.core.TracklistController.get_tl_tracks .. automethod:: mopidy.core.TracklistController.index .. automethod:: mopidy.core.TracklistController.get_version .. automethod:: mopidy.core.TracklistController.get_length .. automethod:: mopidy.core.TracklistController.get_tracks .. automethod:: mopidy.core.TracklistController.slice .. automethod:: mopidy.core.TracklistController.filter Future state ------------ .. automethod:: mopidy.core.TracklistController.get_eot_tlid .. automethod:: mopidy.core.TracklistController.get_next_tlid .. automethod:: mopidy.core.TracklistController.get_previous_tlid .. automethod:: mopidy.core.TracklistController.eot_track .. automethod:: mopidy.core.TracklistController.next_track .. automethod:: mopidy.core.TracklistController.previous_track Options ------- .. automethod:: mopidy.core.TracklistController.get_consume .. automethod:: mopidy.core.TracklistController.set_consume .. automethod:: mopidy.core.TracklistController.get_random .. automethod:: mopidy.core.TracklistController.set_random .. automethod:: mopidy.core.TracklistController.get_repeat .. automethod:: mopidy.core.TracklistController.set_repeat .. automethod:: mopidy.core.TracklistController.get_single .. automethod:: mopidy.core.TracklistController.set_single Playback controller =================== .. autoclass:: mopidy.core.PlaybackController Playback control ---------------- .. automethod:: mopidy.core.PlaybackController.play .. automethod:: mopidy.core.PlaybackController.next .. automethod:: mopidy.core.PlaybackController.previous .. automethod:: mopidy.core.PlaybackController.stop .. automethod:: mopidy.core.PlaybackController.pause .. automethod:: mopidy.core.PlaybackController.resume .. automethod:: mopidy.core.PlaybackController.seek Current track ------------- .. automethod:: mopidy.core.PlaybackController.get_current_tl_track .. automethod:: mopidy.core.PlaybackController.get_current_track .. automethod:: mopidy.core.PlaybackController.get_current_tlid .. automethod:: mopidy.core.PlaybackController.get_stream_title .. automethod:: mopidy.core.PlaybackController.get_time_position Playback states --------------- .. automethod:: mopidy.core.PlaybackController.get_state .. automethod:: mopidy.core.PlaybackController.set_state .. class:: mopidy.core.PlaybackState .. attribute:: STOPPED :annotation: = 'stopped' .. attribute:: PLAYING :annotation: = 'playing' .. attribute:: PAUSED :annotation: = 'paused' Library controller ================== .. class:: mopidy.core.LibraryController .. automethod:: mopidy.core.LibraryController.browse .. automethod:: mopidy.core.LibraryController.search .. automethod:: mopidy.core.LibraryController.lookup .. automethod:: mopidy.core.LibraryController.refresh .. automethod:: mopidy.core.LibraryController.get_images .. automethod:: mopidy.core.LibraryController.get_distinct Playlists controller ==================== .. class:: mopidy.core.PlaylistsController .. automethod:: mopidy.core.PlaylistsController.get_uri_schemes Fetching -------- .. automethod:: mopidy.core.PlaylistsController.as_list .. automethod:: mopidy.core.PlaylistsController.get_items .. automethod:: mopidy.core.PlaylistsController.lookup .. automethod:: mopidy.core.PlaylistsController.refresh Manipulating ------------ .. automethod:: mopidy.core.PlaylistsController.create .. automethod:: mopidy.core.PlaylistsController.save .. automethod:: mopidy.core.PlaylistsController.delete Mixer controller ================ .. class:: mopidy.core.MixerController .. automethod:: mopidy.core.MixerController.get_mute .. automethod:: mopidy.core.MixerController.set_mute .. automethod:: mopidy.core.MixerController.get_volume .. automethod:: mopidy.core.MixerController.set_volume History controller ================== .. class:: mopidy.core.HistoryController .. automethod:: mopidy.core.HistoryController.get_history .. automethod:: mopidy.core.HistoryController.get_length Core events =========== .. autoclass:: mopidy.core.CoreListener :members: ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/api/ext.rst0000644000175100001710000000044200000000000015350 0ustar00runnerdocker.. _ext-api: ********************************** :mod:`mopidy.ext` -- Extension API ********************************** If you want to learn how to make Mopidy extensions, read :ref:`extensiondev`. .. automodule:: mopidy.ext :synopsis: Extension API for extending Mopidy :members: ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/api/frontend.rst0000644000175100001710000000312700000000000016372 0ustar00runnerdocker.. _frontend-api: ************ Frontend API ************ The following requirements applies to any frontend implementation: - A frontend MAY do mostly whatever it wants to, including creating threads, opening TCP ports and exposing Mopidy for a group of clients. - A frontend MUST implement at least one `Pykka `_ actor, called the "main actor" from here on. - The main actor MUST accept two constructor arguments: - ``config``, which is a dict structure with the entire Mopidy configuration. - ``core``, which will be an :class:`ActorProxy ` for the core actor. This object gives access to the full :ref:`core-api`. - It MAY use additional actors to implement whatever it does, and using actors in frontend implementations is encouraged. - The frontend is enabled if the extension it is part of is enabled. See :ref:`extensiondev` for more information. - The main actor MUST be able to start and stop the frontend when the main actor is started and stopped. - The frontend MAY require additional config values to be set for it to work. - Such config values MUST be documented. - The main actor MUST raise the :exc:`mopidy.exceptions.FrontendError` with a descriptive error message if the defined config values are not adequate for the frontend to work properly. - Any actor which is part of the frontend MAY implement the :class:`mopidy.core.CoreListener` interface to receive notification of the specified events. Frontend implementations ======================== See the `extension registry `_. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/api/http-server.rst0000644000175100001710000001376000000000000017042 0ustar00runnerdocker.. _http-server-api: ******************** HTTP server side API ******************** The :ref:`ext-http` extension comes with an HTTP server to host Mopidy's :ref:`http-api`. This web server can also be used by other extensions that need to expose something over HTTP. The HTTP server side API can be used to: - host static files for e.g. a Mopidy client written in pure JavaScript, - host a `Tornado `__ application, or - host a WSGI application, including e.g. Flask applications. To host static files using the web server, an extension needs to register a name and a file path in the extension registry under the ``http:static`` key. To extend the web server with a web application, an extension must register a name and a factory function in the extension registry under the ``http:app`` key. For details on how to make a Mopidy extension, see the :ref:`extensiondev` guide. .. _static-web-client: Static web client example ========================= To serve static files, you just need to register an ``http:static`` dictionary in the extension registry. The dictionary must have two keys: ``name`` and ``path``. The ``name`` is used to build the URL the static files will be served on. By convention, it should be identical with the extension's :attr:`~mopidy.ext.Extension.ext_name`, like in the following example. The ``path`` tells Mopidy where on the disk the static files are located. Assuming that the code below is located in the file :file:`mywebclient/__init__.py`, the files in the directory :file:`mywebclient/static/` will be made available at ``/mywebclient/`` on Mopidy's web server. For example, :file:`mywebclient/static/foo.html` will be available at http://localhost:6680/mywebclient/foo.html. :: import os from mopidy import ext class MyWebClientExtension(ext.Extension): ext_name = 'mywebclient' def setup(self, registry): registry.add('http:static', { 'name': self.ext_name, 'path': os.path.join(os.path.dirname(__file__), 'static'), }) # See the Extension API for the full details on this class Tornado application example =========================== The :ref:`ext-http` extension's web server is based on the `Tornado `__ web framework. Thus, it has first class support for Tornado request handlers. In the following example, we create a :class:`tornado.web.RequestHandler` called :class:`MyRequestHandler` that responds to HTTP GET requests with the string ``Hello, world! This is Mopidy $version``, where it gets the Mopidy version from Mopidy's core API. To hook the request handler into Mopidy's web server, we must register a dictionary under the ``http:app`` key in the extension registry. The dictionary must have two keys: ``name`` and ``factory``. The ``name`` is used to build the URL the app will be served on. By convention, it should be identical with the extension's :attr:`~mopidy.ext.Extension.ext_name`, like in the following example. The ``factory`` must be a function that accepts two arguments, ``config`` and ``core``, respectively a dict structure of Mopidy's config and a :class:`pykka.ActorProxy` to the full Mopidy core API. The ``factory`` function must return a list of Tornado request handlers. The URL patterns of the request handlers should not include the ``name``, as that will be prepended to the URL patterns by the web server. When the extension is installed, Mopidy will respond to requests to http://localhost:6680/mywebclient/ with the string ``Hello, world! This is Mopidy $version``. :: import os import tornado.web from mopidy import ext class MyRequestHandler(tornado.web.RequestHandler): def initialize(self, core): self.core = core def get(self): self.write( 'Hello, world! This is Mopidy %s' % self.core.get_version().get()) def my_app_factory(config, core): return [ ('/', MyRequestHandler, {'core': core}) ] class MyWebClientExtension(ext.Extension): ext_name = 'mywebclient' def setup(self, registry): registry.add('http:app', { 'name': self.ext_name, 'factory': my_app_factory, }) # See the Extension API for the full details on this class WSGI application example ======================== WSGI applications are second-class citizens on Mopidy's HTTP server. The WSGI applications are run inside Tornado, which is based on non-blocking I/O and a single event loop. In other words, your WSGI applications will only have a single thread to run on, and if your application is doing blocking I/O, it will block all other requests from being handled by the web server as well. The example below shows how a WSGI application that returns the string ``Hello, world! This is Mopidy $version`` on all requests. The WSGI application is wrapped as a Tornado application and mounted at http://localhost:6680/mywebclient/. :: import os import tornado.web import tornado.wsgi from mopidy import ext def my_app_factory(config, core): def wsgi_app(environ, start_response): status = '200 OK' response_headers = [('Content-type', 'text/plain')] start_response(status, response_headers) return [ 'Hello, world! This is Mopidy %s\n' % self.core.get_version().get() ] return [ ('(.*)', tornado.web.FallbackHandler, { 'fallback': tornado.wsgi.WSGIContainer(wsgi_app), }), ] class MyWebClientExtension(ext.Extension): ext_name = 'mywebclient' def setup(self, registry): registry.add('http:app', { 'name': self.ext_name, 'factory': my_app_factory, }) # See the Extension API for the full details on this class API implementors ================ See the `extension registry `_. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/api/http.rst0000644000175100001710000000707700000000000015542 0ustar00runnerdocker.. _http-api: ***************** HTTP JSON-RPC API ***************** The :ref:`ext-http` extension makes Mopidy's :ref:`core-api` available using JSON-RPC over HTTP using HTTP POST and WebSockets. We also provide a JavaScript wrapper, called :ref:`Mopidy.js `, around the JSON-RPC over WebSocket API for use both from browsers and Node.js. The `Mopidy-API-Explorer `_ extension can also be used to get you familiarized with HTTP based APIs. .. _http-post-api: HTTP POST API ============= The Mopidy web server accepts HTTP requests with the POST method to http://localhost:6680/mopidy/rpc, where the ``localhost:6680`` part will vary with your local setup. Your requests must also set the ``Content-Type`` header to ``application/json``. The HTTP POST endpoint gives you access to Mopidy's full core API, but does not give you notification on events. If you need to listen to events, you should probably use the WebSocket API instead. Example usage from the command line:: $ curl -d '{"jsonrpc": "2.0", "id": 1, "method": "core.playback.get_state"}' -H 'Content-Type: application/json' http://localhost:6680/mopidy/rpc {"jsonrpc": "2.0", "id": 1, "result": "stopped"} For details on the request and response format, see :ref:`json-rpc`. .. _websocket-api: WebSocket API ============= The Mopidy web server exposes a WebSocket at http://localhost:6680/mopidy/ws, where the ``localhost:6680`` part will vary with your local setup. The WebSocket gives you access to Mopidy's full API and enables Mopidy to instantly push events to the client, as they happen. On the WebSocket we send two different kind of messages: The client can send :ref:`JSON-RPC 2.0 requests `, and the server will respond with JSON-RPC 2.0 responses. In addition, the server will send :ref:`event messages ` when something happens on the server. Both message types are encoded as JSON objects. If you're using the API from JavaScript, either in the browser or in Node.js, you should use :ref:`mopidy-js` which wraps the WebSocket API in a nice JavaScript API. .. _json-rpc: JSON-RPC 2.0 messages ===================== JSON-RPC 2.0 messages can be recognized by checking for the key named ``jsonrpc`` with the string value ``2.0``. For details on the messaging format, please refer to the `JSON-RPC 2.0 spec `_. All methods in the :ref:`core-api` is made available through JSON-RPC calls over the WebSocket. For example, :meth:`mopidy.core.PlaybackController.play` is available as the JSON-RPC method ``core.playback.play``. Example JSON-RPC request:: {"jsonrpc": "2.0", "id": 1, "method": "core.playback.get_current_track"} Example JSON-RPC response:: {"jsonrpc": "2.0", "id": 1, "result": {"__model__": "Track", "...": "..."}} The JSON-RPC method ``core.describe`` returns a data structure describing all available methods. If you're unsure how the core API maps to JSON-RPC, having a look at the ``core.describe`` response can be helpful. .. _json-events: Event messages ============== Event objects will always have a key named ``event`` whose value is the event type. Depending on the event type, the event may include additional fields for related data. The events maps directly to the :class:`mopidy.core.CoreListener` API. Refer to the :class:`~mopidy.core.CoreListener` method names is the available event types. The :class:`~mopidy.core.CoreListener` method's keyword arguments are all included as extra fields on the event objects. Example event message:: {"event": "track_playback_started", "track": {...}} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/api/httpclient.rst0000644000175100001710000000043200000000000016725 0ustar00runnerdocker.. _httpclient-helper: ************************************************ :mod:`mopidy.httpclient` --- HTTP Client helpers ************************************************ .. automodule:: mopidy.httpclient :synopsis: HTTP Client helpers for Mopidy its Extensions. :members: ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/api/index.rst0000644000175100001710000000077100000000000015664 0ustar00runnerdocker.. _api-ref: ************* API reference ************* .. note:: Only APIs documented here are public and open for use by Mopidy extensions. Concepts ======== .. toctree:: architecture models Basics ====== .. toctree:: core frontend backend ext Web/JavaScript ============== .. toctree:: http-server http js Audio ===== .. toctree:: audio mixer Utilities ========= .. toctree:: commands config httpclient zeroconf ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/api/js.rst0000644000175100001710000000103500000000000015163 0ustar00runnerdocker.. _mopidy-js: **************************** Mopidy.js JavaScript library **************************** We've made a JavaScript library, Mopidy.js, which wraps the :ref:`websocket-api` and gets you quickly started with working on your client instead of figuring out how to communicate with Mopidy. This library is used as the foundation of most `Mopidy web clients `__. See the `Mopidy.js project `_ for detailed usage documentation and demo applications built using Mopidy.js. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/api/mixer.rst0000644000175100001710000000062700000000000015701 0ustar00runnerdocker.. _mixer-api: *************************************** :mod:`mopidy.mixer` --- Audio mixer API *************************************** .. module:: mopidy.mixer :synopsis: The audio mixer API .. autoclass:: mopidy.mixer.Mixer :members: .. autoclass:: mopidy.mixer.MixerListener :members: Mixer implementations ===================== See the `extension registry `_. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/api/models.rst0000644000175100001710000000563200000000000016041 0ustar00runnerdocker************************************ :mod:`mopidy.models` --- Data models ************************************ These immutable data models are used for all data transfer within the Mopidy backends and between the backends and the MPD frontend. All fields are optional and immutable. In other words, they can only be set through the class constructor during instance creation. Additionally fields are type checked. If you want to modify a model, use the :meth:`~mopidy.models.ImmutableObject.replace` method. It accepts keyword arguments for the parts of the model you want to change, and copies the rest of the data from the model you call it on. Example:: >>> from mopidy.models import Track >>> track1 = Track(name='Christmas Carol', length=171) >>> track1 Track(artists=[], length=171, name='Christmas Carol') >>> track2 = track1.replace(length=37) >>> track2 Track(artists=[], length=37, name='Christmas Carol') >>> track1 Track(artists=[], length=171, name='Christmas Carol') Data model relations ==================== .. digraph:: model_relations Ref -> Album [ style="dotted", weight=1 ] Ref -> Artist [ style="dotted", weight=1 ] Ref -> Directory [ style="dotted", weight=1 ] Ref -> Playlist [ style="dotted", weight=1 ] Ref -> Track [ style="dotted", weight=1 ] Playlist -> Track [ label="has 0..n", weight=2 ] Track -> Album [ label="has 0..1", weight=10 ] Track -> Artist [ label="has 0..n", weight=10 ] Album -> Artist [ label="has 0..n", weight=10 ] Image SearchResult -> Artist [ label="has 0..n", weight=1 ] SearchResult -> Album [ label="has 0..n", weight=1 ] SearchResult -> Track [ label="has 0..n", weight=1 ] TlTrack -> Track [ label="has 1", weight=20 ] Data model API ============== .. module:: mopidy.models :synopsis: Data model API .. autoclass:: mopidy.models.Ref :members: .. autoclass:: mopidy.models.Track :members: .. autoclass:: mopidy.models.Album :members: .. autoclass:: mopidy.models.Artist :members: .. autoclass:: mopidy.models.Playlist :members: .. autoclass:: mopidy.models.Image :members: .. autoclass:: mopidy.models.TlTrack :members: .. autoclass:: mopidy.models.SearchResult :members: Data model helpers ================== .. autoclass:: mopidy.models.ImmutableObject :members: .. autoclass:: mopidy.models.ValidatedImmutableObject :members: replace Data model (de)serialization ---------------------------- .. autofunction:: mopidy.models.model_json_decoder .. autoclass:: mopidy.models.ModelJSONEncoder Data model field types ---------------------- .. autoclass:: mopidy.models.fields.Field .. autoclass:: mopidy.models.fields.String .. autoclass:: mopidy.models.fields.Identifier .. autoclass:: mopidy.models.fields.URI .. autoclass:: mopidy.models.fields.Date .. autoclass:: mopidy.models.fields.Integer .. autoclass:: mopidy.models.fields.Collection ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/api/zeroconf.rst0000644000175100001710000000041400000000000016374 0ustar00runnerdocker.. _zeroconf-api: *************************************** :mod:`mopidy.zeroconf` --- Zeroconf API *************************************** .. module:: mopidy.zeroconf :synopsis: Helper for publishing of services on Zeroconf .. autoclass:: Zeroconf :members: ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/audiosinks.rst0000644000175100001710000000252300000000000016152 0ustar00runnerdocker.. _audiosinks: *********** Audio sinks *********** Mopidy has very few :ref:`audio configurations `, but the ones we have are very powerful because they let you modify the GStreamer audio pipeline directly. If you have successfully installed GStreamer, and then run the ``gst-inspect-1.0`` command, you should see a long listing of installed plugins, ending in a summary line:: $ gst-inspect-1.0 ... long list of installed plugins ... Total count: 233 plugins, 1339 features Next, you should be able to produce a audible tone by running:: gst-launch-1.0 audiotestsrc ! audioresample ! autoaudiosink If you cannot hear any sound when running this command, you won't hear any sound from Mopidy either, as Mopidy by default uses GStreamer's ``autoaudiosink`` to play audio. Thus, make this work before you file a bug against Mopidy. If you for some reason want to use some other GStreamer audio sink than ``autoaudiosink``, you can set the :confval:`audio/output` config value to a partial GStreamer pipeline description describing the GStreamer sink you want to use. Example ``mopidy.conf`` for using OSS4: .. code-block:: ini [audio] output = oss4sink Again, this is the equivalent of the following ``gst-launch-1.0`` command, so make this work first:: gst-launch-1.0 audiotestsrc ! audioresample ! oss4sink ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/authors.rst0000644000175100001710000000123400000000000015464 0ustar00runnerdocker.. _authors: ******* Authors ******* Mopidy is copyright 2009-2021 Stein Magnus Jodal and contributors. Mopidy is licensed under the `Apache License, Version 2.0 `_. The following persons have contributed to Mopidy. The list is in the order of first contribution. For details on who have contributed what, please refer to our Git repository. .. include:: ../AUTHORS If want to help us making Mopidy better, the best way to do so is to contribute back to the community, either through code, documentation, tests, bug reports, or by helping other users, spreading the word, etc. See :ref:`contributing` for a head start. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/changelog.rst0000644000175100001710000003222400000000000015731 0ustar00runnerdocker.. _changelog: ********* Changelog ********* This changelog is used to track all major changes to Mopidy. For older releases, see :ref:`history`. v3.2.0 (2021-07-08) =================== - Initial type annotations and mypy support. (PR: :issue:`1842`) - Move CI to GitHub Actions (PR: :issue:`1951`) - Fix logging during extension loading (Fixes: :issue:`1958`, PR: :issue:`1960`) - Fix appsrc track change after live-mode previously set. (Fixes: :issue:`1969`, PR: :issue:`1971`) v3.1.1 (2020-12-26) =================== - Fix crash when extracting tags using gst-python >= 1.18. (PR: :issue:`1948`) v3.1.0 (2020-12-16) =================== - Add Python 3.9 to our test matrix. - Add :meth:`mopidy.backend.PlaybackProvider.should_download` which can be implemented by playback providers that want to use GStreamer's download buffering strategy for their URIs. (PR: :issue:`1888`) - Audio: Fix memory leak when converting GStreamer ``sample`` type tags. (Fixes: :issue:`1827`, PR: :issue:`1929`) - Turn off strict parsing of ``*.pls`` playlist files. This was a regression that happened during the migration to Python 3. (PR: :issue:`1923`) - Make the systemd unit that ships with Mopidy wait for an Internet connection before starting Mopidy. When used by distribution packages, this can help avoid that extensions try to connect to cloud services before the machine's Internet connection is ready for use. (PR: :issue:`1946`) v3.0.2 (2020-04-02) =================== Bugfix release. - Core: Reset stream title on receipt of any ``title`` audio tag change. (Fixes: :issue:`1871`, PR: :issue:`1875`) - Core: Hide the methods :meth:`mopidy.core.Core.setup` and :meth:`mopidy.core.Core.teardown` from other actors and JSON-RPC API clients. The methods have always been clearly documented as internal. (PR: :issue:`1865`) - Config: Log a warning if unknown config sections are found. (Fixes: :issue:`1878`, PR: :issue:`1890`) - Config: Fix crash when reading values from keyring. (PR: :issue:`1887`) - Various documentation updates. v3.0.1 (2019-12-22) =================== Bugfix release. - Remove :mod:`mopidy.local` migration helper. (Fixes: :issue:`1861`, PR: :issue:`1862`) v3.0.0 (2019-12-22) =================== The long-awaited Mopidy 3.0 is finally here, just in time for the Mopidy project's 10th anniversary on December 23rd! Mopidy 3.0 is a backward-incompatible release in a pretty significant way: Mopidy no longer runs on Python 2. **Mopidy 3.0 requires Python 3.7 or newer.** While extensions have been able to continue working without changes throughout the 1.x and 2.x series of Mopidy, this time is different: - All extensions must be updated to work on Python 3.7 and newer. - Some extensions need to replace their use of a few long-deprecated APIs that we've removed. See below for details. - Extension maintainers are also encouraged to update their project's setup to match our refreshed `extension cookiecutter`_. In parallel with the development of Mopidy 3.0, we've coordinated with a few extension maintainers and upgraded almost 20 of the most popular extensions. These will all be published shortly after the release of Mopidy 3.0. We've also built a new `extension registry`_, where you can quickly track what extensions are ready for Python 3. In other news, the `Mopidy-MPD`_ and `Mopidy-Local`_ extensions have grown up and moved out to flourish as independent extension projects. After the move, Mopidy-Local merged with Mopidy-Local-SQLite and Mopidy-Local-Images, which are now both a part of the Mopidy-Local extension. .. _extension cookiecutter: https://github.com/mopidy/cookiecutter-mopidy-ext .. _extension registry: https://mopidy.com/ext/ .. _Mopidy-MPD: https://mopidy.com/ext/mpd/ .. _Mopidy-Local: https://mopidy.com/ext/local/ Dependencies ------------ - Python >= 3.7 is now required. Python 2.7 is no longer supported. - GStreamer >= 1.14.0 is now required. - Pykka >= 2.0.1 is now required. - Tornado >= 4.4 is now required. The upper boundary (< 6) has been removed. - We now use a number of constants and functions from ``GLib`` instead of their deprecated equivalents in ``GObject``. The exact version of PyGObject and GLib that makes these constants and functions available in the new location is not known, but is believed to have been released in 2015 or earlier. Logging ------- - The command line option ``mopidy --save-debug-log`` and the configuration :confval:`logging/debug_file` have been removed. To save a debug log for sharing, run ``mopidy -vvvv 2>&1 | tee mopidy.log`` or equivalent. (Fixes: :issue:`1452`, PR: :issue:`1783`) - Replaced the configurations :confval:`logging/console_format` and :confval:`logging/debug_format` with the single configuration :confval:`logging/format`. It defaults to the same format as the old debug format. (Fixes: :issue:`1452`, PR: :issue:`1783`) - Added configuration :confval:`logging/verbosity` to be able to control logging verbosity from the configuration file, in addition to passing ``-q`` or ``-v`` on the command line. (Fixes: :issue:`1452`, PR: :issue:`1783`) Core API -------- - Removed properties, methods, and arguments that have been deprecated since 1.0, released in 2015. Everything removed already has a replacement, that should be used instead. See below for a full list of removals and replacements. (Fixes: :issue:`1083`, :issue:`1461`, PR: :issue:`1768`, :issue:`1769`) Root object ^^^^^^^^^^^ - Removed properties, use getter/setter instead: - :attr:`mopidy.core.Core.uri_schemes` - :attr:`mopidy.core.Core.version` Library controller ^^^^^^^^^^^^^^^^^^ - Removed methods: - :meth:`mopidy.core.LibraryController.find_exact`: Use :meth:`~mopidy.core.LibraryController.search` with the keyword argument ``exact=True`` instead. - Removed the ``uri`` argument to :meth:`mopidy.core.LibraryController.lookup`. Use the ``uris`` argument instead. - Removed the support for passing the search query as keyword arguments to :meth:`mopidy.core.LibraryController.search`. Use the ``query`` argument instead. - :meth:`mopidy.core.LibraryController.search` now returns an empty result if there is no ``query``. Previously, it returned the full music library. This is not feasible for online music services and has thus been deprecated since 1.0. Playback controller ^^^^^^^^^^^^^^^^^^^ - Removed properties, use getter/setter instead: - :attr:`mopidy.core.PlaybackController.current_tl_track` - :attr:`mopidy.core.PlaybackController.current_track` - :attr:`mopidy.core.PlaybackController.state` - :attr:`mopidy.core.PlaybackController.time_position` - Moved to the mixer controller: - :meth:`mopidy.core.PlaybackController.get_mute`: Use :meth:`~mopidy.core.MixerController.get_mute`. - :meth:`mopidy.core.PlaybackController.get_volume`: Use :meth:`~mopidy.core.MixerController.get_volume`. - :meth:`mopidy.core.PlaybackController.set_mute`: Use :meth:`~mopidy.core.MixerController.set_mute`. - :meth:`mopidy.core.PlaybackController.set_volume`: Use :meth:`~mopidy.core.MixerController.set_volume`. - :attr:`mopidy.core.PlaybackController.mute`: Use :meth:`~mopidy.core.MixerController.get_mute` and :meth:`~mopidy.core.MixerController.set_mute`. - :attr:`mopidy.core.PlaybackController.volume`: Use :meth:`~mopidy.core.MixerController.get_volume` and :meth:`~mopidy.core.MixerController.set_volume`. - Deprecated the ``tl_track`` argument to :meth:`mopidy.core.PlaybackController.play`, with the goal of removing it in the next major release. Use the ``tlid`` argument instead. (Fixes: :issue:`1773`, PR: :issue:`1786`, :issue:`1854`) Playlist controller ^^^^^^^^^^^^^^^^^^^ - Removed properties, use getter/setter instead: - :attr:`mopidy.core.PlaylistController.playlists` - Removed methods: - :meth:`mopidy.core.PlaylistsController.filter`: Use :meth:`~mopidy.core.PlaylistsController.as_list` and filter yourself. - :meth:`mopidy.core.PlaylistsController.get_playlists`: Use :meth:`~mopidy.core.PlaylistsController.as_list` and :meth:`~mopidy.core.PlaylistsController.get_items`. Tracklist controller ^^^^^^^^^^^^^^^^^^^^ - Removed properties, use getter/setter instead: - :attr:`mopidy.core.TracklistController.tl_tracks` - :attr:`mopidy.core.TracklistController.tracks` - :attr:`mopidy.core.TracklistController.length` - :attr:`mopidy.core.TracklistController.version` - :attr:`mopidy.core.TracklistController.consume` - :attr:`mopidy.core.TracklistController.random` - :attr:`mopidy.core.TracklistController.repeat` - :attr:`mopidy.core.TracklistController.single` - Removed the ``uri`` argument to :meth:`mopidy.core.TracklistController.add`. Use the ``uris`` argument instead. - Removed the support for passing filter criteria as keyword arguments to :meth:`mopidy.core.TracklistController.filter`. Use the ``criteria`` argument instead. - Removed the support for passing filter criteria as keyword arguments to :meth:`mopidy.core.TracklistController.remove`. Use the ``criteria`` argument instead. - Deprecated methods, with the goal of removing them in the next major release: (Fixes: :issue:`1773`, PR: :issue:`1786`, :issue:`1854`) - :meth:`mopidy.core.TracklistController.eot_track`. Use :meth:`~mopidy.core.TracklistController.get_eot_tlid` instead. - :meth:`mopidy.core.TracklistController.next_track`. Use :meth:`~mopidy.core.TracklistController.get_next_tlid` instead. - :meth:`mopidy.core.TracklistController.previous_track`. Use :meth:`~mopidy.core.TracklistController.get_previous_tlid` instead. - The ``tracks`` argument to :meth:`mopidy.core.TracklistController.add` has been deprecated since Mopidy 1.0. It is still deprecated, with the goal of removing it in the next major release. Use the ``uris`` argument instead. Backend API ----------- - Add :meth:`mopidy.backend.PlaybackProvider.is_live` which can be implemented by playback providers that want to mark their URIs as live streams that should not be buffered. (PR: :issue:`1845`) Models ------ - Remove ``.copy()`` method on all model classes. Use the ``.replace()`` method instead. (Fixes: :issue:`1464`, PR: :issue:`1774`) - Remove :attr:`mopidy.models.Album.images`. Clients should use :meth:`mopidy.core.LibraryController.get_images` instead. Backends should implement :meth:`mopidy.backend.LibraryProvider.get_images`. (Fixes: :issue:`1464`, PR: :issue:`1774`) Extension support ----------------- - The following methods now return :class:`pathlib.Path` objects instead of strings: - :meth:`mopidy.ext.Extension.get_cache_dir` - :meth:`mopidy.ext.Extension.get_config_dir` - :meth:`mopidy.ext.Extension.get_data_dir` This makes it easier to support arbitrary encoding in file names. - The command :command:`mopidy deps` no longer repeats the dependencies of Mopidy itself for every installed extension. This reduces the length of the command's output drastically. (PR: :issue:`1846`) HTTP frontend ------------- - Stop bundling Mopidy.js and serving it at ``/mopidy/mopidy.js`` and ``/mopidy/mopidy.min.js``. All Mopidy web clients must use Mopidy.js from npm or vendor their own copy of the library. (Fixes: :issue:`1083`, :issue:`1460`, PR: :issue:`1708`) - Remove support for serving arbitrary files over HTTP through the use of :confval:`http/static_dir`, which has been deprecated since 1.0. (Fixes: :issue:`1463`, PR: :issue:`1706`) - Add option :confval:`http/default_app` to redirect from web server root to a specific app instead of Mopidy's web app list. (PR: :issue:`1791`) - Add cookie secret to Tornado web server, allowing Tornado request handlers to call ``get_secure_cookie()``, in an implementation of ``get_current_user()``. (PR: :issue:`1801`) MPD frontend ------------ - The Mopidy-MPD frontend is no longer bundled with Mopidy, and has been moved to its own `Git repo `__ and `PyPI project `__. Local backend ------------- - The Mopidy-Local backend is no longer bundled with Mopidy, and has been moved to its own `Git repo `__ and `PyPI project `__. (Fixes: :issue:`1003`) - Removed :exc:`mopidy.exceptions.FindError`, as it was only used by Mopidy-Local. (PR: :issue:`1857`) Audio ----- - Remove the method :meth:`mopidy.audio.Audio.emit_end_of_stream`, which has been deprecated since 1.0. (Fixes: :issue:`1465`, PR: :issue:`1705`) - Add ``live_stream`` option to :meth:`mopidy.audio.Audio.set_uri` that disables buffering, which reduces latency before playback starts, and discards data when paused. (PR: :issue:`1845`) Internals --------- - Format code with Black. (PR: :issue:`1834`) - Port test assertions from ``unittest`` methods to pytest ``assert`` statements. (PR: :issue:`1838`) - Switch all internal path handling to use :mod:`pathlib`. (Fixes: :issue:`1744`, PR: :issue:`1814`) - Remove :mod:`mopidy.compat` and all Python 2/3 compatibility code. (PR: :issue:`1833`, :issue:`1835`) - Replace ``requirements.txt`` and ``setup.py`` with declarative config in ``setup.cfg``. (PR: :issue:`1839`) - Refreshed and updated all of our end user-oriented documentation. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/clients.rst0000644000175100001710000000517600000000000015451 0ustar00runnerdocker.. _clients: ******* Clients ******* Once Mopidy is up and running, you need a client to control it. Note that clients only *control* Mopidy. The audio itself is not streamed to the clients, but it is played on the computer running Mopidy. This is by design, as Mopidy was originally modelled after MPD. If you want to stream audio from Mopidy to another device, the primary options are :ref:`icecast` and `Snapcast`_. The most popular ways to control Mopidy are with web clients and with MPD clients. In addition, alternative frontends like `Mopidy-MPRIS`_ and `Mopidy-Raspberry-GPIO`_ provides additional ways to control Mopidy. Alternative frontends that use a server-client architecture usually list relevant clients in the extension's documentation. .. _Mopidy-MPD: https://mopidy.com/ext/mpd/ .. _Mopidy-MPRIS: https://mopidy.com/ext/mpris/ .. _Mopidy-Raspberry-GPIO: https://mopidy.com/ext/raspberry-gpio/ .. _Snapcast: https://github.com/badaix/snapcast .. _web-clients: Web clients =========== There are many clients available that use :ref:`ext-http` to control Mopidy. Web extensions -------------- Mopidy extensions can make additional web APIs available through Mopidy's builtin web server by implementing the :ref:`http-server-api`. Web clients can use the :ref:`http-api` to control Mopidy from JavaScript. See the `Mopidy extension registry `_ to find a number of web clients can be easily installed as Mopidy extensions. Non-extension web clients ------------------------- There are a few Mopidy web clients that are not installable as Mopidy extensions: - `Apollo Player `_ - `Mopster `_ Web-based MPD clients --------------------- Lastly, there are several web based MPD clients, which doesn't use the :ref:`ext-http` frontend at all, but connect to Mopidy through the Mopidy-MPD frontend. For a list of those, see the "Web clients" section of the `MPD wiki's clients list `_. .. _mpd-clients: MPD clients =========== MPD is the protocol used by the original MPD server project since 2003. The `Mopidy-MPD`_ extension provides a server that implements the same protocol, and is compatible with most MPD clients. There are dozens of MPD clients available. Please refer to the `Mopidy-MPD`_ extension's documentation for an overview. .. _mpris-clients: MPRIS clients ============= MPRIS is a specification that describes a standard D-Bus interface for making media players available to other applications on the same system. See the `Mopidy-MPRIS`_ documentation for a survey of some MPRIS clients. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/codestyle.rst0000644000175100001710000000140400000000000015771 0ustar00runnerdocker.. _codestyle: ********** Code style ********** All projects in the Mopidy organization follows the following code style: - Automatically format all code with `Black `_. Use Black's string normalization, which prefers ``"`` quotes over ``'``, unless the string contains ``"``. - Automatically sort imports using `isort `_. - Follow :pep:`8`. Run `flake8 `_ to check your code against the guidelines. The strict adherence to Black and flake8 are enforced by our CI setup. Pull requests that do not pass these checks will not be merged. For more general advise, take a look at :pep:`20` for a nice peek into a general mindset useful for Python coding. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1625703630.0 Mopidy-3.2.0/docs/command.rst0000644000175100001710000000572400000000000015425 0ustar00runnerdocker.. _mopidy-cmd: ************** mopidy command ************** Synopsis ======== mopidy [-h] [--version] [-q] [-v] [--config CONFIG_FILES] [-o CONFIG_OVERRIDES] [COMMAND] ... Description =========== Mopidy is a music server which can play music both from multiple sources, like your local hard drive, radio streams, and from Spotify and SoundCloud. Searches combines results from all music sources, and you can mix tracks from all sources in your play queue. Your playlists from Spotify or SoundCloud are also available for use. The ``mopidy`` command is used to start the server. Options ======= .. program:: mopidy .. cmdoption:: --help, -h Show help message and exit. .. cmdoption:: --version Show Mopidy's version number and exit. .. cmdoption:: --quiet, -q Show less output: warning level and higher. .. cmdoption:: --verbose, -v Show more output. Repeat up to four times for even more. .. cmdoption:: --config Specify config files and directories to use. To use multiple config files or directories, separate them with a colon. The later files override the earlier ones if there's a conflict. When specifying a directory, all files ending in .conf in the directory are used. .. cmdoption:: --option