From 607c59c6901d52964dbdc09fd5d281100f9052c3 Mon Sep 17 00:00:00 2001 From: cameron Date: Tue, 11 Jan 2022 15:40:07 +1100 Subject: [PATCH 01/12] get album art --- mopidy_mpd/dispatcher.py | 5 +++- mopidy_mpd/network.py | 13 ++++++--- mopidy_mpd/protocol/music_db.py | 47 +++++++++++++++++++++++++++++++++ mopidy_mpd/session.py | 2 +- 4 files changed, 61 insertions(+), 6 deletions(-) diff --git a/mopidy_mpd/dispatcher.py b/mopidy_mpd/dispatcher.py index 25e3220..0ab59d3 100644 --- a/mopidy_mpd/dispatcher.py +++ b/mopidy_mpd/dispatcher.py @@ -155,7 +155,7 @@ def _add_ok_filter(self, request, response, filter_chain): return response def _has_error(self, response): - return response and response[-1].startswith("ACK") + return response and isinstance(response[-1], str) and response[-1].startswith("ACK") # Filter: call handler @@ -239,6 +239,9 @@ class MpdContext: #: The subsytems that we want to be notified about in idle mode. subscriptions = None + #: The maximum binary chunk size + binary_limit = 1024 * 1024 + _uri_map = None def __init__( diff --git a/mopidy_mpd/network.py b/mopidy_mpd/network.py index 23df5cc..7b8f7d4 100644 --- a/mopidy_mpd/network.py +++ b/mopidy_mpd/network.py @@ -494,8 +494,7 @@ def decode(self, line): def join_lines(self, lines): if not lines: return "" - line_terminator = self.decode(self.terminator) - return line_terminator.join(lines) + line_terminator + return self.terminator.join(lines) + self.terminator def send_lines(self, lines): """ @@ -507,5 +506,11 @@ def send_lines(self, lines): if not lines: return - data = self.join_lines(lines) - self.connection.queue_send(self.encode(data)) + encoded_lines = [] + for line in lines: + if not isinstance(line, bytes): + encoded_lines.append(self.encode(line)) + else: + encoded_lines.append(line) + + self.connection.queue_send(self.join_lines(encoded_lines)) diff --git a/mopidy_mpd/protocol/music_db.py b/mopidy_mpd/protocol/music_db.py index da4f0a3..a394bc5 100644 --- a/mopidy_mpd/protocol/music_db.py +++ b/mopidy_mpd/protocol/music_db.py @@ -1,5 +1,7 @@ import functools import itertools +import os.path +import requests from mopidy.models import Track from mopidy_mpd import exceptions, protocol, translator @@ -84,6 +86,51 @@ def _artist_as_track(artist): ) +@protocol.commands.add("albumart") +def albumart(context, uri=None, offset=0): + """ + `albumart {URI} {OFFSET}` + + Locate album art for the given song and return a chunk of an album art image file at offset OFFSET. + """ + import logging + logger = logging.getLogger(__name__) + logger.debug(f"requested {uri}, offset {offset}") + + # TODO work out how validators work and move these there + if uri is None: + raise exceptions.MpdArgError("Need to specify uri") + offset = protocol.INT(offset) + + images = context.core.library.get_images([uri]).get()[uri] + + if len(images) == 0: + raise exceptions.MpdNoExistError("No file exists") + + image_uri = images[0].uri + + # TODO cache + if image_uri.startswith("/"): + MOPIDY_DATA_PATH = os.path.expanduser("~/.local/share/mopidy/") # TODO unhardcode + _, extension, file = image_uri.split("/") + with open(os.path.join(MOPIDY_DATA_PATH, extension, "images", file), "rb") as image_file: + bytes = image_file.read() + elif image_uri.startswith("https://"): + image_request = requests.get(image_uri) + bytes = image_request.content + else: + raise exceptions.MpdNotImplemented(f"cannot make sense of the uri {image_uri}") + + if offset > len(bytes): + raise exceptions.MpdArgError("Offset too large") + + return [ + ("size", len(bytes)), + ("binary", len(bytes[offset:offset + context.binary_limit])), + bytes[offset:offset + context.binary_limit], + ] + + @protocol.commands.add("count") def count(context, *args): """ diff --git a/mopidy_mpd/session.py b/mopidy_mpd/session.py index 2aff621..58d342c 100644 --- a/mopidy_mpd/session.py +++ b/mopidy_mpd/session.py @@ -36,7 +36,7 @@ def on_line_received(self, line): logger.debug( "Response to %s: %s", self.connection, - formatting.indent(self.decode(self.terminator).join(response)), + formatting.indent(self.decode(self.terminator).join([r for r in response if not isinstance(r, bytes)])), ) self.send_lines(response) From 3f63284ea9d1202ccb5d32b38e8d9b0f07bea074 Mon Sep 17 00:00:00 2001 From: cameron Date: Tue, 11 Jan 2022 15:45:41 +1100 Subject: [PATCH 02/12] binary limit --- mopidy_mpd/protocol/connection.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/mopidy_mpd/protocol/connection.py b/mopidy_mpd/protocol/connection.py index 0bdaf1b..99fa2ef 100644 --- a/mopidy_mpd/protocol/connection.py +++ b/mopidy_mpd/protocol/connection.py @@ -51,3 +51,11 @@ def ping(context): Does nothing but return ``OK``. """ pass + + +@protocol.commands.add("binarylimit") +def binarylimit(context, size): + """ + Set the maximum binary response size for the current connection to the specified number of bytes. + """ + context.binary_limit = size From 0d14823a9c92de9f799d6d901a0877193ab736a1 Mon Sep 17 00:00:00 2001 From: cameron Date: Tue, 11 Jan 2022 16:15:18 +1100 Subject: [PATCH 03/12] make album art use the album's uri and add readpicture --- mopidy_mpd/protocol/music_db.py | 34 ++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/mopidy_mpd/protocol/music_db.py b/mopidy_mpd/protocol/music_db.py index a394bc5..61ea3f1 100644 --- a/mopidy_mpd/protocol/music_db.py +++ b/mopidy_mpd/protocol/music_db.py @@ -86,17 +86,7 @@ def _artist_as_track(artist): ) -@protocol.commands.add("albumart") -def albumart(context, uri=None, offset=0): - """ - `albumart {URI} {OFFSET}` - - Locate album art for the given song and return a chunk of an album art image file at offset OFFSET. - """ - import logging - logger = logging.getLogger(__name__) - logger.debug(f"requested {uri}, offset {offset}") - +def _get_art(context, uri=None, offset=0): # TODO work out how validators work and move these there if uri is None: raise exceptions.MpdArgError("Need to specify uri") @@ -129,6 +119,18 @@ def albumart(context, uri=None, offset=0): ("binary", len(bytes[offset:offset + context.binary_limit])), bytes[offset:offset + context.binary_limit], ] + pass + + +@protocol.commands.add("albumart") +def albumart(context, uri=None, offset=0): + """ + `albumart {URI} {OFFSET}` + + Locate album art for the given song and return a chunk of an album art image file at offset OFFSET. + """ + track = context.core.library.lookup([uri]).get()[uri] + return _get_art(context, track[0].album.uri, offset) @protocol.commands.add("count") @@ -595,3 +597,13 @@ def readcomments(context, uri): support it. For example, on Ogg files, this lists the Vorbis comments. """ pass + + +@protocol.commands.add("readpicture") +def readpicture(context, uri=None, offset=0): + """ + `readpicture {URI} {OFFSET}` + + Locate a picture for the given song and return a chunk of the image file at offset OFFSET. + """ + return _get_art(context, uri, offset) From 13650c924b0139ba346bdeb4ae10936d0b5fb5cf Mon Sep 17 00:00:00 2001 From: cameron Date: Fri, 14 Jan 2022 12:21:03 +1100 Subject: [PATCH 04/12] Add simple cache --- mopidy_mpd/protocol/music_db.py | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/mopidy_mpd/protocol/music_db.py b/mopidy_mpd/protocol/music_db.py index 61ea3f1..6493cc8 100644 --- a/mopidy_mpd/protocol/music_db.py +++ b/mopidy_mpd/protocol/music_db.py @@ -86,7 +86,11 @@ def _artist_as_track(artist): ) +_art_cache = ("", bytes()) + + def _get_art(context, uri=None, offset=0): + global _art_cache # TODO work out how validators work and move these there if uri is None: raise exceptions.MpdArgError("Need to specify uri") @@ -99,17 +103,21 @@ def _get_art(context, uri=None, offset=0): image_uri = images[0].uri - # TODO cache - if image_uri.startswith("/"): - MOPIDY_DATA_PATH = os.path.expanduser("~/.local/share/mopidy/") # TODO unhardcode - _, extension, file = image_uri.split("/") - with open(os.path.join(MOPIDY_DATA_PATH, extension, "images", file), "rb") as image_file: - bytes = image_file.read() - elif image_uri.startswith("https://"): - image_request = requests.get(image_uri) - bytes = image_request.content + if image_uri == _art_cache[0]: + bytes = _art_cache[1] else: - raise exceptions.MpdNotImplemented(f"cannot make sense of the uri {image_uri}") + if image_uri.startswith("/"): + MOPIDY_DATA_PATH = os.path.expanduser("~/.local/share/mopidy/") # TODO unhardcode + _, extension, file = image_uri.split("/") + with open(os.path.join(MOPIDY_DATA_PATH, extension, "images", file), "rb") as image_file: + bytes = image_file.read() + elif image_uri.startswith("https://"): + image_request = requests.get(image_uri) + bytes = image_request.content + else: + raise exceptions.MpdNotImplemented(f"cannot make sense of the uri {image_uri}") + + _art_cache = (image_uri, bytes) if offset > len(bytes): raise exceptions.MpdArgError("Offset too large") From 558bf3c919f7d5530a7a6dd3cb9b4e674f53eef8 Mon Sep 17 00:00:00 2001 From: cameron Date: Fri, 14 Jan 2022 12:51:19 +1100 Subject: [PATCH 05/12] formatting --- mopidy_mpd/dispatcher.py | 6 +++++- mopidy_mpd/protocol/connection.py | 3 ++- mopidy_mpd/protocol/music_db.py | 26 +++++++++++++++++--------- mopidy_mpd/session.py | 6 +++++- 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/mopidy_mpd/dispatcher.py b/mopidy_mpd/dispatcher.py index 0ab59d3..0bded04 100644 --- a/mopidy_mpd/dispatcher.py +++ b/mopidy_mpd/dispatcher.py @@ -155,7 +155,11 @@ def _add_ok_filter(self, request, response, filter_chain): return response def _has_error(self, response): - return response and isinstance(response[-1], str) and response[-1].startswith("ACK") + return ( + response + and isinstance(response[-1], str) + and response[-1].startswith("ACK") + ) # Filter: call handler diff --git a/mopidy_mpd/protocol/connection.py b/mopidy_mpd/protocol/connection.py index 99fa2ef..b2f6010 100644 --- a/mopidy_mpd/protocol/connection.py +++ b/mopidy_mpd/protocol/connection.py @@ -56,6 +56,7 @@ def ping(context): @protocol.commands.add("binarylimit") def binarylimit(context, size): """ - Set the maximum binary response size for the current connection to the specified number of bytes. + Set the maximum binary response size for the current connection to the + specified number of bytes. """ context.binary_limit = size diff --git a/mopidy_mpd/protocol/music_db.py b/mopidy_mpd/protocol/music_db.py index 6493cc8..af0e6d5 100644 --- a/mopidy_mpd/protocol/music_db.py +++ b/mopidy_mpd/protocol/music_db.py @@ -107,15 +107,21 @@ def _get_art(context, uri=None, offset=0): bytes = _art_cache[1] else: if image_uri.startswith("/"): - MOPIDY_DATA_PATH = os.path.expanduser("~/.local/share/mopidy/") # TODO unhardcode + MOPIDY_DATA_PATH = os.path.expanduser( + "~/.local/share/mopidy/" + ) # TODO unhardcode _, extension, file = image_uri.split("/") - with open(os.path.join(MOPIDY_DATA_PATH, extension, "images", file), "rb") as image_file: + with open( + os.path.join(MOPIDY_DATA_PATH, extension, "images", file), "rb" + ) as image_file: bytes = image_file.read() elif image_uri.startswith("https://"): image_request = requests.get(image_uri) bytes = image_request.content else: - raise exceptions.MpdNotImplemented(f"cannot make sense of the uri {image_uri}") + raise exceptions.MpdNotImplemented( + f"cannot make sense of the uri {image_uri}" + ) _art_cache = (image_uri, bytes) @@ -124,8 +130,8 @@ def _get_art(context, uri=None, offset=0): return [ ("size", len(bytes)), - ("binary", len(bytes[offset:offset + context.binary_limit])), - bytes[offset:offset + context.binary_limit], + ("binary", len(bytes[offset : offset + context.binary_limit])), + bytes[offset : offset + context.binary_limit], ] pass @@ -133,9 +139,10 @@ def _get_art(context, uri=None, offset=0): @protocol.commands.add("albumart") def albumart(context, uri=None, offset=0): """ - `albumart {URI} {OFFSET}` + `albumart {URI} {OFFSET}` - Locate album art for the given song and return a chunk of an album art image file at offset OFFSET. + Locate album art for the given song and return a chunk of an album art + image file at offset OFFSET. """ track = context.core.library.lookup([uri]).get()[uri] return _get_art(context, track[0].album.uri, offset) @@ -610,8 +617,9 @@ def readcomments(context, uri): @protocol.commands.add("readpicture") def readpicture(context, uri=None, offset=0): """ - `readpicture {URI} {OFFSET}` + `readpicture {URI} {OFFSET}` - Locate a picture for the given song and return a chunk of the image file at offset OFFSET. + Locate a picture for the given song and return a chunk of the image file at + offset OFFSET. """ return _get_art(context, uri, offset) diff --git a/mopidy_mpd/session.py b/mopidy_mpd/session.py index 58d342c..24a3167 100644 --- a/mopidy_mpd/session.py +++ b/mopidy_mpd/session.py @@ -36,7 +36,11 @@ def on_line_received(self, line): logger.debug( "Response to %s: %s", self.connection, - formatting.indent(self.decode(self.terminator).join([r for r in response if not isinstance(r, bytes)])), + formatting.indent( + self.decode(self.terminator).join( + [r for r in response if not isinstance(r, bytes)] + ) + ), ) self.send_lines(response) From b827d5271c3af52861005f55cd07247eee1565aa Mon Sep 17 00:00:00 2001 From: cameron Date: Fri, 14 Jan 2022 15:08:02 +1100 Subject: [PATCH 06/12] dodgy import --- mopidy_mpd/protocol/music_db.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/mopidy_mpd/protocol/music_db.py b/mopidy_mpd/protocol/music_db.py index af0e6d5..ec7af0d 100644 --- a/mopidy_mpd/protocol/music_db.py +++ b/mopidy_mpd/protocol/music_db.py @@ -107,12 +107,14 @@ def _get_art(context, uri=None, offset=0): bytes = _art_cache[1] else: if image_uri.startswith("/"): - MOPIDY_DATA_PATH = os.path.expanduser( - "~/.local/share/mopidy/" - ) # TODO unhardcode + try: + from mopidy_local import Extension + data_path = Extension.get_image_dir(context.dispatcher.config) + except ImportError: + raise exceptions.MpdNoExistError("A local file was requested, but there was no local extension.") _, extension, file = image_uri.split("/") with open( - os.path.join(MOPIDY_DATA_PATH, extension, "images", file), "rb" + os.path.join(data_path, extension, "images", file), "rb" ) as image_file: bytes = image_file.read() elif image_uri.startswith("https://"): From 1db20315494209fa600ca452a68624ef09a766f3 Mon Sep 17 00:00:00 2001 From: cameron Date: Sat, 15 Jan 2022 11:35:02 +1100 Subject: [PATCH 07/12] remove requests dependency and use urllib --- mopidy_mpd/protocol/music_db.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mopidy_mpd/protocol/music_db.py b/mopidy_mpd/protocol/music_db.py index ec7af0d..c67f4c3 100644 --- a/mopidy_mpd/protocol/music_db.py +++ b/mopidy_mpd/protocol/music_db.py @@ -1,7 +1,7 @@ import functools import itertools import os.path -import requests +from urllib.request import Request, urlopen from mopidy.models import Track from mopidy_mpd import exceptions, protocol, translator @@ -118,8 +118,8 @@ def _get_art(context, uri=None, offset=0): ) as image_file: bytes = image_file.read() elif image_uri.startswith("https://"): - image_request = requests.get(image_uri) - bytes = image_request.content + with urlopen(Request(image_uri)) as r: + bytes = r.read() else: raise exceptions.MpdNotImplemented( f"cannot make sense of the uri {image_uri}" From b8b762473460ada90f60e5207a59f757d1a59b4d Mon Sep 17 00:00:00 2001 From: cameron Date: Sat, 15 Jan 2022 11:38:55 +1100 Subject: [PATCH 08/12] Moved cache to context --- mopidy_mpd/dispatcher.py | 3 +++ mopidy_mpd/protocol/music_db.py | 10 +++------- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/mopidy_mpd/dispatcher.py b/mopidy_mpd/dispatcher.py index 0bded04..3dba2bf 100644 --- a/mopidy_mpd/dispatcher.py +++ b/mopidy_mpd/dispatcher.py @@ -246,6 +246,9 @@ class MpdContext: #: The maximum binary chunk size binary_limit = 1024 * 1024 + #: A cache of the most recently sent artwork + art_cache = ("", bytes()) + _uri_map = None def __init__( diff --git a/mopidy_mpd/protocol/music_db.py b/mopidy_mpd/protocol/music_db.py index c67f4c3..324251f 100644 --- a/mopidy_mpd/protocol/music_db.py +++ b/mopidy_mpd/protocol/music_db.py @@ -86,11 +86,7 @@ def _artist_as_track(artist): ) -_art_cache = ("", bytes()) - - def _get_art(context, uri=None, offset=0): - global _art_cache # TODO work out how validators work and move these there if uri is None: raise exceptions.MpdArgError("Need to specify uri") @@ -103,8 +99,8 @@ def _get_art(context, uri=None, offset=0): image_uri = images[0].uri - if image_uri == _art_cache[0]: - bytes = _art_cache[1] + if image_uri == context.art_cache[0]: + bytes = context.art_cache[1] else: if image_uri.startswith("/"): try: @@ -125,7 +121,7 @@ def _get_art(context, uri=None, offset=0): f"cannot make sense of the uri {image_uri}" ) - _art_cache = (image_uri, bytes) + context.art_cache = (image_uri, bytes) if offset > len(bytes): raise exceptions.MpdArgError("Offset too large") From 605585751291becfca06277f0399fae53c36ebf0 Mon Sep 17 00:00:00 2001 From: cameron Date: Sat, 15 Jan 2022 11:49:21 +1100 Subject: [PATCH 09/12] removed ugly import, still not final solution --- mopidy_mpd/protocol/music_db.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/mopidy_mpd/protocol/music_db.py b/mopidy_mpd/protocol/music_db.py index 324251f..e399bc2 100644 --- a/mopidy_mpd/protocol/music_db.py +++ b/mopidy_mpd/protocol/music_db.py @@ -103,11 +103,7 @@ def _get_art(context, uri=None, offset=0): bytes = context.art_cache[1] else: if image_uri.startswith("/"): - try: - from mopidy_local import Extension - data_path = Extension.get_image_dir(context.dispatcher.config) - except ImportError: - raise exceptions.MpdNoExistError("A local file was requested, but there was no local extension.") + data_path = context.config["core"]["config_dir"] _, extension, file = image_uri.split("/") with open( os.path.join(data_path, extension, "images", file), "rb" From 132b0efa915aeeae303bfe220d1279f76fb77613 Mon Sep 17 00:00:00 2001 From: cameron Date: Sat, 15 Jan 2022 11:55:06 +1100 Subject: [PATCH 10/12] support http --- mopidy_mpd/protocol/music_db.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mopidy_mpd/protocol/music_db.py b/mopidy_mpd/protocol/music_db.py index e399bc2..999a741 100644 --- a/mopidy_mpd/protocol/music_db.py +++ b/mopidy_mpd/protocol/music_db.py @@ -109,7 +109,7 @@ def _get_art(context, uri=None, offset=0): os.path.join(data_path, extension, "images", file), "rb" ) as image_file: bytes = image_file.read() - elif image_uri.startswith("https://"): + elif image_uri.startswith("https://") or image_uri.startswith("http://"): with urlopen(Request(image_uri)) as r: bytes = r.read() else: From 75aa9bc74e4710a50be84bc986130ad228cb0a40 Mon Sep 17 00:00:00 2001 From: cameron Date: Sat, 15 Jan 2022 12:45:01 +1100 Subject: [PATCH 11/12] Add try block to getting remote resource --- mopidy_mpd/protocol/music_db.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/mopidy_mpd/protocol/music_db.py b/mopidy_mpd/protocol/music_db.py index 999a741..7a5b4b7 100644 --- a/mopidy_mpd/protocol/music_db.py +++ b/mopidy_mpd/protocol/music_db.py @@ -2,6 +2,7 @@ import itertools import os.path from urllib.request import Request, urlopen +import urllib.error from mopidy.models import Track from mopidy_mpd import exceptions, protocol, translator @@ -110,11 +111,14 @@ def _get_art(context, uri=None, offset=0): ) as image_file: bytes = image_file.read() elif image_uri.startswith("https://") or image_uri.startswith("http://"): - with urlopen(Request(image_uri)) as r: - bytes = r.read() + try: + with urlopen(Request(image_uri)) as r: + bytes = r.read() + except urllib.error.URLError as e: + raise exceptions.MpdArgError(f"There was an error with getting the uri, reason: {e.reason}") else: raise exceptions.MpdNotImplemented( - f"cannot make sense of the uri {image_uri}" + f"Cannot make sense of the uri {image_uri}" ) context.art_cache = (image_uri, bytes) From 4d3e7f446cf85614e3a86634fa4b06d579e3f14c Mon Sep 17 00:00:00 2001 From: cameron Date: Wed, 26 Jan 2022 10:59:38 +1100 Subject: [PATCH 12/12] remove shadowing of bytes --- mopidy_mpd/protocol/music_db.py | 17 ++++++++--------- mopidy_mpd/session.py | 2 +- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/mopidy_mpd/protocol/music_db.py b/mopidy_mpd/protocol/music_db.py index 7a5b4b7..2facc7d 100644 --- a/mopidy_mpd/protocol/music_db.py +++ b/mopidy_mpd/protocol/music_db.py @@ -101,7 +101,7 @@ def _get_art(context, uri=None, offset=0): image_uri = images[0].uri if image_uri == context.art_cache[0]: - bytes = context.art_cache[1] + image_bytes = context.art_cache[1] else: if image_uri.startswith("/"): data_path = context.config["core"]["config_dir"] @@ -109,11 +109,11 @@ def _get_art(context, uri=None, offset=0): with open( os.path.join(data_path, extension, "images", file), "rb" ) as image_file: - bytes = image_file.read() + image_bytes = image_file.read() elif image_uri.startswith("https://") or image_uri.startswith("http://"): try: with urlopen(Request(image_uri)) as r: - bytes = r.read() + image_bytes = r.read() except urllib.error.URLError as e: raise exceptions.MpdArgError(f"There was an error with getting the uri, reason: {e.reason}") else: @@ -121,17 +121,16 @@ def _get_art(context, uri=None, offset=0): f"Cannot make sense of the uri {image_uri}" ) - context.art_cache = (image_uri, bytes) + context.art_cache = (image_uri, image_bytes) - if offset > len(bytes): + if offset > len(image_bytes): raise exceptions.MpdArgError("Offset too large") return [ - ("size", len(bytes)), - ("binary", len(bytes[offset : offset + context.binary_limit])), - bytes[offset : offset + context.binary_limit], + ("size", len(image_bytes)), + ("binary", len(image_bytes[offset : offset + context.binary_limit])), + image_bytes[offset : offset + context.binary_limit], ] - pass @protocol.commands.add("albumart") diff --git a/mopidy_mpd/session.py b/mopidy_mpd/session.py index 24a3167..d09cf4c 100644 --- a/mopidy_mpd/session.py +++ b/mopidy_mpd/session.py @@ -38,7 +38,7 @@ def on_line_received(self, line): self.connection, formatting.indent( self.decode(self.terminator).join( - [r for r in response if not isinstance(r, bytes)] + r for r in response if not isinstance(r, bytes) ) ), )