Mopidy-3.0.1/0000775000175000017500000000000013577726323013201 5ustar jodaljodal00000000000000Mopidy-3.0.1/.circleci/0000775000175000017500000000000013577726323015034 5ustar jodaljodal00000000000000Mopidy-3.0.1/.circleci/config.yml0000664000175000017500000000213213577711652017021 0ustar jodaljodal00000000000000version: 2.1 orbs: codecov: codecov/codecov@1.0.5 workflows: version: 2 test: jobs: - py38 - py37 - black - check-manifest - docs - flake8 jobs: py38: &test-template docker: - image: mopidy/ci-python:3.8 steps: - checkout - restore_cache: name: Restoring tox cache key: tox-v1-{{ .Environment.CIRCLE_JOB }}-{{ checksum "setup.cfg" }} - run: name: Run tests command: | tox -e $CIRCLE_JOB -- \ --junit-xml=test-results/pytest/results.xml \ --cov-report=xml - save_cache: name: Saving tox cache key: tox-v1-{{ .Environment.CIRCLE_JOB }}-{{ checksum "setup.cfg" }} paths: - ./.tox - ~/.cache/pip - codecov/upload: file: coverage.xml - store_test_results: path: test-results py37: <<: *test-template docker: - image: mopidy/ci-python:3.7 black: *test-template check-manifest: *test-template docs: *test-template flake8: *test-template Mopidy-3.0.1/.github/0000775000175000017500000000000013577726323014541 5ustar jodaljodal00000000000000Mopidy-3.0.1/.github/ISSUE_TEMPLATE.md0000664000175000017500000000025113535461505017234 0ustar jodaljodal00000000000000Please use https://discourse.mopidy.com/ for support questions. GitHub Issues should only be used for confirmed problems with Mopidy and well-defined feature requests. Mopidy-3.0.1/.mailmap0000664000175000017500000000450413577711652014624 0ustar jodaljodal00000000000000Thomas 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 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 Mopidy-3.0.1/.readthedocs.yml0000664000175000017500000000031413577711652016264 0ustar jodaljodal00000000000000version: 2 python: version: 3.7 install: - method: pip path: . extra_requirements: - docs sphinx: builder: htmldir configuration: docs/conf.py formats: - pdf - epub Mopidy-3.0.1/AUTHORS0000664000175000017500000001126513577711652014255 0ustar jodaljodal00000000000000- 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 Mopidy-3.0.1/AUTHORS.update0000775000175000017500000000027113577711652015534 0ustar jodaljodal00000000000000#!/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 Mopidy-3.0.1/LICENSE0000664000175000017500000002613613535461505014206 0ustar jodaljodal00000000000000 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. Mopidy-3.0.1/MANIFEST.in0000664000175000017500000000072113577711652014736 0ustar jodaljodal00000000000000include *.py include *.rst include .mailmap include .readthedocs.yml include AUTHORS include AUTHORS.update include LICENSE include MANIFEST.in include pyproject.toml include tox.ini recursive-include .circleci * 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 * Mopidy-3.0.1/Mopidy.egg-info/0000775000175000017500000000000013577726323016134 5ustar jodaljodal00000000000000Mopidy-3.0.1/Mopidy.egg-info/PKG-INFO0000664000175000017500000001245213577726323017235 0ustar jodaljodal00000000000000Metadata-Version: 2.1 Name: Mopidy Version: 3.0.1 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 Description: ****** 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/circleci/project/github/mopidy/mopidy/develop.svg :target: https://circleci.com/gh/mopidy/mopidy :alt: CircleCI 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 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: Topic :: Multimedia :: Sound/Audio :: Players Requires-Python: >=3.7 Provides-Extra: docs Provides-Extra: lint Provides-Extra: release Provides-Extra: test Provides-Extra: dev Mopidy-3.0.1/Mopidy.egg-info/SOURCES.txt0000664000175000017500000001504313577726323020023 0ustar jodaljodal00000000000000.mailmap .readthedocs.yml AUTHORS AUTHORS.update LICENSE MANIFEST.in README.rst pyproject.toml setup.cfg setup.py tox.ini .circleci/config.yml .github/ISSUE_TEMPLATE.md 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/index.rst docs/installation/macos.rst docs/installation/pypi.rst docs/installation/raspberrypi.rst docs/installation/raspberrypi2.jpg 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/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.pyMopidy-3.0.1/Mopidy.egg-info/dependency_links.txt0000664000175000017500000000000113577726323022202 0ustar jodaljodal00000000000000 Mopidy-3.0.1/Mopidy.egg-info/entry_points.txt0000664000175000017500000000034413577726323021433 0ustar jodaljodal00000000000000[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 Mopidy-3.0.1/Mopidy.egg-info/not-zip-safe0000664000175000017500000000000113535462267020360 0ustar jodaljodal00000000000000 Mopidy-3.0.1/Mopidy.egg-info/requires.txt0000664000175000017500000000065313577726323020540 0ustar jodaljodal00000000000000Pykka>=2.0.1 requests>=2.0 setuptools tornado>=4.4 [dev] pygraphviz sphinx sphinx_rtd_theme black check-manifest flake8 flake8-bugbear flake8-import-order isort[pyproject] pep8-naming twine wheel pytest pytest-cov responses [docs] pygraphviz sphinx sphinx_rtd_theme [lint] black check-manifest flake8 flake8-bugbear flake8-import-order isort[pyproject] pep8-naming [release] twine wheel [test] pytest pytest-cov responses Mopidy-3.0.1/Mopidy.egg-info/top_level.txt0000664000175000017500000000000713577726323020663 0ustar jodaljodal00000000000000mopidy Mopidy-3.0.1/PKG-INFO0000664000175000017500000001245213577726323014302 0ustar jodaljodal00000000000000Metadata-Version: 2.1 Name: Mopidy Version: 3.0.1 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 Description: ****** 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/circleci/project/github/mopidy/mopidy/develop.svg :target: https://circleci.com/gh/mopidy/mopidy :alt: CircleCI 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 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: Topic :: Multimedia :: Sound/Audio :: Players Requires-Python: >=3.7 Provides-Extra: docs Provides-Extra: lint Provides-Extra: release Provides-Extra: test Provides-Extra: dev Mopidy-3.0.1/README.rst0000664000175000017500000000661413577711652014676 0ustar jodaljodal00000000000000****** 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/circleci/project/github/mopidy/mopidy/develop.svg :target: https://circleci.com/gh/mopidy/mopidy :alt: CircleCI 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 Mopidy-3.0.1/docs/0000775000175000017500000000000013577726323014131 5ustar jodaljodal00000000000000Mopidy-3.0.1/docs/Makefile0000664000175000017500000001075613535461505015572 0ustar jodaljodal00000000000000# 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." Mopidy-3.0.1/docs/_static/0000775000175000017500000000000013577726323015557 5ustar jodaljodal00000000000000Mopidy-3.0.1/docs/_static/mopidy.png0000664000175000017500000000646613535461505017572 0ustar jodaljodal00000000000000PNG  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`Mopidy-3.0.1/docs/api/0000775000175000017500000000000013577726323014702 5ustar jodaljodal00000000000000Mopidy-3.0.1/docs/api/architecture.rst0000664000175000017500000000704113535461505020110 0ustar jodaljodal00000000000000.. _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. Mopidy-3.0.1/docs/api/audio.rst0000664000175000017500000000205213535461505016524 0ustar jodaljodal00000000000000.. _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: Mopidy-3.0.1/docs/api/backend.rst0000664000175000017500000000700713577711652017026 0ustar jodaljodal00000000000000.. _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. 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 `_. Mopidy-3.0.1/docs/api/commands.rst0000664000175000017500000000034613535461505017230 0ustar jodaljodal00000000000000.. _commands-api: *************************************** :mod:`mopidy.commands` --- Commands API *************************************** .. automodule:: mopidy.commands :synopsis: Commands API for Mopidy CLI. :members: Mopidy-3.0.1/docs/api/config.rst0000664000175000017500000000122513535461505016671 0ustar jodaljodal00000000000000.. _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: Mopidy-3.0.1/docs/api/core.rst0000664000175000017500000001345413577711652016372 0ustar jodaljodal00000000000000.. _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_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: Mopidy-3.0.1/docs/api/ext.rst0000664000175000017500000000044213535461505016224 0ustar jodaljodal00000000000000.. _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: Mopidy-3.0.1/docs/api/frontend.rst0000664000175000017500000000312013577711652017246 0ustar jodaljodal00000000000000.. _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 `_. Mopidy-3.0.1/docs/api/http-server.rst0000664000175000017500000001375713577711652017733 0ustar jodaljodal00000000000000.. _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 `_. Mopidy-3.0.1/docs/api/http.rst0000664000175000017500000000707713577711652016425 0ustar jodaljodal00000000000000.. _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": {...}} Mopidy-3.0.1/docs/api/httpclient.rst0000664000175000017500000000043213535461505017601 0ustar jodaljodal00000000000000.. _httpclient-helper: ************************************************ :mod:`mopidy.httpclient` --- HTTP Client helpers ************************************************ .. automodule:: mopidy.httpclient :synopsis: HTTP Client helpers for Mopidy its Extensions. :members: Mopidy-3.0.1/docs/api/index.rst0000664000175000017500000000077113535461505016540 0ustar jodaljodal00000000000000.. _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 Mopidy-3.0.1/docs/api/js.rst0000664000175000017500000000103513577711652016046 0ustar jodaljodal00000000000000.. _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. Mopidy-3.0.1/docs/api/mixer.rst0000664000175000017500000000062713577711652016564 0ustar jodaljodal00000000000000.. _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 `_. Mopidy-3.0.1/docs/api/models.rst0000664000175000017500000000563213535461505016715 0ustar jodaljodal00000000000000************************************ :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 Mopidy-3.0.1/docs/api/zeroconf.rst0000664000175000017500000000041413535461505017250 0ustar jodaljodal00000000000000.. _zeroconf-api: *************************************** :mod:`mopidy.zeroconf` --- Zeroconf API *************************************** .. module:: mopidy.zeroconf :synopsis: Helper for publishing of services on Zeroconf .. autoclass:: Zeroconf :members: Mopidy-3.0.1/docs/audiosinks.rst0000664000175000017500000000252313577711652017035 0ustar jodaljodal00000000000000.. _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 Mopidy-3.0.1/docs/authors.rst0000664000175000017500000000123413535461505016340 0ustar jodaljodal00000000000000.. _authors: ******* Authors ******* Mopidy is copyright 2009-2019 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. Mopidy-3.0.1/docs/changelog.rst0000664000175000017500000002633613577726300016617 0ustar jodaljodal00000000000000.. _changelog: ********* Changelog ********* This changelog is used to track all major changes to Mopidy. For older releases, see :ref:`history`. v3.0.1 (2019-12-22) =================== Bugfix release. - Remove :mod:`mopidy.local` migration helper. (Fixes: :issue:`1861`, PR: `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 does not work with online music services, and have 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: #1773, PR: #1786, #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: #1773, PR: #1786, #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 wants 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`) - The :exc:`mopidy.exceptions.FindError` has been removed, 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. Mopidy-3.0.1/docs/clients.rst0000664000175000017500000000517613577711652016334 0ustar jodaljodal00000000000000.. _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. Mopidy-3.0.1/docs/codestyle.rst0000664000175000017500000000125313577711652016656 0ustar jodaljodal00000000000000.. _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 ``"``. - 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. Mopidy-3.0.1/docs/command.rst0000664000175000017500000000572413577711652016310 0ustar jodaljodal00000000000000.. _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