Mopidy-SomaFM-2.0.0rc1/0000755000175000017510000000000013571702175016441 5ustar alexandrealexandre00000000000000Mopidy-SomaFM-2.0.0rc1/.circleci/0000755000175000017510000000000013571702175020274 5ustar alexandrealexandre00000000000000Mopidy-SomaFM-2.0.0rc1/.circleci/config.yml0000644000175000017510000000206513571702147022266 0ustar alexandrealexandre00000000000000version: 2.1 orbs: codecov: codecov/codecov@1.0.5 workflows: version: 2 test: jobs: - py38 - py37 - black - check-manifest - 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 flake8: *test-template Mopidy-SomaFM-2.0.0rc1/CHANGES.rst0000644000175000017510000000304713571702147020246 0ustar alexandrealexandre00000000000000Changelog ========= v2.0.0rc1 (2019-12-04) ---------------------- - #32 Migrate to Python 3.7 v1.1.0 (2017-10-14) ------------------- - #24: Graceful fallback - #28: Various fix (DJ as artist, station ordering) v1.0.1 (2016-01-19) ------------------- - Use httpclient helper from Mopidy >= 1.1 v0.8.0 (2015-11-09) ------------------- - #20: Replace HTTP with HTTPS for channels.xml v0.7.1 (2015-01-04) ------------------- - #11: Add Low Bitrate encoding (aacp) v0.7.0 (2014-07-29) ------------------- - #10: Remove playlists provider v0.6.0 (2014-03-15) ------------------- - Directly show PLS in browser - Add precision about 'quality' and 'encoding' couple v0.5.1 (2014-03-09) ------------------- - Fix doc typo v0.5.0 (2014-03-03) ------------------- - #5: Select prefered quality and format from config - Add tests and Travis-CI support v0.4.0 (2014-02-16) ------------------- - Add browse support for LibraryController v0.3.1 (2014-01-30) ------------------- - #3: Correct wrong subclassing v0.3.0 (2014-01-29) ------------------- - Require Mopidy >= 0.18 - Add proxy support for downloading SomaFM content - #1: handle 'requests' exceptions - Use builtin Mopidy's .pls support - Internal code cleanup v0.2.0 (2013-09-22) ------------------- - PLS files are downloaded to local temp directory - Implement library::lookup to allow adding tracks from playlist uri v0.1.1 (2013-09-14) ------------------- - Update Licence information v0.1.0 (2013-09-13) ------------------- - Initial release - Create SomaFM extension for Mopidy Mopidy-SomaFM-2.0.0rc1/LICENSE0000644000175000017510000000207613571702147017452 0ustar alexandrealexandre00000000000000The MIT License (MIT) Copyright (c) 2019 Alexandre Petitjean Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Mopidy-SomaFM-2.0.0rc1/MANIFEST.in0000644000175000017510000000041213571702147020173 0ustar alexandrealexandre00000000000000include *.py include *.rst include .mailmap include LICENSE include MANIFEST.in include pyproject.toml include tox.ini recursive-include .circleci * recursive-include .github * include mopidy_*/ext.conf recursive-include tests *.py recursive-include tests/data * Mopidy-SomaFM-2.0.0rc1/Mopidy_SomaFM.egg-info/0000755000175000017510000000000013571702175022576 5ustar alexandrealexandre00000000000000Mopidy-SomaFM-2.0.0rc1/Mopidy_SomaFM.egg-info/PKG-INFO0000644000175000017510000000654513571702175023705 0ustar alexandrealexandre00000000000000Metadata-Version: 2.1 Name: Mopidy-SomaFM Version: 2.0.0rc1 Summary: SomaFM extension for Mopidy Home-page: https://github.com/AlexandrePTJ/mopidy-somafm Author: Alexandre Petitjean Author-email: alpetitjean@gmail.com License: Apache License, Version 2.0 Description: ************* Mopidy-SomaFM ************* .. image:: https://img.shields.io/pypi/v/Mopidy-SomaFM :target: https://pypi.org/project/Mopidy-SomaFM/ :alt: Latest PyPI version .. image:: https://img.shields.io/circleci/build/gh/AlexandrePTJ/mopidy-somafm :target: https://circleci.com/gh/AlexandrePTJ/mopidy-somafm :alt: CircleCI build status .. image:: https://img.shields.io/codecov/c/gh/AlexandrePTJ/mopidy-somafm :target: https://codecov.io/gh/AlexandrePTJ/mopidy-somafm :alt: Test coverage SomaFM extension for Mopidy Installation ============ Debian/Ubuntu ------------- Install by running:: python3 -m pip install Mopidy-SomaFM Or, if available, install the Debian/Ubuntu package from `apt.mopidy.com `_. Configuration ============= Before starting Mopidy, you must add configuration for Mopidy-SomaFM to your Mopidy configuration file:: [somafm] encoding = aac quality = highest - ``encoding`` must be either ``aac``, ``mp3`` or ``aacp`` - ``quality`` must be one of ``highest``, ``fast``, ``slow``, ``firewall`` If the preferred quality is not available for a channel, the extension will fallback to ``fast``. And afterwards if the preferred encoding is not available for that quality, it will fallback to using ``mp3``. It seems that all channels support the combination ``fast`` + ``mp3`` You can also choose to use the channel DJ as the reported track artist (default behavior):: [somafm] dj_as_artist = true Project resources ================= - `Source code `_ - `Issue tracker `_ - `Changelog `_ Credits ======= - Original author: `Alexandre Petitjean `__ - Current maintainer: `Alexandre Petitjean `__ - `Contributors `_ Platform: UNKNOWN Classifier: Environment :: No Input/Output (Daemon) Classifier: Intended Audience :: End Users/Desktop Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: OS Independent 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: lint Provides-Extra: release Provides-Extra: test Provides-Extra: dev Mopidy-SomaFM-2.0.0rc1/Mopidy_SomaFM.egg-info/SOURCES.txt0000644000175000017510000000101613571702175024460 0ustar alexandrealexandre00000000000000CHANGES.rst LICENSE MANIFEST.in README.rst pyproject.toml setup.cfg setup.py tox.ini .circleci/config.yml Mopidy_SomaFM.egg-info/PKG-INFO Mopidy_SomaFM.egg-info/SOURCES.txt Mopidy_SomaFM.egg-info/dependency_links.txt Mopidy_SomaFM.egg-info/entry_points.txt Mopidy_SomaFM.egg-info/not-zip-safe Mopidy_SomaFM.egg-info/requires.txt Mopidy_SomaFM.egg-info/top_level.txt mopidy_somafm/__init__.py mopidy_somafm/backend.py mopidy_somafm/ext.conf mopidy_somafm/somafm.py tests/__init__.py tests/test_extension.py tests/test_somafm.pyMopidy-SomaFM-2.0.0rc1/Mopidy_SomaFM.egg-info/dependency_links.txt0000644000175000017510000000000113571702175026644 0ustar alexandrealexandre00000000000000 Mopidy-SomaFM-2.0.0rc1/Mopidy_SomaFM.egg-info/entry_points.txt0000644000175000017510000000005713571702175026076 0ustar alexandrealexandre00000000000000[mopidy.ext] somafm = mopidy_somafm:Extension Mopidy-SomaFM-2.0.0rc1/Mopidy_SomaFM.egg-info/not-zip-safe0000644000175000017510000000000113571666354025034 0ustar alexandrealexandre00000000000000 Mopidy-SomaFM-2.0.0rc1/Mopidy_SomaFM.egg-info/requires.txt0000644000175000017510000000046613571702175025204 0ustar alexandrealexandre00000000000000Mopidy>=3.0.0a4 Pykka>=2.0.1 requests>=2.0.0 setuptools [dev] black check-manifest flake8 flake8-bugbear flake8-import-order isort[pyproject] twine wheel pytest pytest-cov [lint] black check-manifest flake8 flake8-bugbear flake8-import-order isort[pyproject] [release] twine wheel [test] pytest pytest-cov Mopidy-SomaFM-2.0.0rc1/Mopidy_SomaFM.egg-info/top_level.txt0000644000175000017510000000001613571702175025325 0ustar alexandrealexandre00000000000000mopidy_somafm Mopidy-SomaFM-2.0.0rc1/PKG-INFO0000644000175000017510000000654513571702175017550 0ustar alexandrealexandre00000000000000Metadata-Version: 2.1 Name: Mopidy-SomaFM Version: 2.0.0rc1 Summary: SomaFM extension for Mopidy Home-page: https://github.com/AlexandrePTJ/mopidy-somafm Author: Alexandre Petitjean Author-email: alpetitjean@gmail.com License: Apache License, Version 2.0 Description: ************* Mopidy-SomaFM ************* .. image:: https://img.shields.io/pypi/v/Mopidy-SomaFM :target: https://pypi.org/project/Mopidy-SomaFM/ :alt: Latest PyPI version .. image:: https://img.shields.io/circleci/build/gh/AlexandrePTJ/mopidy-somafm :target: https://circleci.com/gh/AlexandrePTJ/mopidy-somafm :alt: CircleCI build status .. image:: https://img.shields.io/codecov/c/gh/AlexandrePTJ/mopidy-somafm :target: https://codecov.io/gh/AlexandrePTJ/mopidy-somafm :alt: Test coverage SomaFM extension for Mopidy Installation ============ Debian/Ubuntu ------------- Install by running:: python3 -m pip install Mopidy-SomaFM Or, if available, install the Debian/Ubuntu package from `apt.mopidy.com `_. Configuration ============= Before starting Mopidy, you must add configuration for Mopidy-SomaFM to your Mopidy configuration file:: [somafm] encoding = aac quality = highest - ``encoding`` must be either ``aac``, ``mp3`` or ``aacp`` - ``quality`` must be one of ``highest``, ``fast``, ``slow``, ``firewall`` If the preferred quality is not available for a channel, the extension will fallback to ``fast``. And afterwards if the preferred encoding is not available for that quality, it will fallback to using ``mp3``. It seems that all channels support the combination ``fast`` + ``mp3`` You can also choose to use the channel DJ as the reported track artist (default behavior):: [somafm] dj_as_artist = true Project resources ================= - `Source code `_ - `Issue tracker `_ - `Changelog `_ Credits ======= - Original author: `Alexandre Petitjean `__ - Current maintainer: `Alexandre Petitjean `__ - `Contributors `_ Platform: UNKNOWN Classifier: Environment :: No Input/Output (Daemon) Classifier: Intended Audience :: End Users/Desktop Classifier: License :: OSI Approved :: Apache Software License Classifier: Operating System :: OS Independent 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: lint Provides-Extra: release Provides-Extra: test Provides-Extra: dev Mopidy-SomaFM-2.0.0rc1/README.rst0000644000175000017510000000376613571702147020143 0ustar alexandrealexandre00000000000000************* Mopidy-SomaFM ************* .. image:: https://img.shields.io/pypi/v/Mopidy-SomaFM :target: https://pypi.org/project/Mopidy-SomaFM/ :alt: Latest PyPI version .. image:: https://img.shields.io/circleci/build/gh/AlexandrePTJ/mopidy-somafm :target: https://circleci.com/gh/AlexandrePTJ/mopidy-somafm :alt: CircleCI build status .. image:: https://img.shields.io/codecov/c/gh/AlexandrePTJ/mopidy-somafm :target: https://codecov.io/gh/AlexandrePTJ/mopidy-somafm :alt: Test coverage SomaFM extension for Mopidy Installation ============ Debian/Ubuntu ------------- Install by running:: python3 -m pip install Mopidy-SomaFM Or, if available, install the Debian/Ubuntu package from `apt.mopidy.com `_. Configuration ============= Before starting Mopidy, you must add configuration for Mopidy-SomaFM to your Mopidy configuration file:: [somafm] encoding = aac quality = highest - ``encoding`` must be either ``aac``, ``mp3`` or ``aacp`` - ``quality`` must be one of ``highest``, ``fast``, ``slow``, ``firewall`` If the preferred quality is not available for a channel, the extension will fallback to ``fast``. And afterwards if the preferred encoding is not available for that quality, it will fallback to using ``mp3``. It seems that all channels support the combination ``fast`` + ``mp3`` You can also choose to use the channel DJ as the reported track artist (default behavior):: [somafm] dj_as_artist = true Project resources ================= - `Source code `_ - `Issue tracker `_ - `Changelog `_ Credits ======= - Original author: `Alexandre Petitjean `__ - Current maintainer: `Alexandre Petitjean `__ - `Contributors `_ Mopidy-SomaFM-2.0.0rc1/mopidy_somafm/0000755000175000017510000000000013571702175021304 5ustar alexandrealexandre00000000000000Mopidy-SomaFM-2.0.0rc1/mopidy_somafm/__init__.py0000644000175000017510000000155613571702147023423 0ustar alexandrealexandre00000000000000import logging import pathlib import pkg_resources from mopidy import config, ext __version__ = pkg_resources.get_distribution("Mopidy-SomaFM").version logger = logging.getLogger(__name__) class Extension(ext.Extension): dist_name = "Mopidy-SomaFM" ext_name = "somafm" version = __version__ def get_default_config(self): return config.read(pathlib.Path(__file__).parent / "ext.conf") def get_config_schema(self): schema = super().get_config_schema() schema["encoding"] = config.String(choices=("aac", "mp3", "aacp")) schema["quality"] = config.String( choices=("highest", "fast", "slow", "firewall") ) schema["dj_as_artist"] = config.Boolean() return schema def setup(self, registry): from .backend import SomaFMBackend registry.add("backend", SomaFMBackend) Mopidy-SomaFM-2.0.0rc1/mopidy_somafm/backend.py0000644000175000017510000000534113571702147023247 0ustar alexandrealexandre00000000000000import logging import mopidy_somafm import pykka from mopidy import backend from mopidy.models import Album, Artist, Image, Ref, Track from .somafm import SomaFMClient logger = logging.getLogger(__name__) class SomaFMBackend(pykka.ThreadingActor, backend.Backend): def __init__(self, config, audio): super().__init__() self.somafm = SomaFMClient( config["proxy"], "{}/{}".format( mopidy_somafm.Extension.dist_name, mopidy_somafm.__version__ ), ) self.library = SomaFMLibraryProvider(backend=self) self.uri_schemes = ["somafm"] self.quality = config["somafm"]["quality"] self.encoding = config["somafm"]["encoding"] self.dj_as_artist = config["somafm"]["dj_as_artist"] def on_start(self): self.somafm.refresh(self.encoding, self.quality) class SomaFMLibraryProvider(backend.LibraryProvider): root_directory = Ref.directory(uri="somafm:root", name="SomaFM") def lookup(self, uri): # Whatever the uri, it will always contains one track # which is a url to a pls if not uri.startswith("somafm:"): return None channel_name = uri[uri.index("/") + 1 :] channel_data = self.backend.somafm.channels[channel_name] # Artists if self.backend.dj_as_artist: artist = Artist(name=channel_data["dj"]) else: artist = Artist() # Build album (idem as playlist, but with more metada) album = Album( artists=[artist], name=channel_data["title"], uri="somafm:channel:/%s" % (channel_name), ) track = Track( artists=[artist], album=album, last_modified=channel_data["updated"], comment=channel_data["description"], genre=channel_data["genre"], name=channel_data["title"], uri=channel_data["pls"], ) return [track] def browse(self, uri): if uri != "somafm:root": return [] result = [] for channel in self.backend.somafm.channels: result.append( Ref.track( uri="somafm:channel:/%s" % (channel), name=self.backend.somafm.channels[channel]["title"], ) ) result.sort(key=lambda ref: ref.name.lower()) return result def get_images(self, uris): images = [] for uri in uris: if uri.startswith("somafm:"): channel_name = uri[uri.index("/") + 1 :] image = Image(uri=self.backend.somafm.images[channel_name]) images.append(image) return images Mopidy-SomaFM-2.0.0rc1/mopidy_somafm/ext.conf0000644000175000017510000000011213571140522022735 0ustar alexandrealexandre00000000000000[somafm] enabled = true encoding = mp3 quality = fast dj_as_artist = true Mopidy-SomaFM-2.0.0rc1/mopidy_somafm/somafm.py0000644000175000017510000001205213571702147023137 0ustar alexandrealexandre00000000000000import collections import logging import re from urllib.parse import urlsplit import requests from mopidy import httpclient try: import xml.etree.cElementTree as ET except ImportError: import xml.etree.ElementTree as ET logger = logging.getLogger(__name__) # # Channels are playlist and Album # PLS are tracks # PLS contents for internal use # class SomaFMClient: CHANNELS_URI = "https://api.somafm.com/channels.xml" # All channels seem to have this combination of quality/encoding available FALLBACK_QUALITY = "fast" FALLBACK_ENCODING = "mp3" channels = {} images = {} def __init__(self, proxy_config=None, user_agent=None): super().__init__() # Build requests session self.session = requests.Session() if proxy_config is not None: proxy = httpclient.format_proxy(proxy_config) self.session.proxies.update({"http": proxy, "https": proxy}) full_user_agent = httpclient.format_user_agent(user_agent) self.session.headers.update({"user-agent": full_user_agent}) def refresh(self, encoding, quality): # clean previous data self.channels = {} # download channels xml file channels_content = self._downloadContent(self.CHANNELS_URI) if channels_content is None: logger.error("Cannot fetch %s" % (self.CHANNELS_URI)) return # parse XML root = ET.fromstring(channels_content) for child_channel in root: pls_id = child_channel.attrib["id"] channel_data = {} channel_all_pls = collections.defaultdict(dict) for child_detail in child_channel: key = child_detail.tag val = child_detail.text if key in ["title", "image", "dj", "genre", "description"]: channel_data[key] = val elif key == "updated": channel_data["updated"] = int(val) elif "pls" in key: pls_quality = key[:-3] pls_format = child_detail.attrib["format"] channel_all_pls[pls_quality][pls_format] = val # firewall playlist are fastpls+mp3 but with fw path if pls_quality == "fast" and pls_format == "mp3": r1 = urlsplit(val) channel_all_pls["firewall"][ "mp3" ] = "{}://{}/{}".format( r1.scheme, r1.netloc, "fw" + r1.path ) channel_pls = self._choose_pls(channel_all_pls, encoding, quality) if channel_pls is not None: channel_data["pls"] = channel_pls self.channels[pls_id] = channel_data self.images[pls_id] = channel_data["image"] logger.info("Loaded %i SomaFM channels" % (len(self.channels))) def extractStreamUrlFromPls(self, pls_uri): pls_content = self._downloadContent(pls_uri) if pls_content is None: logger.error("Cannot fetch %s" % (pls_uri)) return pls_uri # try to find FileX= try: m = re.search(r"^(File\d)=(?P\S+)", pls_content, re.M) if m: return m.group("stream_url") else: return pls_uri except BaseException: return pls_uri def _choose_pls(self, all_pls, encoding, quality): if not all_pls: return None if quality in all_pls: quality_pls = all_pls[quality] elif self.FALLBACK_QUALITY in all_pls: quality_pls = all_pls[self.FALLBACK_QUALITY] else: quality_pls = all_pls[next(iter(all_pls))] if not quality_pls: return None if encoding in quality_pls: pls = quality_pls[encoding] elif self.FALLBACK_ENCODING in all_pls: pls = quality_pls[self.FALLBACK_ENCODING] else: pls = quality_pls[next(iter(quality_pls))] return pls def _downloadContent(self, url): try: r = self.session.get(url) logger.debug("Get %s : %i", url, r.status_code) if r.status_code != 200: logger.error( "SomaFM: %s is not reachable [http code:%i]", url, r.status_code, ) return None except requests.exceptions.RequestException as e: logger.error("SomaFM RequestException: %s", e) except requests.exceptions.ConnectionError as e: logger.error("SomaFM ConnectionError: %s", e) except requests.exceptions.URLRequired as e: logger.error("SomaFM URLRequired: %s", e) except requests.exceptions.TooManyRedirects as e: logger.error("SomaFM TooManyRedirects: %s", e) except Exception as e: logger.error("SomaFM exception: %s", e) else: return r.text return None Mopidy-SomaFM-2.0.0rc1/pyproject.toml0000644000175000017510000000052613571702147021357 0ustar alexandrealexandre00000000000000[build-system] requires = ["setuptools >= 30.3.0", "wheel"] [tool.black] target-version = ["py37", "py38"] line-length = 80 [tool.isort] multi_line_output = 3 include_trailing_comma = true force_grid_wrap = 0 use_parentheses = true line_length = 88 known_tests = "tests" sections = "FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,TESTS,LOCALFOLDER" Mopidy-SomaFM-2.0.0rc1/setup.cfg0000644000175000017510000000265713571702175020274 0ustar alexandrealexandre00000000000000[metadata] name = Mopidy-SomaFM version = 2.0.0rc1 url = https://github.com/AlexandrePTJ/mopidy-somafm author = Alexandre Petitjean author_email = alpetitjean@gmail.com license = Apache License, Version 2.0 license_file = LICENSE description = SomaFM extension for Mopidy long_description = file: README.rst classifiers = Environment :: No Input/Output (Daemon) Intended Audience :: End Users/Desktop License :: OSI Approved :: Apache Software License Operating System :: OS Independent Programming Language :: Python :: 3 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Topic :: Multimedia :: Sound/Audio :: Players [options] zip_safe = False include_package_data = True packages = find: python_requires = >= 3.7 install_requires = Mopidy >= 3.0.0a4 # Change to >= 3.0 once final is released Pykka >= 2.0.1 requests >= 2.0.0 setuptools [options.extras_require] lint = black check-manifest flake8 flake8-bugbear flake8-import-order isort[pyproject] release = twine wheel test = pytest pytest-cov dev = %(lint)s %(release)s %(test)s [options.packages.find] exclude = tests tests.* [options.entry_points] mopidy.ext = somafm = mopidy_somafm:Extension [flake8] application-import-names = mopidy_somafm, tests max-line-length = 80 exclude = .git, .tox, build select = C, E, F, W B B950 N ignore = E203 E501 W503 B305 [wheel] universal = 1 [egg_info] tag_build = tag_date = 0 Mopidy-SomaFM-2.0.0rc1/setup.py0000644000175000017510000000004613571702147020152 0ustar alexandrealexandre00000000000000from setuptools import setup setup() Mopidy-SomaFM-2.0.0rc1/tests/0000755000175000017510000000000013571702175017603 5ustar alexandrealexandre00000000000000Mopidy-SomaFM-2.0.0rc1/tests/__init__.py0000644000175000017510000000000013571140522021672 0ustar alexandrealexandre00000000000000Mopidy-SomaFM-2.0.0rc1/tests/test_extension.py0000644000175000017510000000054513571702147023233 0ustar alexandrealexandre00000000000000from mopidy_somafm import Extension def test_get_default_config(): ext = Extension() config = ext.get_default_config() assert "[somafm]" in config assert "enabled = true" in config def test_get_config_schema(): ext = Extension() schema = ext.get_config_schema() assert "quality" in schema assert "encoding" in schema Mopidy-SomaFM-2.0.0rc1/tests/test_somafm.py0000644000175000017510000000265513571702147022505 0ustar alexandrealexandre00000000000000import unittest from mopidy_somafm.somafm import SomaFMClient class SomaFMClientTest(unittest.TestCase): def test_refresh(self): sfmc = SomaFMClient() sfmc.refresh("mp3", "fast") self.assertIsNotNone(sfmc.channels) self.assertNotEqual(len(sfmc.channels), 0) def test_refresh_firewall(self): sfmc = SomaFMClient() sfmc.refresh("mp3", "firewall") self.assertIsNotNone(sfmc.channels) self.assertNotEqual(len(sfmc.channels), 0) def test_refresh_no_channels(self): sfmc = SomaFMClient() sfmc.CHANNELS_URI = "" sfmc.refresh("mp3", "fast") self.assertDictEqual(sfmc.channels, {}) self.assertEqual(len(sfmc.channels), 0) def test_downloadContent(self): url = "http://api.somafm.com/channels.xml" sfmc = SomaFMClient() data = sfmc._downloadContent(url) self.assertNotEqual(len(data), 0) def test_extractStreamUrlFromPls(self): url = "http://somafm.com/groovesalad.pls" sfmc = SomaFMClient() data = sfmc.extractStreamUrlFromPls(url) self.assertNotEqual(len(data), 0) self.assertNotEqual(data, url) def test_extractStreamUrlFromPls_unknown(self): url = "http://somafm.com/noneazerty.pls" sfmc = SomaFMClient() data = sfmc.extractStreamUrlFromPls(url) self.assertNotEqual(len(data), 0) self.assertEqual(data, url) Mopidy-SomaFM-2.0.0rc1/tox.ini0000644000175000017510000000073713571702147017762 0ustar alexandrealexandre00000000000000[tox] envlist = py37, py38, black, check-manifest, flake8 [testenv] sitepackages = true deps = .[test] commands = python -m pytest \ --basetemp={envtmpdir} \ --cov=mopidy_somafm --cov-report=term-missing \ {posargs} [testenv:black] deps = .[lint] commands = python -m black --check . [testenv:check-manifest] deps = .[lint] commands = python -m check_manifest [testenv:flake8] deps = .[lint] commands = python -m flake8 --show-source --statistics