Skip to content

Commit

Permalink
Merge pull request #7 from pimoroni/python3
Browse files Browse the repository at this point in the history
Port to Python 3 for #1
  • Loading branch information
Gadgetoid committed Jan 30, 2020
2 parents 907609c + d6a0fa5 commit 9c87d3d
Show file tree
Hide file tree
Showing 16 changed files with 650 additions and 182 deletions.
51 changes: 51 additions & 0 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
version: 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
15 changes: 8 additions & 7 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
*.egg-info
*.pyc
.coverage
.pytest_cache/
.tox/
MANIFEST
build/
dist/
/.coverage
/.mypy_cache/
/.pytest_cache/
/.tox/
/*.egg-info
/build/
/dist/
/MANIFEST
2 changes: 2 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ include mopidy_pidi/ext.conf
include tox.ini

recursive-include tests *.py

recursive-include .circleci *
10 changes: 5 additions & 5 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
Mopidy-PiDi
****************************

.. image:: https://img.shields.io/pypi/v/Mopidy-PiDi.svg?style=flat
.. image:: https://img.shields.io/pypi/v/Mopidy-PiDi.svg
:target: https://pypi.org/project/Mopidy-PiDi/
:alt: Latest PyPI version

.. image:: https://img.shields.io/travis/pimoroni/mopidy-pidi/master.svg?style=flat
:target: https://travis-ci.org/pimoroni/mopidy-pidi
.. image:: https://img.shields.io/circleci/build/gh/pimoroni/mopidy-pidi/master.svg
:target: https://circleci.com/gh/pimoroni/mopidy-pidi
:alt: Travis CI build status

.. image:: https://img.shields.io/coveralls/pimoroni/mopidy-pidi/master.svg?style=flat
:target: https://coveralls.io/r/pimoroni/mopidy-pidi
.. image:: https://img.shields.io/codecov/gh/pimoroni/mopidy-pidi/master.svg
:target: https://codecov.io/gh/pimoroni/mopidy-pidi
:alt: Test coverage

Mopidy extension for displaying song info and album art using pidi display plugins.
Expand Down
22 changes: 10 additions & 12 deletions mopidy_pidi/__init__.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
from __future__ import unicode_literals

import logging
import os
import pathlib

from pkg_resources import iter_entry_points
import pkg_resources

from mopidy import config, ext

__version__ = "0.2.0"
__version__ = pkg_resources.get_distribution("mopidy_pidi").version

logger = logging.getLogger(__name__)

Expand All @@ -21,26 +19,26 @@ class Extension(ext.Extension):
@classmethod
def get_display_types(self):
display_types = {}
for entry_point in iter_entry_points("pidi.plugin.display"):
for entry_point in pkg_resources.iter_entry_points("pidi.plugin.display"):
try:
plugin = entry_point.load()
display_types[plugin.option_name] = plugin
except (ImportError) as err:
logger.log(logging.WARN, "Error loading display plugin {entry_point}: {err}".format(
entry_point=entry_point,
err=err))
logger.log(
logging.WARN, f"Error loading display plugin {entry_point}: {err}"
)

return display_types

def get_default_config(self):
conf_file = os.path.join(os.path.dirname(__file__), "ext.conf")
return config.read(conf_file)
return config.read(pathlib.Path(__file__).parent / "ext.conf")

def get_config_schema(self):
schema = super(Extension, self).get_config_schema()
schema = super().get_config_schema()
schema["display"] = config.String(choices=self.get_display_types().keys())
return schema

def setup(self, registry):
from .frontend import PiDiFrontend

registry.add("frontend", PiDiFrontend)
51 changes: 27 additions & 24 deletions mopidy_pidi/brainz.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Musicbrainz related functions.
"""
import base64
import logging
import os
import time
from threading import Thread
Expand All @@ -10,29 +11,30 @@

from .__init__ import __version__

logger = logging.getLogger(__name__)


class Brainz:
def __init__(self, cache_dir):
"""Initialize musicbrainz."""
mus.set_useragent("python-pidi: A cover art daemon.",
__version__,
"https://github.com/pimoroni/mopidy-pidi")
mus.set_useragent(
"python-pidi: A cover art daemon.",
__version__,
"https://github.com/pimoroni/mopidy-pidi",
)

self._cache_dir = cache_dir
self._default_filename = os.path.join(self._cache_dir, "__default.jpg")

self.save_album_art(self.get_default_album_art(), self._default_filename)

def get_album_art(self, artist, album, callback=None):
def get_album_art(self, artist, album, callback=None):
if artist is None or album is None or artist == "" or album == "":
if callback is not None:
return callback(self._default_filename)
return self._default_filename

file_name = self.get_cache_file_name("{artist}_{album}".format(
artist=artist,
album=album
))
file_name = self.get_cache_file_name(f"{artist}_{album}")

if os.path.isfile(file_name):
# If a cached file already exists, use it!
Expand All @@ -41,6 +43,7 @@ def get_album_art(self, artist, album, callback=None):
return file_name

if callback is not None:

def async_request_album_art(self, artist, album, file_name, callback):
album_art = self.request_album_art(artist, album)

Expand All @@ -56,12 +59,8 @@ def async_request_album_art(self, artist, album, file_name, callback):

t_album_art = Thread(
target=async_request_album_art,
args=(
self,
artist,
album,
file_name,
callback))
args=(self, artist, album, file_name, callback),
)
t_album_art.start()
return t_album_art

Expand All @@ -85,35 +84,38 @@ def save_album_art(self, data, output_file):
def request_album_art(self, artist, album, size=500, retry_delay=5, retries=5):
"""Download the cover art."""
try:
data = mus.search_releases(artist=artist,
release=album,
limit=1)
data = mus.search_releases(artist=artist, release=album, limit=1)
release_id = data["release-list"][0]["release-group"]["id"]
print("mopidy-pidi: musicbrainz using release-id: {}".format(data['release-list'][0]['id']))
logger.info("mopidy-pidi: musicbrainz using release-id: {release_id}")

return mus.get_release_group_image_front(release_id, size=size)

except mus.NetworkError:
if retries == 0:
# raise mus.NetworkError("Failure connecting to MusicBrainz.org")
return None
print("mopidy-pidi: musicbrainz retrying download. {retries} retries left!".format(retries=retries))
logger.info(
f"mopidy-pidi: musicbrainz retrying download. {retries} retries left!"
)
time.sleep(retry_delay)
self.request_album_art(song, artist, album, size=size, retries=retries - 1)
self.request_album_art(artist, album, size=size, retries=retries - 1)

except mus.ResponseError:
print("mopidy-pidi: musicbrainz couldn't find album art for {artist} - {album}".format(artist=artist, album=album))
logger.info(
f"mopidy-pidi: musicbrainz couldn't find album art for {artist} - {album}"
)
return None

def get_cache_file_name(self, file_name):
file_name = file_name.encode("utf-8")
file_name = "{}.jpg".format(base64.b64encode(file_name))
file_name = f"{base64.b64encode(file_name)}.jpg"

return os.path.join(self._cache_dir, file_name)

def get_default_album_art(self):
"""Return binary version of default album art."""
return base64.b64decode("""
return base64.b64decode(
"""
iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAMAAAAM7l6QAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFn
ZVJlYWR5ccllPAAAAMBQTFRFBHwvBSl8d04DCQ99egJLfAMzejQGcGoAAGZ6AHN3N3wBSHwBKXwDAHlp
NQF9AHtXAFV7VwB7HgN9B30aG30FXncAAXtERwB8fQMbZQB5AUF8fRsHQ04rfQgLFlZTVzgteABiZ14F
Expand All @@ -125,4 +127,5 @@ def get_default_album_art(self):
f2YsZWl6WK8nk+VSOTBN05iGemO73e5w+JnNZpVlRQYIKTcM+g/xtiq1BloR5Dy/3++r7ba6rWLkmmLd
LCvP8zfqCp0zNYgtepZlmu93kiCfTifP87iDNK5OkiSBbpyEe1WPs0DTdJxeEAQr3TCUgyXUQnR6ySgI
dJy7rjclV8y3PdS5jm647nRKDVBIOjoSG4KpAOpfB3V0nM/LjmyapXHBriscylrwx0FpiQ11Hf6PyXX5
ORWAoxqr44Y4/ifAAPd/TAMIg8r1AAAAAElFTkSuQmCC""")
ORWAoxqr44Y4/ifAAPd/TAMIg8r1AAAAAElFTkSuQmCC"""
)

0 comments on commit 9c87d3d

Please sign in to comment.